编译原理——实验2 递归下降语法分析程序设计
【实验要求】
(1)待分析的简单语言的词法同实验1
(2)待分析的简单语言的语法
用扩充的BNF表示如下:
1)<程序>::=begin<语句串>end
2) <语句串>::=<语句>{;<语句>}
3) <语句>::=<赋值语句>
4) <赋值语句>::=ID:=<表达式>
5) <表达式>::=<项>{+<项>|-<项>}
6) <项>::=<因子>{*<因子>|/<因子>}
7) <因子>::=ID|NUM|(<表达式>)
(3)语法分析程序的功能
输入单词串以”#”结束,如果是文法正确的句子,输出成功信息;否则输出错误信息。
例如:
输入 begin a:=9; x:=2 * 3; b:=a + x end #
输出 success
输入 x:=a + b * c end #
输出 error
这个实验二与实验一是有一定联系的,实验一请观看:
实验一 词法分析器实验:https://blog.csdn.net/weixin_44566432/article/details/105415058
具体代码:
#include <iostream>
#include <cstring>
using namespace std;
char prog[800]; //存储程序
char token[10]; //存储单词字符串
char ch; //当前字符
int syn; //单词种别码
int sum; //整型常数
int p; //prog指针
int m; //token指针
int n;
int kk; //错误标记
//关键字
const char * rwtab[6] = {"begin", "if", "then", "while", "do", "end"};
bool isLetter(char ch); //判断是否为字母
bool isDigit(char ch); //判断是否为数字
void scanner(); //扫描分析器
void Irparser(); //语法分析器
void yucu(); //语句串分析函数
void statement(); //语句分析函数
void expression(); //表达式分析函数
void term();
void factor();
bool isLetter(char ch){
if ((ch <= 'z' && ch >='a') || (ch <'Z' && ch >= 'A')){
return true;
}
else{
return false;
}
}
bool isDigit(char ch){
if(ch >= '0' && ch <= '9'){
return true;
}
else{
return false;
}
}
void scanner(){
//清空token
for (n = 0 ; n < 8; n++){
token[n] = NULL;
}
m = 0;
//获取下一个有效字符
ch = prog[p];
while(ch == ' '){
p++;
ch = prog[p];
}
if(isDigit(ch)){
//字符为数字
sum = 0;
while (isDigit(ch)){
sum = sum * 10 + ch - '0'; //str转换为数值类型
p++;
ch = prog[p];
syn = 11;
}
}
//字符为字符串
else if(isLetter(ch)){
while(isDigit(ch) || isLetter(ch)){
token[m] = ch;
m++;
p++;
ch = prog[p];
}
token[m] = '\0';
m++;
syn = 10;
for(n = 0; n < 6; n++){
if(strcmp(token, rwtab[n]) == 0){
syn = n + 1;
break;
}
}
}
else{
switch (ch){
case '<':
syn = 20;
m = 0;
token[m] = ch;
m++;
p++;
ch = prog[p];
if (ch == '>') {
syn = 21;
token[m] = ch;
m++;
p++;
ch = prog[p];
}
else if (ch == '=') {
syn = 22;
token[m++] = ch;
m++;
p++;
ch = prog[p];
}
break;
case '>':
syn = 23;
m = 0;
token[m++] = ch;
p++;
ch = prog[p];
if (ch == '=') {
syn = 24;
token[m] = ch;
m++;
p++;
ch = prog[p];
}
break;
case ':':
syn = 17;
m = 0;
token[m] = ch;
m++;
p++;
ch = prog[p];
if (ch == '=') {
syn = 18;
token[m] = ch;
m++;
p++;
ch = prog[p];
}
break;
case '+':
syn = 13;
token[0] = ch;
p++;
ch = prog[p];
break;
case '-':
syn = 14;
token[0] = ch;
p++;
ch = prog[p];
break;
case '*':
syn = 15;
token[0] = ch;
p++;
ch = prog[p];
break;
case '/':
syn = 16;
token[0] = ch;
p++;
ch = prog[p];
break;
case '=':
syn = 25;
token[0] = ch;
p++;
ch = prog[p];
break;
case ';':
syn = 26;
token[0] = ch;
p++;
ch = prog[p];
break;
case '(':
syn = 27;
token[0] = ch;
p++;
ch = prog[p];
break;
case ')':
syn = 28;
token[0] = ch;
p++;
ch = prog[p];
break;
case '#':
syn = 0;
token[0] = ch;
break;
default:
syn = -1;
break;
}
}
}
void Irparser(){
if (syn ==1){
scanner();
yucu();
if (syn == 6){
scanner();
if (syn == 0 && (kk == 0)){
cout << "success" << endl;
}
}
else{
if (kk != 1){
cout << "缺少end,error" << endl;
kk = 1;
}
}
}
else{
cout << "begin,error!" << endl;
kk = 1;
}
}
void yucu(){
statement();
while (syn == 26){
scanner();
statement();
}
}
void statement(){
if (syn == 10){
scanner();
if (syn == 18){
scanner();
expression();
}
else{
cout << "赋值号error!" << endl;
kk = 1;
}
}
else{
cout << "语句(标识符)error!" << endl;
kk = 1;
}
}
void expression(){
term();
while(syn == 13 || syn == 14){
scanner();
term();
}
}
void term(){
factor() ;
while (syn == 15 || syn == 16){
scanner();
factor();
}
}
void factor(){
if(syn == 10 || syn == 11){
scanner();
}
else if (syn == 27){
scanner();
expression();
if (syn == 28){
scanner();
}
else{
cout << ")error!" << endl;
kk = 1;
}
}
}
int main(int argc, char** argv) {
cout << "please input string: \n" << endl;
p = 0;
char str;
//获取程序
do{
str = getchar();
prog[p] = str;
p++;
}while(str != '#');
p = 0;
ch = prog[p];
scanner();
Irparser();
//开始分析
// do{
// scanner();
// switch(syn){
// case 11:
// cout << "(" << syn << "," << sum << ")" << endl;
// break;
// case -1:
// cout << "error" << endl;
// break;
// default:
// cout << "("<< syn << "," << token << ")" <<endl;
// }
// }while(syn != 0);
system("pause");
return 0;
}
是的,终于写完啦,好开心!!!