编译原理词法分析器

直接上代码:

  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 }

 

posted @ 2018-03-30 08:29  东流vip  阅读(236)  评论(0编辑  收藏  举报