原:(46条消息) 语法分析器的设计与实现_雪琰焦糖的博客-CSDN博客_语法分析器

问题描述】

请根据给定的文法设计并实现语法分析程序,能基于上次作业的词法分析程序所识别出的单词,识别出各类语法成分。输入输出及处理要求如下:

(1)需按文法规则,用递归子程序法对文法中定义的所有种语法成分进行分析;

(2)为了方便进行自动评测,输入的被编译源文件统一命名为testfile.txt(注意不要写错文件名);输出的结果文件统一命名为output.txt(注意不要写错文件名);结果文件中包含如下两种信息:

    1)按词法分析识别单词的顺序,按行输出每个单词的信息(要求同词法分析作业,对于预读的情况不能输出)。

    2)在下列高亮显示的语法分析成分分析结束前,另起一行输出当前语法成分的名字,形如“<常量说明>”(注:未要求输出的语法成分仍需要分析)

【文法定义】

<加法运算符> ::= +|-
<乘法运算符>  ::= *|/
<关系运算符>  ::=  <|<=|>|>=|!=|==
<字母>   ::= _|a|...|z|A|...|Z

<数字>   ::= 0|<非零数字>
<非零数字>  ::= 1|...|9
<字符>    ::=  ‘<加法运算符>’|’<乘法运算符>’|’<字母>’|’<数字>’

<字符串>   ::=  “{十进制编码为32,33,35-126的ASCII字符}”

<程序>    ::= [<常量说明>][<变量说明>]{<有返回值函数定义>|<无返回值函数定义>}<主函数>

<常量说明> ::=  const<常量定义>;{ const<常量定义>;}
<常量定义>   ::=   int<标识符>=<整数>{,<标识符>=<整数>}

                           | char<标识符>=<字符>{,<标识符>=<字符>}

<无符号整数>  ::= <非零数字>{<数字>}| 0
<整数>        ::= [+|-]<无符号整数>

<标识符>    ::=  <字母>{<字母>|<数字>}

<声明头部>   ::=  int<标识符> |char<标识符>

<变量说明>  ::= <变量定义>;{<变量定义>;}

<变量定义>  ::= <类型标识符>(<标识符>|<标识符>'[‘<无符号整数>’]’){,(<标识符>|<标识符>'[‘<无符号整数>’]’ )}

                 //<无符号整数>表示数组元素的个数,其值需大于0

<类型标识符>      ::=  int | char

<有返回值函数定义>  ::=  <声明头部>'(‘<参数表>’)’ ‘{‘<复合语句>’}’
<无返回值函数定义>  ::= void<标识符>'(‘<参数表>’)”{‘<复合语句>’}’
<复合语句>   ::=  [<常量说明>][<变量说明>]<语句列>

<参数表>    ::=  <类型标识符><标识符>{,<类型标识符><标识符>}| <空>
<主函数>    ::= void main‘(’‘)’ ‘{’<复合语句>‘}’

<表达式>    ::= [+|-]<项>{<加法运算符><项>}   //[+|-]只作用于第一个<项>
<项>     ::= <因子>{<乘法运算符><因子>}
<因子>    ::= <标识符>|<标识符>'[‘<表达式>’]’|'(‘<表达式>’)’|<整数>|<字符>|<有返回值函数调用语句>         
<语句>    ::= <条件语句>|<循环语句>| ‘{‘<语句列>’}’| <有返回值函数调用语句>; 
                      |<无返回值函数调用语句>;|<赋值语句>;|<读语句>;|<写语句>;|<空>;|<返回语句>;

<赋值语句>   ::=  <标识符>=<表达式>|<标识符>'[‘<表达式>’]’=<表达式>
<条件语句>  ::= if ‘(‘<条件>’)’<语句>[else<语句>]
<条件>    ::=  <表达式><关系运算符><表达式> //整型表达式之间才能进行关系运算

        |<表达式>    //表达式为整型,其值为0条件为假,值不为0时条件为真                                             

<循环语句>   ::=  while ‘(‘<条件>’)’<语句>| do<语句>while ‘(‘<条件>’)’ |for'(‘<标识符>=<表达式>;<条件>;<标识符>=<标识符>(+|-)<步长>’)’<语句>
<步长>::= <无符号整数>  
<有返回值函数调用语句> ::= <标识符>'(‘<值参数表>’)’
<无返回值函数调用语句> ::= <标识符>'(‘<值参数表>’)’
<值参数表>   ::= <表达式>{,<表达式>}|<空>
<语句列>   ::= {<语句>}
<读语句>    ::=  scanf ‘(‘<标识符>{,<标识符>}’)’
<写语句>    ::= printf ‘(‘ <字符串>,<表达式> ‘)’| printf ‘(‘<字符串> ‘)’| printf ‘(‘<表达式>’)’
<返回语句>   ::=  return[‘(‘<表达式>’)’]   

【输入形式】testfile.txt中的符合文法要求的测试程序。

【输出形式】按如上要求将语法分析结果输出至output.txt中,中文字符的编码格式要求是UTF-8。

【特别提醒】(1)本次作业只考核对正确程序的处理,但需要为今后可能出现的错误情况预留接口。

                    (2)当前要求的输出只是为了便于评测,完成编译器中无需出现这些信息,请设计为方便打开/关闭这些输出的方案。

【样例输入】

const int const1 = 1, const2 = -100;
const char const3 = '_';
int change1;
char change3;
int gets1(int var1,int var2){
    change1 = var1 + var2;
    return (change1);
}
void main(){
    printf("Hello World");
    printf(gets1(10, 20));
}

【样例输出】

CONSTTK const
INTTK int
IDENFR const1
ASSIGN =
INTCON 1
<无符号整数>
<整数>
COMMA ,
IDENFR const2
ASSIGN =
MINU -
INTCON 100
<无符号整数>
<整数>
<常量定义>
SEMICN ;
CONSTTK const
CHARTK char
IDENFR const3
ASSIGN =
CHARCON _
<常量定义>
SEMICN ;
<常量说明>
INTTK int
IDENFR change1
<变量定义>
SEMICN ;
CHARTK char
IDENFR change3
<变量定义>
SEMICN ;
<变量说明>
INTTK int
IDENFR gets1
<声明头部>
LPARENT (
INTTK int
IDENFR var1
COMMA ,
INTTK int
IDENFR var2
<参数表>
RPARENT )
LBRACE {
IDENFR change1
ASSIGN =
IDENFR var1
<因子>
<项>
PLUS +
IDENFR var2
<因子>
<项>
<表达式>
<赋值语句>
SEMICN ;
<语句>
RETURNTK return
LPARENT (
IDENFR change1
<因子>
<项>
<表达式>
RPARENT )
<返回语句>
SEMICN ;
<语句>
<语句列>
<复合语句>
RBRACE }
<有返回值函数定义>
VOIDTK void
MAINTK main
LPARENT (
RPARENT )
LBRACE {
PRINTFTK printf
LPARENT (
STRCON Hello World
<字符串>
RPARENT )
<写语句>
SEMICN ;
<语句>
PRINTFTK printf
LPARENT (
IDENFR gets1
LPARENT (
INTCON 10
<无符号整数>
<整数>
<因子>
<项>
<表达式>
COMMA ,
INTCON 20
<无符号整数>
<整数>
<因子>
<项>
<表达式>
<值参数表>
RPARENT )
<有返回值函数调用语句>
<因子>
<项>
<表达式>
RPARENT )
<写语句>
SEMICN ;
<语句>
<语句列>
<复合语句>
RBRACE }
<主函数>
<程序>

  1 #include <iostream>
  2 #include <vector>
  3 #include <map>
  4 #include <string>
  5 #include <cstdio>
  6 #include <cctype>
  7 #include <regex>
  8 #include <algorithm>
  9 #include <fstream>
 10 using  namespace std;
 11 //关键字
 12 static vector<string> keyWordKey = {"const", "int", "char", "void", "main", "getint", "if", "else", "switch", "case", "default", "while", "for", "scanf", "printf", "return", "auto", "short", "long", "float", "double", "struct", "union", "enum", "typedef", "unsigned", "signed", "extern", "register", "static", "volatile", "do", "goto", "continue", "break", "sizeof"};
 13 
 14 //关键字种别码
 15 static vector<string> keyWordValue = {"CONSTTK", "INTTK", "CHARTK", "VOIDTK", "MAINTK", "GETINTTK", "IFTK", "ELSETK", "SWITCHTK", "CASETK", "DEFAULTTK", "WHILETK", "FORTK", "SCANFTK", "PRINTFTK", "RETURNTK", "AUTOTK", "SHORTTK", "LONGTK", "FLOATTK", "DOUBLETK", "STRUCTTK", "UNIONTK", "ENUMTK", "TYPEDEFTK", "UNSIGNEDTK", "SIGNEDTK", "EXTERNTK", "REGISTERTK", "STATICTK", "VOLATILLETK", "DOTK", "GOTOTK", "CONTINUETK", "BREAKTK", "SIZEOFTK"};
 16 
 17 //运算符
 18 static vector<string> operationKey = {"+", "-", "*", "/", "<", "<=", ">", ">=", "==", "!=", "="};
 19 //运算符种别码
 20 static vector<string> operationValue = {"PLUS", "MINU", "MULT", "DIV", "LSS", "LEQ", "GRE", "GEQ", "EQL", "NEQ", "ASSIGN"};
 21 
 22 //界符
 23 static vector<string> symbolKey = {":", ";", ",", "(", ")", "{", "}", "[", "]"};
 24 
 25 //界符种别码
 26 static vector<string> symbolValue = {"COLON", "SEMICN", "COMMA", "LPARENT", "RPARENT", "LBRACE", "RBRACE", "LBRACK", "RBRACK"};
 27 
 28 //语法分析当前单词的种别码
 29 static vector<string> Tokens;
 30 //语法分析当前单词
 31 static vector<string> vals;
 32 
 33 //key为函数的方法名,Value值为1表示该方法是有返回值的方法
 34 static map<string,int> NVoidFunction;
 35 
 36 static map<string,string> keywords;
 37 static map<string,string> operations;
 38 static map<string,string> symbols;
 39 
 40 //指向当前所读到字符串的位置的指针
 41 static int p, lines;
 42 
 43 //语法分析当前单词位置
 44 static int q;
 45 
 46 
 47 
 48 ofstream write("output.txt");
 49 ifstream read("testfile.txt");
 50 void lexAnalysing(string str);
 51 void init();
 52 void digitCheck(string str);
 53 void letterCheck(string str);
 54 void stringCheck(string str);
 55 void charCheck(string str);
 56 void symbolCheck(string str);
 57 void parsing();
 58 void parse0();
 59 void parse1();
 60 void parse2();
 61 void parse3();
 62 void parse4();
 63 void parse5();
 64 void parse6();
 65 void parse7();
 66 void parse8();
 67 void parse9();
 68 void parse10();
 69 void parse11();
 70 void parse12();
 71 void parse13();
 72 void parse14();
 73 void parse15();
 74 void parse16();
 75 void parse17();
 76 void parse18();
 77 void parse19();
 78 void parse20();
 79 void parse21();
 80 void parse22();
 81 void parse23();
 82 void parse234();
 83 void parse25();
 84 void parse26();
 85 void parse27();
 86 void parse28();
 87 void parse29();
 88 void MatchToken(string expected);
 89 int main(){
 90     init();
 91     lines=1;
 92     string line;
 93     while(getline(read,line)){
 94         lexAnalysing(line);
 95         lines++;
 96     }
 97     parsing();
 98     write.close();
 99     read.close();
100     return 0;
101 }
102 void init(){
103     for(int i=0;i<keyWordKey.size();i++){
104         keywords[keyWordKey[i]]=keyWordValue[i];
105     }
106     for(int i=0;i<operationKey.size();i++){
107         operations[operationKey[i]]=operationValue[i];
108     }
109     for(int i=0;i<symbolKey.size();i++){
110         symbols[symbolKey[i]]=symbolValue[i];
111     }
112 }
113 void lexAnalysing(string str) {
114     p=0;
115     char ch;
116     str.erase(0, str.find_first_not_of(' '));
117     str.erase(str.find_last_not_of(' ')+1);
118     for(;p<str.length();p++){
119         ch=str.at(p);
120         if(isdigit(ch)){
121             digitCheck(str);
122         }
123         else if(isalpha(ch) || ch == '_'){
124             letterCheck(str);
125         }
126         else if(ch == '"'){
127             stringCheck(str);
128         }
129         else if(ch == '\''){
130             charCheck(str);
131         }
132         else if(ch == ' '){
133             continue;
134         }
135         else {
136             symbolCheck(str);
137         }
138     }
139 }
140 void digitCheck(string str) {
141 
142     string token;
143     token.push_back(str.at(p++));
144     //判断数字的小数点是否有且是否大于1
145     int flag = 0;
146     bool err = false;
147     char ch;
148     for (; p < str.length(); p++) {
149         ch = str.at(p);
150         if (ch == ' ' || (!isalnum(ch) && ch != '.')) {
151             //遇到空格符,运算符或者界符
152             break;
153         } else if (err) {
154             token += ch;
155         } else {
156             token += ch;
157             if (ch == '.') {
158                 if (flag == 1) {
159                     err = true;
160                 } else {
161                     flag++;
162                 }
163             } else if (isalpha(ch)) {
164                 err = true;
165             }
166         }
167     }
168     if (token.at(token.length() - 1) == '.') {
169         err = true;
170     }
171     Tokens.emplace_back("INTCON");
172     vals.push_back(token);
173     if (p != str.length() - 1 || (p == str.length() - 1 && !isdigit(str.at(p)))) {
174         p--;
175     }
176 }
177 void letterCheck(string str) {
178     string token;
179     token.push_back(str.at(p++));
180     char ch;
181     for (; p < str.length(); p++) {
182         ch = str.at(p);
183         if (!isalnum(ch) && ch != '_') {
184             break;
185         } else {
186             token += ch;
187         }
188     }
189     if (keywords.count(token)) {
190         Tokens.push_back(keywords[token]);
191         vals.push_back(token);
192     } else {
193         Tokens.emplace_back("IDENFR");
194         vals.push_back(token);
195     }
196     if (p != str.length() - 1 || (p == str.length() - 1 && (!isalnum(str.at(p)) && str.at(p) != '_'))) {
197         p--;
198     }
199 }
200 void stringCheck(string str) {
201 
202     string token;
203     token.push_back(str.at(p++));
204     char ch;
205     for (; p < str.length(); p++) {
206         ch = str.at(p);
207         token += ch;
208         if (ch == '"') {
209             break;
210         }
211     }
212     token.erase(remove(token.begin(),token.end(),'\"'), token.end());
213     Tokens.emplace_back("STRCON");
214     vals.emplace_back(token);
215 }
216 void charCheck(string str)  {
217 
218     string token;
219     token.push_back(str.at(p++));
220     char ch;
221     for (; p < str.length(); p++) {
222         ch = str.at(p);
223         token += ch;
224         if (ch == '\'') {
225             break;
226         }
227     }
228     token.erase(remove(token.begin(),token.end(),'\''), token.end());
229     Tokens.emplace_back("CHARCON");
230     vals.push_back(token);
231 }
232 void symbolCheck(string str) {
233 
234     string token;
235     token.push_back(str.at(p++));
236     char ch;
237     if (symbols.count(token)) {
238         Tokens.push_back(symbols[token]);
239         vals.push_back(token);
240         p--;
241     } else {
242         if (operations.count(token) || token=="!") {
243             if (p < str.length()) {
244                 ch = str.at(p);
245                 if (operations.count(token + ch)) {
246                     token += ch;
247                     p++;
248                     if (p < str.length()) {
249                         ch = str.at(p);
250                         if (operations.count(token + ch)) {
251                             token += ch;
252                             Tokens.push_back(operations[token]);
253                             vals.push_back(token);
254                         } else {
255                             p--;
256                             Tokens.push_back(operations[token]);
257                             vals.push_back(token);
258                         }
259                     } else {
260                         Tokens.push_back(operations[token]);
261                         vals.push_back(token);
262                     }
263                 } else {
264                     p--;
265                     Tokens.push_back(operations[token]);
266                     vals.push_back(token);
267                 }
268             }
269         } else {
270             p--;
271         }
272     }
273 }
274 
275 void parsing(){
276     q = 0;
277     parse1(); //从<程序>节点开始
278 }
279 void parse0() {
280     //<字符串> ::=  "{十进制编码为32,33,35-126的ASCII字符}"
281     MatchToken("STRCON");
282     write<<"<字符串>"<<endl;
283     cout<<"<字符串>"<<endl;
284 }
285 void parse1() {
286     //<程序> ::= [<常量说明>][<变量说明>]{<有返回值函数定义>|<无返回值函数定义>}<主函数>
287     if (Tokens[q] == "CONSTTK") {
288         parse2(); //<常量说明>
289     }
290     if ((Tokens[q] == "INTTK" || Tokens[q] == "CHARTK") && Tokens[q+1] == "IDENFR" && Tokens[q+2] != "LPARENT") {
291         parse7(); //<变量说明>
292     }
293     while ((Tokens[q] == "INTTK" || Tokens[q] == "CHARTK" || Tokens[q] == "VOIDTK") &&
294            Tokens[q+1] == "IDENFR" && Tokens[q+2] == "LPARENT") {
295         if (Tokens[q] == "VOIDTK") {
296             parse10(); //<无返回值函数定义>
297         } else {
298             parse9(); //<有返回值函数定义>
299         }
300     }
301     if (Tokens[q] == "VOIDTK" && Tokens[q+1]== "MAINTK") {
302         parse13(); //<主函数>
303     }
304     if (q == Tokens.size()) {
305         cout<<"<程序>"<<endl;
306         write<<"<程序>"<<endl;
307     }
308 }
309 void parse2() {
310     //<常量说明> ::=  const<常量定义>;{ const<常量定义>;}
311     do {
312         MatchToken("CONSTTK");
313         parse3(); //<常量定义>
314         MatchToken("SEMICN");
315     } while (Tokens[q] == "CONSTTK");
316     cout<<"<常量说明>"<<endl;
317     write<<"<常量说明>"<<endl;
318 }
319 
320 void parse3() {
321     //<常量定义>   ::=   int<标识符>=<整数>{,<标识符>=<整数>}| char<标识符>=<字符>{,<标识符>=<字符>}
322     if (Tokens[q]== "INTTK") {
323         MatchToken("INTTK");
324         MatchToken("IDENFR");
325         MatchToken("ASSIGN");
326         parse5(); //<整数>
327         while (Tokens[q] == "COMMA") {
328             MatchToken("COMMA");
329             MatchToken("IDENFR");
330             MatchToken("ASSIGN");
331             parse5();
332         }
333     }
334     if (Tokens[q] == "CHARTK") {
335         MatchToken("CHARTK");
336         MatchToken("IDENFR");
337         MatchToken("ASSIGN");
338         MatchToken("CHARCON");
339         while (Tokens[q] == "COMMA") {
340             MatchToken("COMMA");
341             MatchToken("IDENFR");
342             MatchToken("ASSIGN");
343             MatchToken("CHARCON");
344         }
345     }
346     cout<<("<常量定义>")<<endl;
347     write<<("<常量定义>")<<endl;
348 
349 }
350 
351 void parse4() {
352 //<无符号整数>
353     MatchToken("INTCON");
354     cout<<("<无符号整数>")<<endl;
355     write<<("<无符号整数>")<<endl;
356 
357 }
358 
359 void parse5() {
360     //<整数> ::= [+|-]<无符号整数>
361     if (Tokens[q] == "PLUS")
362         MatchToken("PLUS");
363     else if (Tokens[q] == "MINU")
364         MatchToken("MINU");
365     parse4(); //<无符号整数>
366     cout<<("<整数>")<<endl;
367     write<<("<整数>")<<endl;
368 
369 }
370 
371 void parse6() {
372     //<声明头部> ::=  int<标识符> |char<标识符>
373     if (Tokens[q] == "INTTK")
374         MatchToken("INTTK");
375     else if (Tokens[q] == "CHARTK")
376         MatchToken("CHARTK");
377     MatchToken("IDENFR");
378     cout<<("<声明头部>")<<endl;
379     write<<("<声明头部>")<<endl;
380 
381 }
382 
383 void parse7() {
384     //<变量说明> ::= <变量定义>;{<变量定义>;}
385     do {
386         parse8(); //<变量定义>
387         MatchToken("SEMICN");
388     } while ((Tokens[q] == "INTTK" || Tokens[q] == "CHARTK") &&
389              Tokens[q + 1] == "IDENFR" && Tokens[q + 2] != "LPARENT");
390     cout<<("<变量说明>")<<endl;
391     write<<("<变量说明>")<<endl;
392 
393 }
394 void parse8() {
395     //<变量定义> ::= <类型标识符>(<标识符>|<标识符>'['<无符号整数>']'){,(<标识符>|<标识符>'['<无符号整数>']')}
396     if (Tokens[q] == "INTTK")
397         MatchToken("INTTK");
398     else if (Tokens[q] == "CHARTK")
399         MatchToken("CHARTK");
400     MatchToken("IDENFR");
401     if (Tokens[q] == "LBRACK") {
402         MatchToken("LBRACK");
403         parse4(); //<无符号整数>
404         MatchToken("RBRACK");
405     }
406     while (Tokens[q] == "COMMA") {
407         MatchToken("COMMA");
408         MatchToken("IDENFR");
409         if (Tokens[q] == "LBRACK") {
410             MatchToken("LBRACK");
411             parse4(); //<无符号整数>
412             MatchToken("RBRACK");
413         }
414     }
415     cout<<("<变量定义>")<<endl;
416     write<<("<变量定义>")<<endl;
417 
418 }
419 void parse9() {
420     //<有返回值函数定义> ::=  <声明头部>'('<参数表>')' '{'<复合语句>'}'
421     parse6(); //<声明头部>
422     NVoidFunction.insert({vals[q - 1], 1});
423     MatchToken("LPARENT");
424     parse12(); //<参数表>
425     MatchToken("RPARENT");
426     MatchToken("LBRACE");
427     parse11(); //<复合语句>
428     MatchToken("RBRACE");
429     cout<<("<有返回值函数定义>")<<endl;
430     write<<("<有返回值函数定义>")<<endl;
431 
432 }
433 void parse10() {
434     //<无返回值函数定义> ::= void<标识符>'('<参数表>')''{'<复合语句>'}'
435     MatchToken("VOIDTK");
436     MatchToken("IDENFR");
437     MatchToken("LPARENT");
438     parse12(); //<参数表>
439     MatchToken("RPARENT");
440     MatchToken("LBRACE");
441     parse11(); //<复合语句>
442     MatchToken("RBRACE");
443     cout<<("<无返回值函数定义>")<<endl;
444     write<<("<无返回值函数定义>")<<endl;
445 
446 }
447 void parse11() {
448     //<复合语句> ::=  [<常量说明>][<变量说明>]<语句列>
449     if (Tokens[q] == "CONSTTK") {
450         parse2(); //<常量说明>
451     }
452     if ((Tokens[q] == "INTTK" || Tokens[q] == "CHARTK") &&
453         Tokens[q + 1]== "IDENFR" && Tokens[q + 2] != "LPARENT") {
454         parse7(); //<变量说明>
455     }
456     parse26(); //<语句列>
457     cout<<("<复合语句>")<<endl;
458     write<<("<复合语句>")<<endl;
459 
460 }
461 void parse12() {
462     //<参数表> ::=  <类型标识符><标识符>{,<类型标识符><标识符>}| <空>
463     if (Tokens[q] != "RPARENT")//如果下一个token为右小括号,则为空
464     {
465         if (Tokens[q] == "INTTK")
466             MatchToken("INTTK");
467         else if (Tokens[q] == "CHARTK")
468             MatchToken("CHARTK");
469         MatchToken("IDENFR");
470         while (Tokens[q] == "COMMA") {
471             MatchToken("COMMA");
472             if (Tokens[q] == "INTTK")
473                 MatchToken("INTTK");
474             else if (Tokens[q] == "CHARTK")
475                 MatchToken("CHARTK");
476             MatchToken("IDENFR");
477         }
478     }
479     cout<<("<参数表>")<<endl;
480     write<<("<参数表>")<<endl;
481 
482 }
483 
484 void parse13() {
485     //<主函数> ::= void main‘(’‘)’ ‘{’<复合语句>‘}’
486     MatchToken("VOIDTK");
487     MatchToken("MAINTK");
488     MatchToken("LPARENT");
489     MatchToken("RPARENT");
490     MatchToken("LBRACE");
491     parse11(); //<复合语句>
492     MatchToken("RBRACE");
493     cout<<("<主函数>")<<endl;
494     write<<("<主函数>")<<endl;
495 
496 }
497 
498 void parse14() {
499     //<表达式> ::= [+|-]<项>{<加法运算符><项>}
500     if (Tokens[q] == "PLUS")
501         MatchToken("PLUS");
502     else if (Tokens[q] == "MINU")
503         MatchToken("MINU");
504     parse15(); //<项>
505     while (Tokens[q] == "PLUS" || Tokens[q] == "MINU") {
506         if (Tokens[q] == "PLUS")
507             MatchToken("PLUS");
508         else if (Tokens[q] == "MINU")
509             MatchToken("MINU");
510         parse15(); //<项>
511     }
512     cout<<("<表达式>")<<endl;
513     write<<("<表达式>")<<endl;
514 
515 }
516 
517 void parse15() {
518     //<项> ::= <因子>{<乘法运算符><因子>}
519     parse16(); //<因子>
520     while (Tokens[q] == "MULT" || Tokens[q] == "DIV") {
521         if (Tokens[q] == "MULT")
522             MatchToken("MULT");
523         else if (Tokens[q] == "DIV")
524             MatchToken("DIV");
525         parse16(); //<因子>
526     }
527     cout<<("<项>")<<endl;
528     write<<("<项>")<<endl;
529 
530 }
531 
532 void parse16() {
533     //<因子> ::= <标识符>|<标识符>'['<表达式>']'|'('<表达式>')'|<整数>|<字符>|<有返回值函数调用语句>
534     if (Tokens[q] == "IDENFR") {
535         if (Tokens[q + 1]== "LBRACK") {
536             MatchToken("IDENFR");
537             MatchToken("LBRACK");
538             parse14(); //<表达式>
539             MatchToken("RBRACK");
540         } else if (Tokens[q + 1 ]== "LPARENT")
541             parse234(); //<有返回值函数调用语句>
542         else MatchToken("IDENFR");
543     } else if (Tokens[q] == "LPARENT") {
544         MatchToken("LPARENT");
545         parse14(); //<表达式>
546         MatchToken("RPARENT");
547     } else if (Tokens[q] == "INTCON" || Tokens[q] == "PLUS" || Tokens[q] == "MINU")
548         parse5(); //<整数>
549     else if (Tokens[q] == "CHARCON")
550         MatchToken("CHARCON");
551     cout<<("<因子>")<<endl;
552     write<<("<因子>")<<endl;
553 
554 }
555 
556 void parse17() {
557     /*<语句> ::= <条件语句>|<循环语句>| '{'<语句列>'}'
558         | <有返回值函数调用语句>; |<无返回值函数调用语句>;|<赋值语句>;
559         |<读语句>;|<写语句>;|<空>;|<返回语句>;*/
560     if (Tokens[q] == "IFTK")
561         parse19(); //<条件语句>
562     else if (Tokens[q] == "WHILETK" || Tokens[q] == "DOTK" || Tokens[q] == "FORTK")
563         parse21(); //<循环语句>
564     else if (Tokens[q] == "LBRACE") {
565         MatchToken("LBRACE");
566         parse26(); //<语句列>
567         MatchToken("RBRACE");
568     } else if (Tokens[q] == "IDENFR") {
569         if (Tokens[q + 1] == "LPARENT") {
570             parse234(); //<有无返回值函数调用语句>
571             MatchToken("SEMICN");
572         } else {
573             parse18(); //<赋值语句>
574             MatchToken("SEMICN");
575         }
576     } else if (Tokens[q] == "SCANFTK") {
577         parse27(); //<读语句>
578         MatchToken("SEMICN");
579     } else if (Tokens[q] == "PRINTFTK") {
580         parse28(); //<写语句>
581         MatchToken("SEMICN");
582     } else if (Tokens[q] == "RETURNTK") {
583         parse29(); //<返回语句>
584         MatchToken("SEMICN");
585     } else if (Tokens[q] == "SEMICN")
586         MatchToken("SEMICN");
587     cout<<("<语句>")<<endl;
588     write<<("<语句>")<<endl;
589 
590 }
591 
592 void parse18() {
593     //<赋值语句> ::=  <标识符>=<表达式>|<标识符>'['<表达式>']'=<表达式>
594     MatchToken("IDENFR");
595     if (Tokens[q] == "LBRACK") {
596         MatchToken("LBRACK");
597         parse14(); //<表达式>
598         MatchToken("RBRACK");
599     }
600     MatchToken("ASSIGN");
601     parse14(); //<表达式>
602     cout<<("<赋值语句>")<<endl;
603     write<<("<赋值语句>")<<endl;
604 
605 }
606 
607 void parse19() {
608     //<条件语句> ::= if '('<条件>')'<语句>[else<语句>]
609     MatchToken("IFTK");
610     MatchToken("LPARENT");
611     parse20(); //<条件>
612     MatchToken("RPARENT");
613     parse17(); //<语句>
614     if (Tokens[q] == "ELSETK") {
615         MatchToken("ELSETK");
616         parse17(); //<语句>
617     }
618     cout<<("<条件语句>")<<endl;
619     write<<("<条件语句>")<<endl;
620 
621 }
622 
623 void parse20() {
624     //<条件>    ::=  <表达式><关系运算符><表达式> //整型表达式之间才能进行关系运算|<表达式>
625     // 表达式为整型,其值为0条件为假,值不为0时条件为真
626     parse14(); //<表达式>
627     if (Tokens[q] == "LSS" || Tokens[q] == "LEQ" || Tokens[q] == "GRE"
628         || Tokens[q] == "GEQ" || Tokens[q] == "EQL" || Tokens[q] == "NEQ") {
629         MatchToken((string) Tokens[q]);
630         parse14(); //<表达式>
631     }
632     cout<<("<条件>")<<endl;
633     write<<("<条件>")<<endl;
634 
635 }
636 
637 void parse21() {
638     //<循环语句> ::=  while '('<条件>')'<语句>
639     //          |do<语句>while '('<条件>')'
640     //          |for'('<标识符>=<表达式>;<条件>;<标识符>=<标识符>(+|-)<步长>')'<语句>
641     if (Tokens[q] == "WHILETK") {
642         MatchToken("WHILETK");
643         MatchToken("LPARENT");
644         parse20(); //<条件>
645         MatchToken("RPARENT");
646         parse17(); //<语句>
647     } else if (Tokens[q] == "DOTK") {
648         MatchToken("DOTK");
649         parse17(); //<语句>
650         MatchToken("WHILETK");
651         MatchToken("LPARENT");
652         parse20(); //<条件>
653         MatchToken("RPARENT");
654     } else if (Tokens[q] == "FORTK") {
655         MatchToken("FORTK");
656         MatchToken("LPARENT");
657         MatchToken("IDENFR");
658         MatchToken("ASSIGN");
659         parse14(); //<表达式>
660         MatchToken("SEMICN");
661         parse20(); //<条件>
662         MatchToken("SEMICN");
663         MatchToken("IDENFR");
664         MatchToken("ASSIGN");
665         MatchToken("IDENFR");
666         if (Tokens[q] == "PLUS")
667             MatchToken("PLUS");
668         else if (Tokens[q] == "MINU")
669             MatchToken("MINU");
670         parse22(); //<步长>
671         MatchToken("RPARENT");
672         parse17(); //<语句>
673     }
674     cout<<("<循环语句>")<<endl;
675     write<<("<循环语句>")<<endl;
676 
677 }
678 
679 void parse22() {
680     //<步长>::= <无符号整数>
681     parse4(); //<无符号整数>
682     cout<<("<步长>")<<endl;
683     write<<("<步长>")<<endl;
684 
685 }
686 
687 void parse234() {
688     //<有无返回值函数调用语句> ::= <标识符>'('<值参数表>')'
689     int FunctionType = 0;
690     if(NVoidFunction.count(vals[q])) {
691         FunctionType = NVoidFunction[vals[q]];
692     }
693     MatchToken("IDENFR");
694     MatchToken("LPARENT");
695     parse25(); //<值参数表>
696     MatchToken("RPARENT");
697     if (FunctionType == 1) {
698         cout<<("<有返回值函数调用语句>")<<endl;
699         write<<("<有返回值函数调用语句>")<<endl;
700 
701     } else {
702         cout<<("<无返回值函数调用语句>")<<endl;
703         write<<("<无返回值函数调用语句>")<<endl;
704 
705     }
706 }
707 
708 void parse25() {
709     //<值参数表> ::= <表达式>{,<表达式>}|<空>
710     if (Tokens[q] != "RPARENT") {
711         parse14(); //<表达式>
712         while (Tokens[q] == "COMMA") {
713             MatchToken("COMMA");
714             parse14();
715         }
716     }
717     cout<<("<值参数表>")<<endl;
718     write<<("<值参数表>")<<endl;
719 
720 }
721 
722 void parse26() {
723     //<语句列> ::= {<语句>}
724     while (Tokens[q] != "RBRACE")
725         parse17(); //<语句>
726     cout<<("<语句列>")<<endl;
727     write<<("<语句列>")<<endl;
728 
729 }
730 
731 void parse27() {
732     //<读语句> ::=  scanf '('<标识符>{,<标识符>}')'
733     MatchToken("SCANFTK");
734     MatchToken("LPARENT");
735     MatchToken("IDENFR");
736     while (Tokens[q] == "COMMA") {
737         MatchToken("COMMA");
738         MatchToken("IDENFR");
739     }
740     MatchToken("RPARENT");
741     cout<<("<读语句>")<<endl;
742     write<<("<读语句>")<<endl;
743 
744 }
745 
746 void parse28() {
747     //<写语句> ::= printf '(' <字符串>,<表达式> ')'
748     //          | printf '('<字符串> ')'
749     //          | printf '('<表达式>')'
750     MatchToken("PRINTFTK");
751     MatchToken("LPARENT");
752     if (Tokens[q] == "STRCON")
753         parse0(); //<字符串>
754     else
755         parse14(); //<表达式>
756     if (Tokens[q] == "COMMA") {
757         MatchToken("COMMA");
758         parse14(); //<表达式>
759     }
760     MatchToken("RPARENT");
761     cout<<("<写语句>")<<endl;
762     write<<("<写语句>")<<endl;
763 
764 }
765 
766 void parse29() {
767     //<返回语句> ::=  return['('<表达式>')']
768     MatchToken("RETURNTK");
769     if (Tokens[q] == "LPARENT") {
770         MatchToken("LPARENT");
771         parse14(); //<表达式>
772         MatchToken("RPARENT");
773     }
774     cout<<("<返回语句>")<<endl;
775     write<<("<返回语句>")<<endl;
776 
777 }
778 
779 void MatchToken(string expected) {
780     if (Tokens[q] == expected) {
781         cout<<Tokens[q]<<" "<<vals[q]<<endl;
782         write<<Tokens[q]<<" "<<vals[q]<<endl;
783         q++; //下一个单词
784     }
785 }

 

原文地址:http://www.cnblogs.com/rrrover/p/16881398.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性