本实验采用预测分析法,对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