首页 > 其他分享 >《编译原理》实验二:自上而下语法分析

《编译原理》实验二:自上而下语法分析

时间:2023-05-16 19:45:04浏览次数:40  
标签:ident 语法分析 back terminal 编译 push 终结符 nonterminal 自上而下

本实验采用预测分析法,对PL/0语言的算术运算进行语法分析。

因为我所见到的互联网上的语法分析程序大多使用的递归下降法,所以本程序完全由我个人独立完成,代码为C++98,因此可能较丑陋(尤其是预测分析表部分),且不能保证完全正确,还请见谅 ┗( T﹏T )┛


一. 设计思想

1.文法

(1)EBNF

<表达式> ::= [+|-]<项>{<加法运算符> <项>}

<项> ::= <因子>{<乘法运算符> <因子>}

<因子> ::= <标识符>|<无符号整数>| ‘(’<表达式>‘)’

<加法运算符> ::= +|-

<乘法运算符> ::= *|/

(2)对EBNF中的各对象简称

E:表达式

X:项

Y:因子

A:加法运算符

C:乘法运算符

b:标识符

z:无符号整数

(3)将文法改写成常规的产生式形式

E -> AX|X|EAX

X -> Y|XCY

Y -> b|z|(E)

A -> +|-

C -> *|/

(4)消除左递归后的文法

E -> AXE'|XE'

E' -> AXE'|ε

X -> YX'

X' -> CYX'|ε

Y -> b|z|(E)

A -> +|-

C -> *|/

注意:以上文法为了文章美观在"->"前后添加了空格,实际输入时不要输入空格,否则结果将错误。

2. First集和Follow集

First(E) = {+,-,b,z,(} Follow(E) = {#,)}
First(E') = {+,-,ε} Follow(E') = {#,)}
First(X) = {b,z,(} Follow(X) = {+,-,#,)}
First(X') = {*,/,ε} Follow(X') = {+,-,#,)}
First(Y) = {b,z,(} Follow(Y) = {+,-,#,)}
First(A) = {+,-} Follow(A) = {b,z,(}
First(C) = {*,/} Follow(C) = {b,z,(}

满足LL(1)文法的条件,是LL(1)文法。

3.预测分析表

  + - * / # ( ) b z
E E -> AXE' E -> AXE'       E -> XE'   E -> XE' E -> XE'
E' E -> AXE' E -> AXE'     E' -> ε   E' -> ε    
X           X -> YX'   X -> YX' X -> YX'
X' X' -> ε X' -> ε X' -> CYX' X' -> CYX' X' -> ε   X' -> ε    
Y           Y -> (E)   Y -> b Y -> z
A A -> + A -> -              
C     C -> * C -> /          

二. 算法流程

 

三. 源程序

  1 #include <iostream>
  2 #include <string>
  3 #include <vector>
  4 #include <map>
  5 #include <stack>
  6 using namespace std;
  7 
  8 vector<vector<string> > input;   // 输入(逗号两边)
  9 const int nt_num=10;    // 非终结符数目
 10 const int t_num=10;     // 终结符数目
 11 vector<string> nonterminal,terminal;   // 非终结符数组 终结符数组
 12 map<string,int> ntchar2idx;   // 非终结符转下标
 13 map<string,int> tchar2idx;   // 终结符转下标
 14 vector<vector<vector<string> > > table(t_num,vector<vector<string> >(nt_num,vector<string>(4,"")));   // 预测分析表
 15 stack<string> s;
 16 
 17 void getNonterminal()   // 非终结符数组
 18 {
 19     // TODO
 20     nonterminal.push_back("E");
 21     nonterminal.push_back("E'");
 22     nonterminal.push_back("X");
 23     nonterminal.push_back("X'");
 24     nonterminal.push_back("Y");
 25     nonterminal.push_back("A");
 26     nonterminal.push_back("C");
 27 }
 28 
 29 void getTerminal()   // 终结符数组
 30 {
 31     // TODO
 32     terminal.push_back("+");
 33     terminal.push_back("-");
 34     terminal.push_back("*");
 35     terminal.push_back("/");
 36     terminal.push_back("#");
 37     terminal.push_back("(");
 38     terminal.push_back(")");
 39     terminal.push_back("b");
 40     terminal.push_back("z");
 41 }
 42 
 43 bool isTerminal(const string& str)   // 判断是否为终结符
 44 {
 45     for (int i=0;i<(int)terminal.size();++i)
 46     {
 47         if (str==terminal[i])
 48         {
 49             return true;
 50         }
 51     }
 52     return false;
 53 }
 54 
 55 void char2idx()   // (非)终结符转下标
 56 {
 57     string str;
 58     for (int i=0;i<(int)nonterminal.size();++i)
 59     {
 60         str=nonterminal[i];
 61         ntchar2idx[str]=i+1;
 62     }
 63     for (int i=0;i<(int)terminal.size();++i)
 64     {
 65         str=terminal[i];
 66         tchar2idx[str]=i+1;
 67     }
 68 }
 69 
 70 void createTable()   // 创建预测分析表
 71 {
 72     // TODO,C++98的写法太丑了。。。
 73     string str1[3]={"A","X","E'"};
 74     table[1][1].insert(table[1][1].begin(),str1,str1+3);
 75     table[1][1].resize(3);
 76     string str2[3]={"A","X","E'"};
 77     table[1][2].insert(table[1][2].begin(),str2,str2+3);
 78     table[1][2].resize(3);
 79     string str3[2]={"X","E'"};
 80     table[1][6].insert(table[1][6].begin(),str3,str3+2);
 81     table[1][6].resize(2);
 82     string str4[2]={"X","E'"};
 83     table[1][8].insert(table[1][8].begin(),str4,str4+2);
 84     table[1][8].resize(2);
 85     string str5[2]={"X","E'"};
 86     table[1][9].insert(table[1][9].begin(),str5,str5+2);
 87     table[1][9].resize(2);
 88     string str6[3]={"A","X","E'"};
 89     table[2][1].insert(table[2][1].begin(),str6,str6+3);
 90     table[2][1].resize(3);
 91     string str7[3]={"A","X","E'"};
 92     table[2][2].insert(table[2][2].begin(),str7,str7+3);
 93     table[2][2].resize(3);
 94     string str8[1]={" "};
 95     table[2][5].insert(table[2][5].begin(),str8,str8+1);
 96     table[2][5].resize(1);
 97     string str9[1]={" "};
 98     table[2][7].insert(table[2][7].begin(),str9,str9+1);
 99     table[2][7].resize(1);
100     string str10[2]={"Y","X'"};
101     table[3][6].insert(table[3][6].begin(),str10,str10+2);
102     table[3][6].resize(2);
103     string str11[2]={"Y","X'"};
104     table[3][8].insert(table[3][8].begin(),str11,str11+2);
105     table[3][8].resize(2);
106     string str12[2]={"Y","X'"};
107     table[3][9].insert(table[3][9].begin(),str12,str12+2);
108     table[3][9].resize(2);
109     string str13[1]={" "};
110     table[4][1].insert(table[4][1].begin(),str13,str13+1);
111     table[4][1].resize(1);
112     string str14[1]={" "};
113     table[4][2].insert(table[4][2].begin(),str14,str14+1);
114     table[4][2].resize(1);
115     string str15[3]={"C","Y","X'"};
116     table[4][3].insert(table[4][3].begin(),str15,str15+3);
117     table[4][3].resize(3);
118     string str16[3]={"C","Y","X'"};
119     table[4][4].insert(table[4][4].begin(),str16,str16+3);
120     table[4][4].resize(3);
121     string str17[1]={" "};
122     table[4][5].insert(table[4][5].begin(),str17,str17+1);
123     table[4][5].resize(1);
124     string str18[1]={" "};
125     table[4][7].insert(table[4][7].begin(),str18,str18+1);
126     table[4][7].resize(1);
127     string str19[3]={"(","E",")"};
128     table[5][6].insert(table[5][6].begin(),str19,str19+3);
129     table[5][6].resize(3);
130     string str20[1]={"b"};
131     table[5][8].insert(table[5][8].begin(),str20,str20+1);
132     table[5][8].resize(1);
133     string str21[1]={"z"};
134     table[5][9].insert(table[5][9].begin(),str21,str21+1);
135     table[5][9].resize(1);
136     string str22[1]={"+"};
137     table[6][1].insert(table[6][1].begin(),str22,str22+1);
138     table[6][1].resize(1);
139     string str23[1]={"-"};
140     table[6][2].insert(table[6][2].begin(),str23,str23+1);
141     table[6][2].resize(1);
142     string str24[1]={"*"};
143     table[7][3].insert(table[7][3].begin(),str24,str24+1);
144     table[7][3].resize(1);
145     string str25[1]={"/"};
146     table[7][4].insert(table[7][4].begin(),str25,str25+1);
147     table[7][4].resize(1);
148     return;
149 }
150 
151 inline bool ERROR(int pos)
152 {
153     //cout<<"wrong_pos = "<<pos<<endl;
154     return false;
155 }
156 
157 bool predictAnalyse()   // 预测分析程序
158 {
159     s.push("#");
160     s.push("E");   //TODO
161     int i=0;
162     string nt,t0,t1;
163     vector<string> vec;
164     while (!s.empty() && i<(int)input.size())
165     {   //cout<<"s.size="<<s.size()<<"    "<<"i="<<i<<endl;
166         if (isTerminal(s.top()))   // 栈顶元素是终结符
167         {
168             t0=input[i][0];
169             if (t0=="ident")
170             {
171                 t1="b";
172             }
173             else if (t0=="number")
174             {
175                 t1="z";
176             }
177             else
178             {
179                 t1=input[i][1];
180             }
181             if (s.top()==t1)
182             {
183                 s.pop();
184                 ++i;
185             }
186             else
187             {
188                 return ERROR(1);
189             }
190         }
191         else   // 栈顶元素是非终结符
192         {
193             nt=s.top();
194             s.pop();
195             t0=input[i][0];
196             if (t0=="ident")
197             {
198                 t1="b";
199             }
200             else if (t0=="number")
201             {
202                 t1="z";
203             }
204             else
205             {
206                 t1=input[i][1];
207             }
208             vec.clear();
209             //cout<<ntchar2idx[nt]<<","<<tchar2idx[t1]<<endl;
210             vec.assign(table[ntchar2idx[nt]][tchar2idx[t1]].begin(),table[ntchar2idx[nt]][tchar2idx[t1]].end());
211             if (vec.size())
212             {
213                 if (vec[0]==" ")
214                 {
215                     continue;
216                 }
217                 else if (vec[0]!="")
218                 {
219                     for (int i=vec.size()-1;i>=0;--i)
220                     {
221                         s.push(vec[i]);
222                     }
223                 }
224                 else
225                 {
226                     return ERROR(2);
227                 }
228             }
229             else
230             {
231                 return  ERROR(3);
232             }
233         }
234     }
235     if (!s.empty() || i<(int)input.size())
236     {
237         return ERROR(4);
238     }
239     return true;
240 }
241 
242 int main()
243 {
244     getNonterminal();
245     getTerminal();
246     char2idx();
247     createTable();
248     string str;
249     vector<string> vec;
250     while (cin>>str)
251     {
252         int pos=str.find(',');
253         vec.clear();
254         vec.push_back(str.substr(1,pos-1));
255         vec.push_back(str.substr(pos+1,str.size()-pos-2));
256 //        for (auto i:vec)
257 //        {
258 //            cout<<i<<",";
259 //        }cout<<endl;
260         input.push_back(vec);
261     }
262     vec.clear();
263     vec.push_back("#");vec.push_back("#");
264     input.push_back(vec);
265 
266     if (predictAnalyse())
267     {
268         cout<<"Yes,it is correct."<<endl;
269     }
270     else
271     {
272         cout<<"No,it is wrong."<<endl;
273     }
274 
275     return 0;
276 }
View Code

注释为TODO的代码由两个预期程序进行替换:

1.实验1的词法分析程序

2.自构建预测分析表程序(从输入文法到去掉左递归到First、Follow集再到预测分析表),感觉较难

四. 调试数据

1.样例输入:

1 (lparen,()
2 (ident,a)
3 (plus,+)
4 (number,15)
5 (rparen,))
6 (times,*)
7 (ident,b)

样例输出:

Yes,it is correct.

图片展示:

2.样例输入:

 1 (number,0)
 2 (plus,+)
 3 (number,10)
 4 (times,*)
 5 (ident,b)
 6 (minus,-)
 7 (lparen,()
 8 (ident,z)
 9 (slash,/)
10 (number,3)
11 (rparen,))

样例输出:

Yes,it is correct.

图片展示:

3.样例输入:

 1 (lparen,()
 2 (lparen,()
 3 (ident,a)
 4 (plus,+)
 5 (number,3)
 6 (rparen,))
 7 (times,*)
 8 (lparen,()
 9 (number,0)
10 (minus,-)
11 (ident,b)
12 (rparen,))
13 (minus,-)
14 (ident,c)
15 (slash,/)
16 (number,0)
17 (plus,+)
18 (lparen,()
19 (ident,a)
20 (times,*)
21 (ident,d)
22 (slash,/)
23 (ident,e)
24 (plus,+)
25 (ident,f)
26 (rparen,))
27 (rparen,))

样例输出:

Yes,it is correct.

图片展示:

4.样例输入:

1 (lparen,()
2 (ident,a)
3 (plus,+)
4 (number,15)
5 (rparen,))
6 (times,*)

样例输出:

No,it is wrong.

图片展示:

5.样例输入:

1 (ident,a)
2 (plus,+)
3 (number,15)
4 (rparen,))
5 (times,*)
6 (ident,b)

样例输出:

No,it is wrong.

图片展示:

6.样例输入:

 1 (number,0)
 2 (plus,+)
 3 (number,10)
 4 (times,*)
 5 (ident,b)
 6 (lparen,()
 7 (ident,z)
 8 (slash,/)
 9 (number,3)
10 (rparen,))

样例输出:

No,it is wrong.

图片展示:

注:文法只包含简单的+、-、*、/运算等,而像实验1中的const和:=等符号均未引入。

五. 实验调试情况及体会


六. thinking & upgrade

1.将实验1的词法分析写入本实验:

  1 #include <iostream>
  2 #include <string>
  3 #include <vector>
  4 #include <map>
  5 #include <stack>
  6 using namespace std;
  7 
  8 vector<vector<string> > input;   // 输入(逗号两边)
  9 const int nt_num=10;    // 非终结符数目
 10 const int t_num=10;     // 终结符数目
 11 vector<string> nonterminal,terminal;   // 非终结符数组 终结符数组
 12 map<string,int> ntchar2idx;   // 非终结符转下标
 13 map<string,int> tchar2idx;   // 终结符转下标
 14 vector<vector<vector<string> > > table(t_num,vector<vector<string> >(nt_num,vector<string>(4,"")));   // 预测分析表
 15 stack<string> s;
 16 
 17 void getNonterminal()   // 非终结符数组
 18 {
 19     // TODO
 20     nonterminal.push_back("E");
 21     nonterminal.push_back("E'");
 22     nonterminal.push_back("X");
 23     nonterminal.push_back("X'");
 24     nonterminal.push_back("Y");
 25     nonterminal.push_back("A");
 26     nonterminal.push_back("C");
 27 }
 28 
 29 void getTerminal()   // 终结符数组
 30 {
 31     // TODO
 32     terminal.push_back("+");
 33     terminal.push_back("-");
 34     terminal.push_back("*");
 35     terminal.push_back("/");
 36     terminal.push_back("#");
 37     terminal.push_back("(");
 38     terminal.push_back(")");
 39     terminal.push_back("b");
 40     terminal.push_back("z");
 41 }
 42 
 43 bool isTerminal(const string& str)   // 判断是否为终结符
 44 {
 45     for (int i=0;i<(int)terminal.size();++i)
 46     {
 47         if (str==terminal[i])
 48         {
 49             return true;
 50         }
 51     }
 52     return false;
 53 }
 54 
 55 void char2idx()   // (非)终结符转下标
 56 {
 57     string str;
 58     for (int i=0;i<(int)nonterminal.size();++i)
 59     {
 60         str=nonterminal[i];
 61         ntchar2idx[str]=i+1;
 62     }
 63     for (int i=0;i<(int)terminal.size();++i)
 64     {
 65         str=terminal[i];
 66         tchar2idx[str]=i+1;
 67     }
 68 }
 69 
 70 void createTable()   // 创建预测分析表
 71 {
 72     // TODO,C++98的写法太丑了。。。
 73     string str1[3]={"A","X","E'"};
 74     table[1][1].insert(table[1][1].begin(),str1,str1+3);
 75     table[1][1].resize(3);
 76     string str2[3]={"A","X","E'"};
 77     table[1][2].insert(table[1][2].begin(),str2,str2+3);
 78     table[1][2].resize(3);
 79     string str3[2]={"X","E'"};
 80     table[1][6].insert(table[1][6].begin(),str3,str3+2);
 81     table[1][6].resize(2);
 82     string str4[2]={"X","E'"};
 83     table[1][8].insert(table[1][8].begin(),str4,str4+2);
 84     table[1][8].resize(2);
 85     string str5[2]={"X","E'"};
 86     table[1][9].insert(table[1][9].begin(),str5,str5+2);
 87     table[1][9].resize(2);
 88     string str6[3]={"A","X","E'"};
 89     table[2][1].insert(table[2][1].begin(),str6,str6+3);
 90     table[2][1].resize(3);
 91     string str7[3]={"A","X","E'"};
 92     table[2][2].insert(table[2][2].begin(),str7,str7+3);
 93     table[2][2].resize(3);
 94     string str8[1]={" "};
 95     table[2][5].insert(table[2][5].begin(),str8,str8+1);
 96     table[2][5].resize(1);
 97     string str9[1]={" "};
 98     table[2][7].insert(table[2][7].begin(),str9,str9+1);
 99     table[2][7].resize(1);
100     string str10[2]={"Y","X'"};
101     table[3][6].insert(table[3][6].begin(),str10,str10+2);
102     table[3][6].resize(2);
103     string str11[2]={"Y","X'"};
104     table[3][8].insert(table[3][8].begin(),str11,str11+2);
105     table[3][8].resize(2);
106     string str12[2]={"Y","X'"};
107     table[3][9].insert(table[3][9].begin(),str12,str12+2);
108     table[3][9].resize(2);
109     string str13[1]={" "};
110     table[4][1].insert(table[4][1].begin(),str13,str13+1);
111     table[4][1].resize(1);
112     string str14[1]={" "};
113     table[4][2].insert(table[4][2].begin(),str14,str14+1);
114     table[4][2].resize(1);
115     string str15[3]={"C","Y","X'"};
116     table[4][3].insert(table[4][3].begin(),str15,str15+3);
117     table[4][3].resize(3);
118     string str16[3]={"C","Y","X'"};
119     table[4][4].insert(table[4][4].begin(),str16,str16+3);
120     table[4][4].resize(3);
121     string str17[1]={" "};
122     table[4][5].insert(table[4][5].begin(),str17,str17+1);
123     table[4][5].resize(1);
124     string str18[1]={" "};
125     table[4][7].insert(table[4][7].begin(),str18,str18+1);
126     table[4][7].resize(1);
127     string str19[3]={"(","E",")"};
128     table[5][6].insert(table[5][6].begin(),str19,str19+3);
129     table[5][6].resize(3);
130     string str20[1]={"b"};
131     table[5][8].insert(table[5][8].begin(),str20,str20+1);
132     table[5][8].resize(1);
133     string str21[1]={"z"};
134     table[5][9].insert(table[5][9].begin(),str21,str21+1);
135     table[5][9].resize(1);
136     string str22[1]={"+"};
137     table[6][1].insert(table[6][1].begin(),str22,str22+1);
138     table[6][1].resize(1);
139     string str23[1]={"-"};
140     table[6][2].insert(table[6][2].begin(),str23,str23+1);
141     table[6][2].resize(1);
142     string str24[1]={"*"};
143     table[7][3].insert(table[7][3].begin(),str24,str24+1);
144     table[7][3].resize(1);
145     string str25[1]={"/"};
146     table[7][4].insert(table[7][4].begin(),str25,str25+1);
147     table[7][4].resize(1);
148     return;
149 }
150 
151 inline bool ERROR(int pos)
152 {
153     //cout<<"wrong_pos = "<<pos<<endl;
154     return false;
155 }
156 
157 bool predictAnalyse()   // 预测分析程序
158 {
159     s.push("#");
160     s.push("E");   //TODO
161     int i=0;
162     string nt,t0,t1;
163     vector<string> vec;
164     while (!s.empty() && i<(int)input.size())
165     {
166         if (isTerminal(s.top()))   // 栈顶元素是终结符
167         {
168             t0=input[i][0];
169             if (t0=="ident")
170             {
171                 t1="b";
172             }
173             else if (t0=="number")
174             {
175                 t1="z";
176             }
177             else
178             {
179                 t1=input[i][1];
180             }
181             if (s.top()==t1)
182             {
183                 s.pop();
184                 ++i;
185             }
186             else
187             {
188                 return ERROR(1);
189             }
190         }
191         else   // 栈顶元素是非终结符
192         {
193             nt=s.top();
194             s.pop();
195             t0=input[i][0];
196             if (t0=="ident")
197             {
198                 t1="b";
199             }
200             else if (t0=="number")
201             {
202                 t1="z";
203             }
204             else
205             {
206                 t1=input[i][1];
207             }
208             vec.clear();
209             vec.assign(table[ntchar2idx[nt]][tchar2idx[t1]].begin(),table[ntchar2idx[nt]][tchar2idx[t1]].end());
210             if (vec.size())
211             {
212                 if (vec[0]==" ")
213                 {
214                     continue;
215                 }
216                 else if (vec[0]!="")
217                 {
218                     for (int i=vec.size()-1;i>=0;--i)
219                     {
220                         s.push(vec[i]);
221                     }
222                 }
223                 else
224                 {
225                     return ERROR(2);
226                 }
227             }
228             else
229             {
230                 return  ERROR(3);
231             }
232         }
233     }
234     if (!s.empty() || i<(int)input.size())
235     {
236         return ERROR(4);
237     }
238     return true;
239 }
240 
241 /* 词法分析start */
242 void getChar(const string s,int& idx,char& ch)   // 取下个字符
243 {
244     ch=s[idx++];
245     return;
246 }
247 
248 void getBC(const string s,int& idx,char& ch)   // 跳过空格
249 {
250     while (ch==' ')
251     {
252         getChar(s,idx,ch);
253     }
254     return;
255 }
256 
257 void concat(string& strToken,const char ch)   // 字符拼接
258 {
259     strToken+=ch;
260     return;
261 }
262 
263 void retract(int& idx,char& ch)   // 退一格
264 {
265     --idx;
266     ch=' ';
267     return;
268 }
269 // 基本字数组
270 string basicWord[13]={"begin","call","const","do","end",
271                         "if","odd","procedure","read",
272                         "then","var","while","write"};
273 // 处理基本字
274 string basic(const string strToken)
275 {
276     bool isbasic=false;
277     for (int i=0;i<13;++i)
278     {
279         if (strToken==basicWord[i])
280         {
281             isbasic=true;
282             break;
283         }
284     }
285     if (isbasic)   // 如果是基本字
286     {
287         return strToken;
288     }
289     else   // 否则是标识符
290     {
291         return "ident";
292     }
293 }
294 /* 词法分析end */
295 
296 void getInput()
297 {
298     string s="";
299     string str;
300     while (cin>>str)   // 循环读入
301     {
302         s=s+' '+str;
303     }
304 
305     int idx=0;
306     while (idx<(int)s.length())   // 处理每个字符
307     {
308         char ch=' ';
309         string strToken="";
310         getChar(s,idx,ch);
311         getBC(s,idx,ch);
312         if (isalpha(ch))   // 如果是字母
313         {
314             while (isalnum(ch))   // 读字母或数字
315             {
316                 concat(strToken,ch);
317                 getChar(s,idx,ch);
318             }
319             retract(idx,ch);
320             string ret=basic(strToken);
321             if (ret=="ident")
322             {
323                 input.push_back({"ident",strToken});
324             }
325             else
326             {
327                 input.push_back({string(ret+"sym"),strToken});
328             }
329         }
330         else if (isdigit(ch))   // 如果是数字
331         {
332             while (isdigit(ch))   // 持续获取数字
333             {
334                 concat(strToken,ch);   // 将所有数字拼起来
335                 getChar(s,idx,ch);   // 下一个字符
336             }
337             retract(idx,ch);
338             input.push_back({"number",strToken});
339         }
340         else if (ch=='+')
341         {
342             input.push_back({"plus","+"});
343         }
344         else if (ch=='-')
345         {
346             input.push_back({"minus","-"});
347         }
348         else if (ch=='*')
349         {
350             input.push_back({"times","*"});
351         }
352         else if (ch=='/')
353         {
354             input.push_back({"slash","/"});
355         }
356         else if (ch=='=')
357         {
358             input.push_back({"eql","="});
359         }
360         else if (ch=='<')   // '<'后有 <>、<= 两种可能
361         {
362             getChar(s,idx,ch);
363             if (ch=='>')
364             {
365                 input.push_back({"neq","<>"});
366             }
367             else if (ch=='=')
368             {
369                 input.push_back({"leq","<="});
370             }
371             else
372             {
373                 retract(idx,ch);
374                 input.push_back({"les","<"});
375             }
376         }
377         else if (ch=='>')   // '>'后有 >= 的可能
378         {
379             getChar(s,idx,ch);
380             if (ch=='=')
381             {
382                 input.push_back({"geq",">="});
383             }
384             else
385             {
386                 retract(idx,ch);
387                 input.push_back({"gtr",">"});
388             }
389         }
390         else if (ch==':')
391         {
392             getChar(s,idx,ch);
393             if (ch=='=')
394             {
395                 input.push_back({"becomes",":="});
396             }
397         }
398         else if (ch=='(')
399         {
400             input.push_back({"lparen","("});
401         }
402         else if (ch==')')
403         {
404             input.push_back({"rparen",")"});
405         }
406         else if (ch==',')
407         {
408             input.push_back({"comma",","});
409         }
410         else if (ch==';')
411         {
412             input.push_back({"semicolon",";"});
413         }
414         else if (ch=='.')
415         {
416             input.push_back({"period","."});
417         }
418         else
419         {
420             str=ch;
421             input.push_back({"OTHER",str});
422         }
423     }
424 //    for (int i=0;i<(int)input.size();++i)   // 输出
425 //    {
426 //        cout<<input[i][0]<<" "<<input[i][1]<<endl;
427 //    }
428     return;
429 }
430 
431 int main()
432 {
433     getNonterminal();
434     getTerminal();
435     char2idx();
436     createTable();
437     string str;
438     vector<string> vec;
439     getInput();
440     vec.clear();
441     vec.push_back("#");vec.push_back("#");
442     input.push_back(vec);
443 
444     if (predictAnalyse())
445     {
446         cout<<"Yes,it is correct."<<endl;
447     }
448     else
449     {
450         cout<<"No,it is wrong."<<endl;
451     }
452 
453     return 0;
454 }
View Code

2.将自构建预测分析表写入本实验:

TODO。。。


参考博客:

标签:ident,语法分析,back,terminal,编译,push,终结符,nonterminal,自上而下
From: https://www.cnblogs.com/hell0er/p/17365494.html

相关文章

  • 自动驾驶代码-Ros移植Apollo规划方案,可编译运行,包含autoware的Lanelet2框架。
    自动驾驶代码-Ros移植Apollo规划方案,可编译运行,包含autoware的Lanelet2框架。帮助大家快速入门实践。完善代码,加功能等。ID:31215675011337220......
  • canopencanopen sys tec 某泰学习资料,文档,例子,协 议站原程序,stm32的主站从站代码可编
    canopencanopensystec某泰学习资料,文档,例子,协议站原程序,stm32的主站从站代码可编译,其他平台没用过。协议支持全面,有nmtsdopdolss等功能,移植和开发文档详细,是开发canopen设备必备资源。远程IO,驱动等产品使用该资料,非常好用。ID:861500638397862379......
  • Nginx编译安装
    1.进入安装目录:#cd/usr/local/src2、下载nginx源码文件nginx网址:http://nginx.org/en/download.html 3、复制文件下载地址:http://nginx.org/download/nginx-1.22.1.tar.gz4、开始下载:#wget http://nginx.org/download/nginx-1.22.1.tar.gz 5、解压#tar-zxvf nginx......
  • 关于uniapp条件编译ifdef, ifndef, endif
     标识含义: 示例  转载于https://lequ7.com/guan-yu-uniappuniapp-tiao-jian-bian-yi-ifdefifndefendif.html......
  • cmake 编译提示找不到openssl的解决办法
    最后通过export 设置环境变量解决问题。exportOPENSSL_ROOT_DIR=/usr/local/opensslexportOPENSSL_LIBRARIES=/usr/local/openssl/lib参考链接:https://blog.csdn.net/davidullua/article/details/126717060......
  • ffmpeg编译配置srt模块
    官网拉取srt源码gitclonehttps://github.com/Haivision/srt.gitsudoapt-getupdatesudoapt-getupgradesudoapt-getinstalltclshpkg-configcmakelibssl-devbuild-essentialzlib1g-devgit打开目录进行编译默认的安装路径是/usr/local,默认静态动态一起编译。./conf......
  • AOSP源码编译—交换空间扩容
    编译AOSP源码的时候会出现提示如下:意思是需要16G左右的内存(实际上编译会超过16G),而我们之前安装Ubuntu的时候只分配了8G,编译一定会失败!此时需要添加虚拟内存(swap交换空间)Linux的交换分区(swap),或者叫内存置换空间(swapspace),是磁盘上的一块区域,可以是一个分区,也可以是一个文件,或......
  • 编译原理(前端)的算法和实现
    编译原理(前端)的算法和实现本文介绍从零实现Lex+YACC(即一键生成编译器(前端))的算法。完整代码在(https://gitee.com/bitzhuwei/grammar-mentor)和(https://github.com/bitzhuwei/GrammarMentor)。下文将用“解析器”指代编译器前端(即词法分析和语法分析)。本文主要以四则运算为例,其文法......
  • C#_HK_BSL视觉上位机MES源码VS2019 到手vs2019可以直接编译、 视觉检
    C#_HK_BSL视觉上位机MES源码VS2019到手vs2019可以直接编译、视觉检测、AOI视觉检测、机械手定位、点胶机、插件机、激光切割机、视觉螺丝机、视觉贴合机、激光焊接机、视觉裁板机……,C#联合Halcon混合编程源码,插件式开发,带手眼标定,相机静止和运动,支持C#脚本…能让你站在巨人的肩......
  • AOSP下载且编译
    一、简介AOSP:AndroidOpenSourceProject二、环境要求我们可以先了解官网(https://source.android.com/docs/setup/start/requirements?hl=zh-cn)的对设备的要求的介绍:2.1、软硬件要求我们可以看到官网对硬件的要求是磁盘最少250GB的可用磁盘空间,内存最少需要16GB,如何内......