sicily1000. 词法分析程序设计 **
题目:
Description
设一语言的关键词、运算符、分界符的个数与单词如下:
struct { int number; string str[10]; } keywords={3,"int","main","return"} ; //关键词
struct { int number; string str[10]; } operators ={5,"+","*","=","+=","*="}; //运算符
struct { int number; string str[10]; } boundaries ={6,"(",")","{","}",",",";"} ; //分界符
struct { int number; string str[100];} identifieres={0}; //标识符
struct { int number; string str[100];} Unsigned_integer={0}; //无符号整数
以上类号分别为1~5,序号从0开始;
标识符是字母开头的字母数字串;常量为无符号整数;
用C++设计一程序实现词法分析。
Input
输入一程序,结束符用”#”;
Output
输出单词数对:<类号,序号>。 输出标识符表,用空格分隔; 输出无符号整数表,用空格分隔;
Sample Input
main() { int a=2,b=3; return 2*b+a; }#
Sample Output
<1,1><3,0><3,1><3,2><1,0><4,0><2,2><5,0><3,4><4,1><2,2><5,1><3,5><1,2><5,0><2,1> <4,1><2,0><4,0><3,5><3,3> identifieres:a b Unsigned_integer:2 3
题意分析:很明显,这道题是需要我们模仿编译器的词法分析部分来模拟实现。有五个类别,我们在scan的过程中就要对每个类别进行一次判断,然后选择在哪一个类别中进行分析。
词法分析的过程大概如下:
- 对最简单的分解符进行匹配,
- 对运算符进行匹配,
- 对无符号整数进行匹配,
- 对关键字和标识符进行匹配,
然后这就是我们要写的整个流程。
代码如下:
// Problem#: 20907 // Submission#: 5180737 // The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License // URI: http://creativecommons.org/licenses/by-nc-sa/3.0/ // All Copyright reserved by Informatic Lab of Sun Yat-sen University #include<iostream> #include<string> #include<set> using namespace std; struct { int number; string str[10]; } keywords = { 3,"int","main","return" }; //关键词 struct { int number; string str[10]; } operators = { 5,"+","*","=","+=","*=" }; //运算符 struct { int number; string str[10]; } boundaries = { 6,"(",")","{","}",",",";" }; //分界符 struct { int number; string str[100]; } identifieres = { 0 }; //标识符 struct { int number; string str[100]; } Unsigned_integer = { 0 }; //无符号整数 void scan(string s) { string b =""; set<string> sset; int i, index = 0; for (i = 0; i < s.size(); i++) { for (int j = 0; j < boundaries.number; j++) { if (s[i] == boundaries.str[j][0]) { cout << "<3," << j << ">"; break; } } for (int j = 0; j < 2; j++) { if (s[i] == operators.str[j][0]) { if (s[i + 1] == '=') { cout << "<2," << j + 3 << ">"; break; } else { cout << "<2," << j << ">"; break; } } } if (s[i] == '=') { cout << "<2,2>"; continue; } if (s[i] == ' ' || s[i] == '\n') continue; if (s[i] >= '0'&&s[i] <= '9') { //b[index] += s[i]; b += s[i]; if (s[i+1]<'0'||s[i+1]>'9') { int k, flag = 1; for (k = 0; k < Unsigned_integer.number; k++) { if (b == Unsigned_integer.str[k]) { flag = 0; break; } } if (flag) { cout << "<5," << Unsigned_integer.number << ">"; Unsigned_integer.str[Unsigned_integer.number] = b; Unsigned_integer.number++; b = ""; continue; } else { cout << "<5," << k << ">"; b = ""; continue; } } } if (isalpha(s[i])) { b += s[i]; int bflag = 1; for (int j = 0; j < 3; j++) { if (b == keywords.str[j]) { cout << "<1," << j << ">"; b = ""; bflag = 0; break; } } if (bflag) if (!isalpha(s[i+1])) { int flag = 1; for (int j = 0; j < 3; j++) { if (b == keywords.str[j]) { cout << "<1," << j << ">"; b = ""; flag = 0; break; } } for (int k = 0; k < identifieres.number; k++) { if (b == identifieres.str[k]) { cout << "<4," << k << ">"; b = ""; flag = 0; break; } } if (flag) { identifieres.str[identifieres.number++] = b; cout << "<4," << identifieres.number - 1 << ">"; b = ""; continue; } } } } cout << "\nidentifieres:"; for (int i = 0; i < identifieres.number-1; i++) { cout << identifieres.str[i] << " "; } if(identifieres.number) cout << identifieres.str[identifieres.number -1]; cout << endl << "Unsigned_integer:"; for (int i = 0; i < Unsigned_integer.number - 1; i++) { cout << Unsigned_integer.str[i] << " "; } if (Unsigned_integer.number) { cout << Unsigned_integer.str[Unsigned_integer.number-1]; } cout << endl; } int main() { char c; string s; while (cin >> c&&c != '#') { s += c; } scan(s); system("pause"); }