/*要求:1. 使用的文法如下(见编译陈第三版):E TE E + TE | T FT T * FT | F (E) | id2. 对于任意给定的输入串(词法记号流)进行语法分析,递归下降方法和非递归预测分析方法可以任选其一来实现。3. 要有一定的错误处理功能。即对错误能提示,并且能在一定程度上忽略尽量少的记号来进行接下来的分析。可以参考书上介绍的同步记号集合来处理。可能的出错情况:idid*id, id**id, (id+id, +id*+id ……4. 输入串以#结尾,输出推导过程中使用到的产生式。例如: 输入:id+id*id# 输出:E TE T FT F idE + TE T FT ……如果输入串有错误,则在输出中要体现是跳过输入串的某些记号了,还是弹栈,弹出某个非终结符或者是终结符了,同时给出相应的出错提示信息。比如:idid*id对应的出错信息是:“输入串跳过记号id,用户多输入了一个id”;id**id对应的出错信息是:“弹栈,弹出非终结符F,用户少输入了一个id”(id+id对应的出错信息是:“弹栈,弹出终结符 ) ,用户少输入了一个右括号(或者说,括号不匹配)”
*/
#include <iostream>
#include "textanalyse.h"
#include<string>
#include<stack>
using namespace std;
string nexttoken(int index,list <string> stringlist)
{
int k=0;
list<string>::iterator i;
for (i = stringlist.begin(); i != stringlist.end(); ++i)
//测试
// cout<<*i<<endl;
{
if(k==index)
{
return *i;
}
k++;
}
return " ";
}
string str[5][6]={{"E→TE'"," "," ","E→TE'","synch","synch"},
{" ","E'→+TE'"," "," ","E'→ε","E'→ε"},
{"T→FT'","synch"," ","T→FT'","synch","synch"},
{" ","T'→ε","T'→*FT'"," ","T'→ε","T'→ε"},
{"F→id","synch","synch","F→(E)","synch","synch"}};;
static map<string ,int> tablenum;
void inittable()
{
tablenum.insert(map<string,int>::value_type("id",0));
tablenum.insert(map<string,int>::value_type("+",1));
tablenum.insert(map<string,int>::value_type("*",2));
tablenum.insert(map<string,int>::value_type("(",3));
tablenum.insert(map<string,int>::value_type(")",4));
tablenum.insert(map<string,int>::value_type("$",5));
}
stack<string> s;
int index=0;
int findtablevalue(string key)
{
map<string,int >::iterator l_it;;
l_it=tablenum.find(key);
if(l_it==tablenum.end())
return -1;
else
return l_it->second;
}
void analyse(list<string>a)
{
int max=a.size();
s.push("$");
s.push("E");
for(index=0;index<max;index++)
{
if(s.top()=="E"&&(nexttoken(index,a)=="id"))
{
cout<<str[0][0]<<endl;
s.pop();
s.push("E'");
s.push("T");
index--;
}
else if(s.top()=="E'"&&(nexttoken(index,a)=="id"))
{
cout<<"error,user input duplicated id,ignore id"<<endl;
}
else if(s.top()=="T"&&(nexttoken(index,a)=="id"))
{
cout<<str[2][0]<<endl;
s.pop();
s.push("T'");
s.push("F");
index--;
}
else if(s.top()=="T'"&&(nexttoken(index,a)=="id"))
{
cout<<"error,user input duplicated id,ignore id"<<endl;
}
else if(s.top()=="F"&&(nexttoken(index,a)=="id"))
{
cout<<str[4][0]<<endl;
s.pop();
s.push("id");
index--;
}
else if(s.top()=="E"&&(nexttoken(index,a)=="+"))
{
cout<<"error,user input duplicated id,ignore +"<<endl;
}
else if(s.top()=="E'"&&(nexttoken(index,a)=="+"))
{
cout<<str[1][1]<<endl;
s.push("E'");
s.push("T");
s.push("+");
index--;
}
else if(s.top()=="T"&&(nexttoken(index,a)=="+"))
{
cout<<"Pop stack T,lost id"<<endl;
s.pop();
index--;
}
else if(s.top()=="T'"&&(nexttoken(index,a)=="+"))
{
cout<<str[3][1]<<endl;
s.pop();
index--;
}
else if(s.top()=="F"&&(nexttoken(index,a)=="+"))
{
cout<<"Pop stack F,lost id"<<endl;
s.pop();
index--;
}
else if(s.top()=="E"&&(nexttoken(index,a)=="*"))
{
cout<<"error,user input duplicated id,ignore *"<<endl;
}
else if(s.top()=="E'"&&(nexttoken(index,a)=="*"))
{
cout<<"error,user input duplicated id,ignore *"<<endl;
}
else if(s.top()=="T'"&&(nexttoken(index,a)=="*"))
{
cout<<str[3][2]<<endl;
s.pop();
s.push("T'");
s.push("F");
s.push("*");
index--;
}
else if(s.top()=="T"&&(nexttoken(index,a)=="*"))
{
cout<<"error,user input duplicated id,ignore *"<<endl;
}
else if(s.top()=="F"&&(nexttoken(index,a)=="*"))
{
cout<<"Pop stack F,lost id"<<endl;
s.pop();
index--;
}
else if(s.top()=="E"&&(nexttoken(index,a)=="("))
{
cout<<str[0][3]<<endl;
s.pop();
s.push("E'");
s.push("T");
index--;
}
else if(s.top()=="E'"&&(nexttoken(index,a)=="("))
{
cout<<"error,user input duplicated id,ignore ("<<endl;
}
else if(s.top()=="T"&&(nexttoken(index,a)=="("))
{
cout<<str[2][3]<<endl;
s.pop();
s.push("T'");
s.push("F");
index--;
}
else if(s.top()=="T'"&&(nexttoken(index,a)=="("))
{
cout<<"error,user input duplicated id,ignore ("<<endl;
}
else if(s.top()=="F"&&(nexttoken(index,a)=="("))
{
cout<<str[4][3]<<endl;
s.pop();
s.push(")");
s.push("E");
s.push("(");
index--;
}
else if(s.top()=="E"&&(nexttoken(index,a)==")"))
{
cout<<"Pop stack E,lost id"<<endl;
s.pop();
index--;
}
else if(s.top()=="E'"&&(nexttoken(index,a)==")"))
{
cout<<str[1][4]<<endl;
s.pop();
index--;
}
else if(s.top()=="T"&&(nexttoken(index,a)==")"))
{
cout<<"Pop stack T,lost id"<<endl;
s.pop();
index--;
}
else if(s.top()=="T'"&&(nexttoken(index,a)==")"))
{
cout<<str[3][4]<<endl;
s.pop();
index--;
}
else if(s.top()=="F"&&(nexttoken(index,a)==")"))
{
cout<<"Pop stack F,lost id"<<endl;
s.pop();
index--;
}
else if(s.top()=="E"&&(nexttoken(index,a)=="$"))
{
cout<<"Pop stack E,lost id"<<endl;
s.pop();
index--;
}
else if(s.top()=="E'"&&(nexttoken(index,a)=="$"))
{
cout<<str[1][5]<<endl;
s.pop();
index--;
}
else if(s.top()=="T"&&(nexttoken(index,a)=="$"))
{
cout<<"Pop stack T,lost id"<<endl;
s.pop();
index--;
}
else if(s.top()=="T'"&&(nexttoken(index,a)=="$"))
{
cout<<str[3][5]<<endl;
s.pop();
index--;
}
else if(s.top()=="F"&&(nexttoken(index,a)=="$"))
{
cout<<"Pop stack F,lost id"<<endl;
s.pop();
index--;
}
else if(s.top()=="id"&&(nexttoken(index,a)=="id"))
{
s.pop();
}
else if(s.top()=="id"&&(nexttoken(index,a)!="id"))
{
cout<<"error,user input duplicated id,id"<<endl;
}
else if(s.top()=="("&&(nexttoken(index,a)=="("))
{
s.pop();
}
else if(s.top()=="("&&(nexttoken(index,a)!="("))
{
cout<<"error,user input duplicated id,((error"<<endl;
}
else if(s.top()=="+"&&(nexttoken(index,a)=="+"))
{
s.pop();
}
else if(s.top()==")"&&(nexttoken(index,a)==")"))
{
s.pop();
}
else if(s.top()==")"&&(nexttoken(index,a)!=")"))
{
cout<<"error,user input duplicated id,))error"<<endl;
}
else if(s.top()=="+"&&(nexttoken(index,a)=="+"))
{
s.pop();
}
else if(s.top()=="+"&&(nexttoken(index,a)!="+"))
{
cout<<"error,user input duplicated id,+"<<endl;
}
else if(s.top()=="*"&&(nexttoken(index,a)=="*"))
{
s.pop();
}
else if(s.top()=="*"&&(nexttoken(index,a)!="*"))
{
cout<<"error,user input duplicated id,*"<<endl;
}
else if(s.top()=="$"&&(nexttoken(index,a)=="$"))
{
s.pop();
cout<<"acc"<<endl;
return;
}
else if(s.top()=="$"&&(nexttoken(index,a)!="$"))
{
cout<<"error,user input duplicated id,$"<<endl;
}
}
}
void E();
void EE();
void T();
void TT();
void F();
int main()
{
analyse(File_output("a.txt"));
/* cout<<nexttoken(0,File_output("a.txt"))<<endl;
cout<<"1"<<endl;
cout<<nexttoken(1,File_output("a.txt"))<<endl;
cout<<"2"<<endl;
cout<<nexttoken(2,File_output("a.txt"))<<endl;
cout<<"3"<<endl;
cout<<nexttoken(3,File_output("a.txt"))<<endl;*/
return 0;
}
#include <iostream>
#include<string>
#include<map>
#include<sstream>
#include <fstream>
#include <list>
using namespace std;
static map<string ,int> dictionary;
void init()
{
dictionary.insert(map<string,int>::value_type("for",1));
dictionary.insert(map<string,int>::value_type("if",2));
dictionary.insert(map<string,int>::value_type("then",3));
dictionary.insert(map<string,int>::value_type("else",4));
dictionary.insert(map<string,int>::value_type("while",5));
dictionary.insert(map<string,int>::value_type("do",6));
dictionary.insert(map<string,int>::value_type("var",10));
dictionary.insert(map<string,int>::value_type("num",11));
dictionary.insert(map<string,int>::value_type("+",13));
dictionary.insert(map<string,int>::value_type("-",14));
dictionary.insert(map<string,int>::value_type("*",15));
dictionary.insert(map<string,int>::value_type("/",16));
dictionary.insert(map<string,int>::value_type(":",17));
dictionary.insert(map<string,int>::value_type(":=",18));
dictionary.insert(map<string,int>::value_type("<",19));
dictionary.insert(map<string,int>::value_type("<>",21));
dictionary.insert(map<string,int>::value_type("<=",22));
dictionary.insert(map<string,int>::value_type(">",23));
dictionary.insert(map<string,int>::value_type(">=",24));
dictionary.insert(map<string,int>::value_type("=",25));
dictionary.insert(map<string,int>::value_type(";",26));
dictionary.insert(map<string,int>::value_type("(",27));
dictionary.insert(map<string,int>::value_type(")",28));
dictionary.insert(map<string,int>::value_type("#",0));
}
int findbykey(string key)
{
map<string,int >::iterator l_it;;
l_it=dictionary.find(key);
if(l_it==dictionary.end())
return -1;
else
return l_it->second;
}
string keyword[6]={"for","if","then","else","while","do"};
bool isletter(char a)
{
if((a>='a'&&a<='z')||(a>='A'&&a<='Z'))
{
return true;
}
else
{
return false;
}
}
bool isdigit(char a)
{
if(a>='0'&&a<='9')
{
return true;
}
else
{
return false;
}
}
bool iskeyw(string keywords)
{
for(int i=0;i<6;i++)
{
if(keyword[i]==keywords)
{
return true;
}
}
return false;
}
bool isvar(string var) //ID=letter(letter | digit)*
{
if(isletter(var[0]))
{
for(int i=0;i<var.length();i++)
{
if(isletter(var[i])||isdigit(var[i]))
{
}
else
{
return false;
}
}
return true;
}
else
{
return false;
}
}
bool isnum(string num) //NUM=digit digit* (xiaoshudian
{
if(isdigit(num[0]))
{
int flag1=1;
int flag2=1;
for(int i=0;i<num.length();i++)
{
if(isdigit(num[i]))
{
}
else if(num[i]=='.'&&isdigit(num[i+1])&&flag1)
{
flag1=0;
}
else if (((num[i]=='E'||num[i]=='e')&&(num[i+1]=='+'||num[i+1]=='-'||isdigit(num[i+1]))&&flag2))
{
flag2=0;
}
else if((num[i]=='+'||num[i]=='-')&&isdigit(num[i+1]))
{
}
else
{
return false;
}
}
return true;
}
else
{
return false;
}
}
string to_String(int n)
{
string temp;
stringstream ss;
ss<<n;
temp = ss.str();
return temp;
}
string packet(string test,int type)
{
int a;
string req="";
string aa;
if(type==0)
{
a=findbykey(test);
aa=to_String(a);
req+="<" + aa;
req+=",";
req+=test;
req+="> ";
}
else if(type==1)
{
a=findbykey("var");
aa=to_String(a);
req+="<" + aa;
req+=",";
req+="var";
req+="> ";
}
else if(type==2)
{
a=findbykey("num");
aa=to_String(a);
req+="<" + aa;
req+=",";
req+="num";
req+="> ";
}
return req;
}
string texthandle(string test,int linenum)
{
if(iskeyw(test))
{
return packet(test,0);
}
else if(isvar(test))
{
return packet(test,1);
}
else if(isnum(test))
{
return packet(test,2);
}
else if(-1==findbykey(test))
{
string b="There are some errors in Line ";
string bb;
bb= to_String(linenum);
b+=bb;
return b;
}
else
{
return packet(test,0);
}
}
list<string> File_output(char* filename)
{
int linenum=0;
string test;
fstream file;
string pice;
string expression="";
list<string> words;
file.open(filename,ios_base::in|ios_base::out) ;
if(!file)
{
cout<<"error"<<endl;
}
else
{
while(getline(file, test))
{
linenum++;
//处理逻辑
/*
划分单词,. 标点
*/
string temp="";
for(int i=0;i<test.length();i++)
{
if( test[i] == ' ' )
{
}
else
{
temp+=test[i];
if(test[i+1]==' '||test[i+1]=='\0')
{
/*words.push_back(temp);
pice=texthandle(temp,linenum);
expression+="\n";*/
// expression+=temp;
words.push_back(temp);
temp="";
}
}
}
}
//对单词链表进行处理
list<string>::iterator i;
for (i = words.begin(); i != words.end(); ++i)
//测试
cout<<*i<<endl;
//cout<<expression<<endl;
}
return words;
}
请大神告诉我:1.如何实现自动构建这种表呢?2.有没有通用的方法