词法分析程序设计
设一语言的关键词、运算符、分界符的个数与单词如下:
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++设计一程序实现词法分析。
输入一程序,结束符用”#”;
输出单词数对:<类号,序号>。 输出标识符表,用空格分隔; 输出无符号整数表,用空格分隔;
main() { int a=2,b=3; return 2*b+a; }#
<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
----------------------------------------------------------------------------------------------------
现在的能AC的这个代码在输入的标识符连续的时候会出现不能正确读取的情况:
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 5 struct { int number; string str[10]; } keywords={3,"int","main","return"} ; //关键词 6 struct { int number; string str[10]; } operators ={5,"+","*","=","+=","*="}; //运算符 7 struct { int number; string str[10]; } boundaries ={6,"(",")","{","}",",",";"} ; //分界符 8 struct { int number; string str[100];} identifieres={0}; //标识符 9 struct { int number; string str[100];} Unsigned_integer={0}; //无符号整数 10 11 char k=0; 12 string st=""; 13 int main(){ 14 int i; char ch; bool nochar=1; 15 16 do{ 17 if(nochar)cin.get(ch); 18 if(ch=='('){st+="<3,0>";nochar=1;} 19 else if(ch==')'){ st+="<3,1>";nochar=1; } 20 else if(ch=='{'){ st+="<3,2>";nochar=1; } 21 else if(ch=='}'){ st+="<3,3>";nochar=1; } 22 else if(ch==','){ st+="<3,4>";nochar=1; } 23 else if(ch==';'){ st+="<3,5>";nochar=1; } 24 else if(ch=='+'){ 25 cin.get(ch); 26 if(ch=='='){ 27 st+="<2,3>";nochar=1; 28 } 29 else{ 30 st+="<2,0>";nochar=1; 31 } 32 } 33 else if(ch=='*'){ 34 cin.get(ch); 35 if(ch=='='){ 36 st+="<2,4>";nochar=1; 37 } 38 else{ 39 st+="<2,1>";nochar=1; 40 } 41 } 42 else if(ch=='='){ 43 st+="<2,2>";nochar=1; 44 } 45 else if('0'<=ch&&ch<='9'){ 46 string nstring=""; nochar=0; 47 do{ 48 nstring+=ch; 49 cin.get(ch); 50 } while('0'<=ch&&ch<='9'); 51 for(k=0;k<Unsigned_integer.number&&Unsigned_integer.str[k]!=nstring;k++ ); 52 53 if(k==Unsigned_integer.number ){ 54 Unsigned_integer.str[k] = nstring; 55 st+="<5,";st+=char('0'+k); st+=">"; 56 Unsigned_integer.number++; 57 } 58 else{ 59 st+="<5,";st+=char('0'+k);st+=">"; 60 } 61 } 62 else if('a'<=ch&&ch<='z'||'A'<=ch&&ch<='Z'){ 63 string nstring="";nochar=0; 64 do{ 65 nstring+=ch; 66 cin.get(ch); 67 } while('a'<=ch&&ch<='z'||'A'<=ch&&ch<='Z') ; //读入关键字或者标示符的东西 68 69 for(k=0;k<= keywords.number &&keywords.str[k]!=nstring;k++ ); 70 if(k<keywords.number ){ 71 //测得输入字符是关键字之一 72 st+="<1,"; st+=char('0'+k);st+=">"; 73 } 74 else{ 75 //测得输入字符不是关键字之一,而是标识符 76 for(k=0;k<identifieres.number && identifieres.str[k]!=nstring;k++ ); //检查是否是已经记录过的标识符 77 if(k==identifieres.number ){ //不是已经标识过的标识符 78 identifieres.str[k]=nstring; 79 st+="<4,";st=st+char('0'+k);st+=">"; 80 identifieres.number++; 81 } 82 else{ 83 st+="<4,";st=st+char('0'+k);st+=">"; 84 } 85 } 86 } 87 else nochar=1; 88 89 } while(ch!='#'); 90 91 cout<<st<<endl; 92 cout<<"identifieres:"; 93 for(i=0;i<identifieres.number;i++ ){cout<<identifieres.str[i]<<" ";} cout<<endl; 94 cout<<"Unsigned_integer:"; 95 for(i=0;i<Unsigned_integer.number;i++ ){cout<<Unsigned_integer.str[i]<<" ";} cout<<endl; 96 97 return 0; 98 } 99
在输入的时候需要注意输入的规范,标识符要用空格分开,才能正确读取,这是需要加强的地方。