85397518 2020-05-16
系列第二更!
【问题描述】
最基本的要求,能对一个算术表达式(a+15)*b做自上而下的语法分析,具体内容见实验指导实验二的内容,文法在实验指导最开始几页,重点关注以下几条文法的EBNF,若不习惯看文法的巴科斯范式EBNF,可先将文法改写成常规的产生式形式P75:
<表达式> ::= [+|-]<项>{<加法运算符> <项>}
<项> ::= <因子>{<乘法运算符> <因子>}
<因子> ::= <标识符>|<无符号整数>| ‘(’<表达式>‘)’
<加法运算符> ::= +|-
<乘法运算符> ::= *|/
考虑到大家用的编程语言不同,且实验一有少数同学没有得到正确结果,为不影响实验二的开展,实验二的输入统一采用词法分析器的输出结果为输入。输入形式如下:
【输入形式】
(lparen,() (ident,a) (plus,+) (number,15) (rparen,)) (times,*) (ident,b)
【输出形式】
对于语法正确的表达式,报告“语法正确”,输出为“Yes,it is correct.”
对于语法错误的表达式,报告“语法错误”,输出为“No,it is wrong.”
【样例输入】
(lparen,() (ident,a) (plus,+) (number,15) (rparen,)) (times,*) (ident,b)
【样例输出】
Yes,it is correct.
补充说明:学有余力的同学,可以在完成本实验后思考如何将词法分析的程序和语法分析的程序写在一起?以语法分析程序为主程序,词法分析程序为被调用程序,直接用(a+15)b做输入。(注意:这个扩展的写法请不要传到编程题!!!可以写在实验报告中。因为实验二的编程题的测试输入形式我给的不是(a+15)b,而是用(a+15)*b的词法分析的输出作为实验二语法分析的输入,如上面的样例输入形式。)
选择递归下降分析方法:
1.设计出每个非终结符的文法识别过程
2.将输入数据进行处理,提取出单词的编码
3.为每个非终结符写识别递归函数
4.函数相互调用
数据读入和错误处理部分我处理的不是很妥当,对于这个题目是OK的,但是不健壮。
#include <iostream> #include <string> #include<bits/stdc++.h> #define N 8 using namespace std; string words[N];//每个元素都是“lparen”/“ident”这样的标志符 int sym=0;//words的指针 // 函数声明 void E(); void T(); void F(); // 填充words数组 void getwords() { string line; for(int i=0; i<N-1; i++) { cin >> line; int pos = line.find(‘,‘, 0); words[i] = line.substr(1, pos-1); // cout << words[i]; } } // 指针前进 void advance() { ++sym; if(sym > N-1){ cout << "ERROR!words指针越界"; exit(0); } } // 因子分析 void F() { //cout << "F正在分析" << words[sym] << endl; if(words[sym] == "ident"){ advance(); } else if(words[sym] == "number") { advance(); } else if(words[sym] == "lparen") { advance(); E(); //cout << "E返回,F正在分析" << words[sym] << endl; if(words[sym] == "rparen") { advance(); } else { //cout << "ERROR!未能匹配右括号!语法错误" << endl; exit(0); } } return; } // 项分析 void T() { //cout << "T正在分析" << words[sym] << endl; F(); //cout << "1F返回,T正在分析" << words[sym] << endl; while(words[sym] == "times" || words[sym] == "slash"){ advance(); F(); //cout << "2F返回,T正在分析" << words[sym] << endl; } return; } // 表达式分析 void E() { //cout << "E正在分析" << words[sym] << endl; if(words[sym] == "plus" || words[sym] == "minus"){ advance(); } T(); //cout << "1T返回,E正在分析" << words[sym] << endl; while(words[sym] == "plus" || words[sym] == "minus") { advance(); T(); //cout << "2T返回,E正在分析" << words[sym] << endl; } return; } int main() { getwords(); E(); if(sym == N-1) { cout << "Yes,it is correct." << endl; } else { cout << "No,it is wrong."; } return 0; }