编译原理词法分析器
直接上代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <string> 4 #include <iostream> 5 #include <map> 6 #include <algorithm> 7 using namespace std; 8 9 map<string,int>mp_res; 10 map<string,int>mp_oper; 11 map<char,int>mp_dili; 12 string pre=""; 13 14 int flag1=false,flag2=1;//flag1用作判断/*或*/是否在引号内,flag2判断内容是否处于注释状态 15 string mstr,flagstr,ansstr=""; 16 17 string double_slash(string s)//双斜杠注释处理 18 { 19 string ans=""; 20 bool flag=false;//判断//是否在双引号内作为字符串 21 for(int i=0;i<s.length();i++) 22 { 23 if(s[i]=='/'&&s[i+1]=='/'&&i+1<s.length()&&!flag) 24 break; 25 if(s[i]==34) 26 flag=!flag; 27 ans+=s[i]; 28 } 29 return ans; 30 } 31 32 string block_comments(string s)//去除/* */的注释 33 { 34 string ans; 35 for(int i=0;i<s.length();i++) 36 { 37 if(s[i]==34) 38 flag1=!flag1; 39 if(s[i]=='/'&&s[i+1]=='*'&&i+1<s.length()&&!flag1) 40 { 41 flag2=0; 42 i+=2; 43 } 44 if(s[i]=='*'&&s[i+1]=='/'&&i+1<s.length()&&!flag1) 45 { 46 flag2=1; 47 i+=2; 48 } 49 if(flag2) 50 ans+=s[i]; 51 } 52 return ans; 53 } 54 55 string space(string s)//多个连续空格并为一个,去除tab 56 { 57 bool flag=1; 58 string ans=""; 59 for(int i=0;i<s.length();i++) 60 { 61 if(s[i]=='\t') 62 continue; 63 if(s[i]!=' ') 64 flag=0; 65 if(flag&&s[i]==' ') 66 continue; 67 if(s[i]==' ') 68 flag=1; 69 ans+=s[i]; 70 } 71 return ans; 72 } 73 74 void init_table()//初始化对应值 75 { 76 string resword[35]={"int","long","short","float","double","char","bool","unsigned","signed","const","void","volatile", 77 "enum","struct","union","if","else","goto","switch","case","do","while","for","continue","break","return", 78 "default","typedef","auto","register","extern","static","sizeof","string","namespace"}; 79 string operchar[33]={"+","-","*","/","%","++","--", 80 ">","<","==",">=","<=","!=", 81 "&&","||","!", 82 "&","|","~","^","<<",">>", 83 "=","+=","-=","*=","/=","&=","|=","^=",">>=","<<=","."}; 84 char dilimiters[11]={'(',')','{','}','[',']',';','\'','"','#',','}; 85 //标识符为1,数字为2 86 for(int i=0;i<35;i++) 87 mp_res[resword[i]]=i+2; 88 for(int i=0;i<33;i++) 89 mp_oper[operchar[i]]=i+37; 90 for(int i=0;i<11;i++) 91 mp_dili[dilimiters[i]]=i+70; 92 } 93 94 int is_digit(string s)//判断是否是数字 95 { 96 if(s[0]>='0'&&s[0]<='9') 97 { 98 for(int i=0;i<s.length();i++) 99 { 100 if(!(s[i]>='0'&&s[i]<='9')) 101 return -1; 102 } 103 return 1; 104 } 105 return 0; 106 } 107 108 void print()//处理输出 109 { 110 string temp="",oper=""; 111 int x; 112 for(int i=0;i<ansstr.length();i++) 113 { 114 string ts=""; ts+=ansstr[i]; 115 if(ansstr[i]!=' '&&mp_dili[ansstr[i]]==0&&mp_oper[ts]==0) 116 temp+=ansstr[i]; 117 else 118 { 119 if(temp.size()>0) 120 { 121 cout<<temp; 122 x=30-temp.length(); 123 for(int j=1;j<=x;j++) 124 printf(" "); 125 printf("|"); 126 if(mp_res[temp]!=0) 127 { 128 printf("%10d",mp_res[temp]); 129 printf(" |"); 130 printf(" keyword\n"); 131 pre="keyword"; 132 } 133 else if(is_digit(temp)==1) 134 { 135 printf("%10d",2); 136 printf(" |"); 137 printf(" digit"); 138 if(pre=="digit") 139 cout<<"(error)"<<endl; 140 else 141 cout<<endl; 142 pre="digit"; 143 } 144 else if(is_digit(temp)==0) 145 { 146 printf("%10d",1); 147 printf(" |"); 148 printf(" identifier"); 149 if(pre=="identifier") 150 cout<<"(error)"<<endl; 151 else 152 cout<<endl; 153 pre="identifier"; 154 } 155 else 156 { 157 printf("%10d",-1); 158 printf(" |"); 159 printf(" ERROR\n"); 160 } 161 temp=""; 162 163 } 164 if(mp_dili[ansstr[i]]!=0) 165 { 166 cout<<ansstr[i]; 167 for(int j=1;j<=29;j++) 168 printf(" "); 169 printf("|"); 170 printf("%10d",mp_dili[ansstr[i]]); 171 printf(" |"); 172 printf(" delimiter\n"); 173 pre="delimiter"; 174 } 175 if(mp_oper[ts]!=0) 176 { 177 while(mp_oper[ts]!=0) 178 { 179 oper=ts; 180 i++; 181 ts+=ansstr[i]; 182 } 183 cout<<oper; 184 x=30-oper.length(); 185 for(int j=1;j<=x;j++) 186 printf(" "); 187 printf("|"); 188 printf("%10d",mp_oper[oper]); 189 oper=""; 190 i--; 191 printf(" |"); 192 printf(" operator\n"); 193 pre="operator"; 194 } 195 196 } 197 198 } 199 } 200 201 int main() 202 { 203 freopen("datain.txt","r",stdin); 204 freopen("dataout.txt","w+",stdout); 205 cout<<"单词符号 | 种别码 | 种类"<<endl; 206 while(getline(cin,mstr))//边读边去注释 207 { 208 mstr=double_slash(mstr); 209 ansstr+=block_comments(mstr); 210 ansstr+=' '; 211 } 212 ansstr=space(ansstr);//合并空格 213 init_table(); 214 print(); 215 }