www.pudn.com > Pascal_分析.rar > Pascal.cpp


// PASCAL词法分析程序 
// 2002102319 王昕 
#include  
#include  
#include  
#include  
#include  
using namespace std; 
// 保留字数组定义 
char* ReserveWords[35] = { 
  "and", "array", "begin", "case", "const", "div", "do", "downto", "else", "end", "file", 
  "for", "function", "goto", "if", "in", "label", "mod", "nil", "not", "of", "or", "packed", 
  "procedure", "program", "record", "repeat", "set", "then", "to", "type", "until", "var", 
  "while", "with" 
}; 
char arrow[] = " -----> "; 
char enter[] = "\r\n"; 
// 读入ch 
char GetChar(ifstream& src) 
{ 
  char cRet; 
  src.get(cRet); 
  return cRet; 
} 
// 读入空格 
char GetBC(ifstream& src) 
{ 
  char cRet; 
  src.get(cRet); 
  while (cRet == ' ') 
    src.get(cRet); 
  return cRet; 
} 
// 连接单词符号 
void Concat(char *str, char c) 
{ 
  size_t n = strlen(str); 
  str[n++] = c; 
  str[n] = '\0'; 
} 
// 判断是否为保留字 
bool Reserve(const char* str) 
{ 
  bool bRet = false; 
  for (int i = 0; i < 35; i++) 
  { 
    if (_stricmp(ReserveWords[i], str) == 0) 
    { 
      bRet = true; 
      break; 
    } 
  } 
  return bRet; 
} 
// 回调字符 
char Retract(ifstream& src) 
{ 
  src.seekg(-1, ios::cur); 
  return '\0'; 
} 
// 分析函数 
void Analyzer(ifstream& src, ofstream& dst) 
{ 
  char ch; 
  char strToken[1024] = ""; 
  ch = GetBC(src); 
  // 判断标识符的情况 
  if (isalpha(ch)) 
  { 
    while (isalpha(ch) || isdigit(ch) || ch == '_') 
    { 
      Concat(strToken, ch); 
      ch = GetChar(src); 
    } 
    ch = Retract(src); 
    if (Reserve(strToken)) 
      dst << strToken << arrow << "Reserve Word" << enter; 
    else 
      dst << strToken << arrow << "Identifier" << enter; 
  } 
  // 判断数值的情况 
  else if (isdigit(ch)) 
  { 
    while (isdigit(ch)) 
    { 
      Concat(strToken, ch); 
      ch = GetChar(src); 
    } 
    Retract(src); 
    dst << strToken << arrow << "Number" << enter; 
  } 
  // 判断字符串的情况 
  else if (ch == '\'') 
  { 
    Concat(strToken, ch); 
    ch = GetChar(src); 
    while (ch != '\'') 
    { 
      Concat(strToken, ch); 
      ch = GetChar(src); 
    } 
    if (ch != '\'') 
      cerr << "String is too long - more than 1024 bytes!" << endl; 
    else 
    { 
      Concat(strToken, ch); 
      dst << strToken << arrow << "String" << enter; 
    } 
  } 
  // 过滤注释 
  else if (ch == '{') 
  { 
    while (GetChar(src) != '}') 
      ; 
  } 
  // 判断所有没有歧义的单目运算符 
  else if (ch == '+') 
    dst << ch << arrow << "Plus" << enter; 
  else if (ch == '-') 
    dst << ch << arrow << "Minus" << enter; 
  else if (ch == '*') 
    dst << ch << arrow << "Multiply" << enter; 
  else if (ch == '/') 
    dst << ch << arrow << "Divide" << enter; 
  else if (ch == '=') 
    dst << ch << arrow << "Equal" << enter; 
  else if (ch == '[') 
    dst << ch << arrow << "Left Square Brackets" << enter; 
  else if (ch == ']') 
    dst << ch << arrow << "Right Square Brackets" << enter; 
  else if (ch == ',') 
    dst << ch << arrow << "Comma" << enter; 
  else if (ch == '^') 
    dst << ch << arrow << "Pointer" << enter; 
  else if (ch == ';') 
    dst << ch << arrow << "Semicolon" << enter; 
  else if (ch == '(') 
    dst << ch << arrow << "Left Parenthesis" << enter; 
  else if (ch == ')') 
    dst << ch << arrow << "Right Parenthesis" << enter; 
  // 判断<、<>和<= 
  else if (ch == '<') 
  { 
    ch = GetChar(src); 
    if (ch == '>') 
      dst << "<>" << arrow << "Unequal" << enter; 
    else if (ch == '=') 
      dst << "<=" << arrow << "Less or Equal" << enter; 
    else 
    { 
      dst << '<' << arrow << "Less" << enter; 
      Retract(src); 
    } 
  } 
  // 判断>和>= 
  else if (ch == '>') 
  { 
    ch = GetChar(src); 
    if (ch == '=') 
      dst << ">=" << arrow << "Greater or Equal" << enter; 
    else 
    { 
      dst << '>' << arrow << "Greater" << enter; 
      Retract(src); 
    } 
  } 
  // 判断.和.. 
  else if (ch == '.') 
  { 
    ch = GetChar(src); 
    if (ch == '.') 
      dst << ".." << arrow << "Bound" << enter; 
    else 
    { 
      dst << '.' << arrow << "Point" << enter; 
      Retract(src); 
    } 
  } 
  // 判断:和:= 
  else if (ch == ':') 
  { 
    ch = GetChar(src); 
    if (ch == '=') 
      dst << ":=" << arrow << "Assign" << enter; 
    else 
    { 
      dst << ':' << arrow << "Colon" << enter; 
      Retract(src); 
    } 
  } 
} 
int main(int argc, char* argv[]) 
{ 
  string strSrc; 
  // 命令行的支持 
  if (argc == 1) 
  { 
    cout << "Please input PASCAL source file name: "; 
    getline(cin, strSrc); 
  } 
  else 
    strSrc = argv[1]; 
  // 打开文件 
  ifstream src(strSrc.c_str()); 
  if (src.fail()) 
  { 
    cerr << "\aFailed openning \"" << strSrc << "\"!" << endl; 
    return 1; 
  } 
  ofstream dst("Result.txt"); 
  // 开始解析 
  while (!src.eof()) 
    Analyzer(src, dst); 
  // 收尾工作 
  dst.close(); 
  src.close(); 
  cout << "The result of Analyzing is written into Result.txt." << endl; 
  return 0; 
}