编译原理c++基于LR分析表编写语法分析器

具体要求

已知文法G[E]:

E->E+T | T

T->(E) | id | id[E] //其中E,T为非终结符,其余符号为终结符

(1)为该文法建立LR分析表。//通过构造项目集规范族完成识别可归前缀的DFA。

(2)根据测试样例及你建立的LR分析表,用c++完成语法分析器的设计。

测试样例

要求格式完全一致,第一行为输入,第二行为要求的输出,共四组样例。

a1 + a2

Syntax analysis is right

 

a1 + (a2)

Syntax analysis is right

 

a1++a2

Error on syntax analysis

 

a1[a2 + a3] + a4 + a5

Syntax analysis is right

 

a1 + a2[a3] + a4 + (a5 + a6)

Syntax analysis is right

PS

1.代码仅考虑了变量为a0-a9的情况,如有变化,需要进行修改。

2.代码在本机测试时完全正确,在上传在线平台验证时报错,信息如下:

 具体原因未知,怀疑是数组或栈的问题,在解决后更新。。。

  运行时错误(SIGSEGV)
错误原因可能是:
非法的内存引用, 具体原因可能是:
1.数组越界使用;
2.指针的错误使用, 一般是对非用户区的地址空间进行读或者写操作;
3.越权操作文件指针, 程序中却未捕捉该类错误;
4.栈溢出, 一般是因为过多的递归调用或者过大的临时变量导致;5.程序使用的内存超过了题目设定的上限。

 

具体实现

#include 

#include 

#include 

#include 
 
#include  

#include 

#define MAXNUM 1000

using namespace std;

int symbolNum;
string inputSymbol[MAXNUM];
stack status;
stack instr;
stack symbol;

int table1[12][7]={0,1,0,0,0,1,0,
					1,0,0,0,0,0,-1,
					2,0,2,0,2,0,2,
					2,0,2,0,2,1,2,
					2,0,2,1,2,0,2,
					0,1,0,0,0,1,0,
					0,1,0,0,0,1,0,
					1,0,1,0,0,0,0,
					1,0,0,0,1,0,0,
					2,0,2,0,2,0,2,
					2,0,2,0,2,0,2,
					2,0,2,0,2,0,2};
int table2[12][7]={0,3,0,0,0,4,0,
					5,0,0,0,0,0,0,
					2,0,2,0,2,0,2,
					4,0,4,0,4,4,4,
					4,0,4,6,4,0,4,
					0,3,0,0,0,4,0,
					0,3,0,0,0,4,0,
					5,0,10,0,0,0,0,
					5,0,0,0,11,0,0,
					1,0,1,0,1,0,1,
					3,0,3,0,3,0,3,
					5,0,5,0,5,0,5};;
int table3[12][2]={1,2,
					0,0,
					0,0,
					7,2,
					0,0,
					0,9,
					8,2,
					0,0,
					0,0,
					0,0,
					0,0,
					0,0};;

map infer;
map infernum;
map inferstr;

void initial(){
	
	infer["E+T"] = "E";
  	infer["T"] = "E";
  	infer["(E)"] = "T";
  	infer["id"] = "T";
  	infer["id[E]"] = "T";
  	
	infernum["E+T"] = 3;
  	infernum["T"] = 1;
  	infernum["(E)"] = 3;
  	infernum["id"] = 1;
  	infernum["id[E]"] = 4;
  	
  	inferstr[1]="E+T";
  	inferstr[2]="T";
  	inferstr[3]="(E)";
  	inferstr[4]="id";
  	inferstr[5]="id[E]";
  	
	status.push(0);

	instr.push("#");
	symbol.push("#");

	for (int i=symbolNum-1; i>=0; i--) {
		symbol.push(inputSymbol[i]);
	}
}

bool isnumber (char ch){
		
		if(ch>=48 && ch<=57){
            return 1;
        }
     
    return 0;
}

int symboltoint(string ch){
	if(ch=="+")return 0;
	if(ch=="(")return 1; 
	if(ch==")")return 2;
	if(ch=="[")return 3;
	if(ch=="]")return 4;
	if(ch=="id")return 5;
	if(ch=="#")return 6;
}

int instrtoint(string ch){
	if(ch=="E")return 0;
	if(ch=="T")return 1;
}

void grammerAnalysis(){
	int action,change,number;
	while(true){
		action=table1[status.top()][symboltoint(symbol.top())];//1,2
		change=table2[status.top()][symboltoint(symbol.top())];//4,2
		//action:S,移进
		if(action==1){
		 	instr.push(symbol.top());
		 	symbol.pop();
		 	status.push(change);
		}
		//action:r,规约 
		else if(action==2){
			string n=inferstr[change];
			for(int i=0;i

12月19日更新:

不容易,花了好几个小时终于过了。

报错原因:系统中,scanf函数不接受换行符‘\n’

解决办法:用getline函数直接获取一整行字符串的输入,再把字符串的每一个字符挨个放进字符数组里

代码如下:修改main函数中读取输入的部分

	string input;
	char ch[1024];
	int number;
	getline(cin,input);
	for(int i=0;i<=input.length();i++){
		ch[number++]=input[i];
	}
	//cout<

 

你可能感兴趣的:(编译原理c++基于LR分析表编写语法分析器)