本程序只是针对LL(1)文法,对于左递归和含有回溯的文法没有进行处理。本程序主要包括以下功能:
对于读取的文法存在文法类(grammar)中,具体结构见下:
//定义文法类,保存文法个数和记录所有文法
class Grammar{
public:
//保存所有文法
list grammarTable[N][N];
//保存终结字符
char terminalChar[N];
//保存终结字符的个数
int terNum;
//保存每行的产生式的个数
int countEachRow[N];
//定义文法数量
int count;
Grammar(){
terNum = 0;
}
};
对每一文法符号X∈VT∪VN构造FIRST(X),连续使用下面的规则,直至每个集合FIRST
不再增大为止:
1. 若X∈VT,则FIRST(X)={X}。
2. 若X∈VN,且有产生式X→a…,则把a加入到FIRST(X)中;若X→e也是一条产生式,
则把e也加到FIRST(X)中。
3.若X→Y…是一个产生式且Y∈VN,则把FIRST(Y)中的所有非e-元素都加到FIRST(X)中;
4.若X→Y1Y2…Yk是一个产生式,Y1,…,Yi-1都是非终结符,而且,对于任何j,1≤j≤i-1,FIRST(Yj)都含有e(即Y1…Yi-1e), 则把FIRST(Yi)中的所有非e-元素都加到FIRST(X)中;特别是,若所有的FIRST(Yj)均含有e,j=1,2,…,k,则把e加到FIRST(X)中。
具体实现算法如下:
具体代码实现如下:
//保存每个非终结符的FIRST集合
class FIRST{
public:
//保存每个非终结符的FIRST集合
set First[N];
//保存非终结符
char nonTerminal[N];
//保存是否计算出相应的FIRST集
bool flag[N] ={0};
//保存已计算FIRST集的个数
int calCount ;
FIRST(){
calCount =0;
}
};
//计算FIRST集
void calFIRSTSet(){
while(reloadCalCount() != grammar.count){
//扫描每一个产生式
for(int i=0;i::iterator it = grammar.grammarTable[i][j].begin();
//获取产生式的首字符
it++;
//如果it没有到边界并且是非终结字符并且并且已经计算FIRST集并且FIRST含有空字
while(it != grammar.grammarTable[i][j].end() && isNonTerminal(*it) &&
first.flag[getNonTerminalIndex(*it)] && hasEmpty(getNonTerminalIndex(*it))){
first.nonTerminal[i] = grammar.grammarTable[i][0].front();
calSetUnion(i,getNonTerminalIndex(*it));
it++;
}
//如果it到边界,说明每个非终结符的FIRST集都已经计算出来,并且都含有空字
if(it == grammar.grammarTable[i][j].end()){
//把空字加入
first.First[i].insert('@');
first.flag[i] = true;
continue;
}
//否则,it没有到边界
else{
//如果*it为终结符
if(isTerminal(*it)){
first.nonTerminal[i] = grammar.grammarTable[i][0].front();
first.flag[i] = true;
//把终结字符保存到FIRST集
first.First[i].insert(*it);
}
//如果是非终结符
else if(isNonTerminal(*it)){
//如果已经计算过FIRST集,则把FIrst集加入
if(first.flag[getNonTerminalIndex(*it)]){
first.nonTerminal[i] = grammar.grammarTable[i][0].front();
first.flag[i] = true;
calSetUnion(i,getNonTerminalIndex(*it));
}
//没有计算过
else{
first.flag[i] = false;
}
}
//如果是空字
else{
first.nonTerminal[i] = grammar.grammarTable[i][0].front();
first.flag[i] = true;
//把终结字符保存到FIRST集
first.First[i].insert(*it);
}
}
}
}
//如果计算FIRST集
else{
continue;
}
}
}
}
对于文法G的每个非终结符A构造FOLLOW(A)的办法是,连续使用下面的规则,直至每个FOLLOW不再增大为止:
1. 对于文法的开始符号S,置#于FOLLOW(S)中;
2. 若A→aBb是一个产生式,则把FIRST(b)\{e}加至FOLLOW(B)中;
3. 若A→aB是一个产生式,或A→aBβ是一个产生式,而b *推导出e (即e∈FIRST(b)),则把FOLLOW(A)加至FOLLOW(B)中。
具体实现算法如下:
具体代码实现如下:
//保存每个非终结符的FOLLOW集合
class FOLLOW{
public:
//保存每个非终结符的FOLLOW集合
set Follow[N];
//保存非终结符
char nonTerminal[N];
//保存是否计算出相应的FOLLOW集
bool flag[N] ={0};
//保存已计算Follow集的个数
int calCount ;
//保存产生式的索引
vector position[N];
FOLLOW(){
calCount =0;
}
};
//计算FOLLOW集
void calFOLLOWSet(){
//对于开始符号S,需将"#"加入其FOLLOW集
follow.Follow[0].insert('#');
while(reloadFOLLOWCalCount()!= grammar.count){
//扫描每个产生式
for(int i=0;i::iterator it = follow.position[i].begin();
for(it ;it!= follow.position[i].end();it++){
int m = (*it).x;
int n = (*it).y ;
list::iterator itp = grammar.grammarTable[m][n].begin();
//使其指向首字符
itp++;
for(itp;itp!=grammar.grammarTable[m][n].end();itp++){
if((int)(*itp) == (int)grammar.grammarTable[i][0].front()){
itp++;
break;
}
}
//itp不指向结尾,并且是非终结符并FIRST集含有空字,则继续检测while(itp != grammar.grammarTable[m][n].end() && isNonTerminal(*itp) && hasEmpty(getNonTerminalIndex(*itp))){
int index = getNonTerminalIndex(*itp);
follow.nonTerminal[i] = grammar.grammarTable[i][0].front();
//将非终结符去空字的FIRST集加入FOLLOW集
calFollowAndFirstUnion(i,index);
itp++;
}
//如果itp没有指向end指针,说明该字符为终结字符或非终结字符或空字
if(itp != grammar.grammarTable[m][n].end()){
if(isTerminal(*itp)){
follow.nonTerminal[i] = grammar.grammarTable[i][0].front();
//将非终结字符加入FOLLOW集
follow.Follow[i].insert(*itp);
//标记已经计算该非终结符的FOLLOW集
follow.flag[i] = true;
}
else if(isNonTerminal(*itp)){
int index = getNonTerminalIndex(*itp);
follow.nonTerminal[i] = grammar.grammarTable[i][0].front();
//将非终结符去空字的FIRST集加入FOLLOW集
calFollowAndFirstUnion(i,index);
//标记已经计算该非终结符的FOLLOW集
follow.flag[i] = true;
}
//空字什么也不做
else{
}
}
//itp指向end指针
else{
if(!follow.flag[m]){
//如果没有计算则标记false
follow.flag[i] = false;
}
else{
follow.nonTerminal[i] = grammar.grammarTable[i][0].front();
calFollowAndFollowUnion(i,m);
//标记已经计算该非终结符的FOLLOW集
follow.flag[i] = true;
}
}
}
}
}
}
}
①对文法G的每个产生式A→a执行第2步和第3步。
② 对每个终结符a∈FIRST(a),把A→a加至M[A,a]。
③若e∈FIRST(a),则对任何b∈FOLLOW(A)把A→a加至M[A,b]中,若e ∉ FIRST(a),则对任何b∈FOLLOW(A)把” synch”加至M[A,b]中,以便出错处理;
具体实现代码如下:
//构建预测分析表
void bulidAnalyseTable(){
bool flag = false;
//遍历每个非终结符
for(int i=0;i firstSet = buildFirstForOne(i,j);
set::iterator it = firstSet.begin();
for(it;it != firstSet.end();it++){
//如果FIRST集存在空字,记上标记
if(isEmpty(*it)){
flag = true;
}
//否则将相应的产生式加入预测分析表
else{
//将文法字符转为字符串
string str =charToString(i,j);
analyseTable[i][getTerminalIndex(*it)] = str;
}
}
//产生式的FIRST集中含有空字
if(flag){
//获取i为索引的非终结字符的FOLLOW集
set::iterator it = follow.Follow[i].begin();
for(it;it != follow.Follow[i].end();it++){
if(isTerminal(*it)){
analyseTable[i][getTerminalIndex(*it)] = (string)"@";
}
}
}
//产生式的FIRST集中不含有空字
else{
//获取i为索引的非终结字符的FOLLOW集
set::iterator it = follow.Follow[i].begin();
for(it;it != follow.Follow[i].end();it++){
analyseTable[i][getTerminalIndex(*it)]=(string)"synch";
}
}
}
}
}
BEGIN
首先把’#’然后把文法开始符号推进STACK栈;
把第一个输入符号读进a;
FLAG := TRUE;
WHILE FLAG DO
BEGIN
把STACK栈顶符号上托出去并放在X中;
IF X∈VT THEN
IF X =a THEN 把下个输入符号读进a;
ELSE ERROR;
ELSE IF X = ‘#’ THEN
IF X = a THEN FLAG:= FALSE;
ELSE ERROR;
ELSE IF M[A,a] ={X->X1X2…XK} THEN
把XK,XK-1,…,X1一一推进STACK栈
/* 若X1X2…XK = e */
ELSE ERROR;
END OF WHILE
STOP
END
由于篇幅有限代码不在贴出。
分析时,若发现M[A,a]为空则跳过输入符号a;若该项为“synch”,则弹出栈顶非终结符(开始符号除外);若栈顶的终结符号不匹配输入符号,则弹出栈顶的终结符。
#ifndef _grammar_
#define _grammar_
#include
#include
#include
#define N 50
using namespace std;
//定义文法类,保存文法个数和记录所有文法
class Grammar{
public:
//保存所有文法
list grammarTable[N][N];
//保存终结字符
char terminalChar[N];
//保存终结字符的个数
int terNum;
//保存每行的产生式的个数
int countEachRow[N];
//定义文法数量
int count;
Grammar(){
terNum = 0;
}
};
//保存每个非终结符的FIRST集合
class FIRST{
public:
//保存每个非终结符的FIRST集合
set First[N];
//保存非终结符
char nonTerminal[N];
//保存是否计算出相应的FIRST集
bool flag[N] ={0};
//保存已计算FIRST集的个数
int calCount ;
FIRST(){
calCount =0;
}
};
class Position{
public:
int x;
int y;
Position(){
x=-1;
y=-1;
}
};
//保存每个非终结符的FOLLOW集合
class FOLLOW{
public:
//保存每个非终结符的FOLLOW集合
set Follow[N];
//保存非终结符
char nonTerminal[N];
//保存是否计算出相应的FOLLOW集
bool flag[N] ={0};
//保存已计算Follow集的个数
int calCount ;
//保存产生式的索引
vector position[N];
FOLLOW(){
calCount =0;
}
};
#endif // _grammar_
#include
#include
#include
#include
#include
#include
#include
#include "grammar.h"
using namespace std;
//定义一个文法类对象
Grammar grammar;
//定义FIRST集
FIRST first;
//定义·FOLLOW集
FOLLOW follow;
//定义预测分析表
string analyseTable[N][N] ;
//检测一个字符是否为非终结字符
bool isNonTerminal(char var);
//检测一个字符是否为空字
bool isEmpty(char var);
//检测一个字符是否为终结字符
bool isTerminal(char var);
//从控制台读取文法并保存
void readGrammar();
//判断一个产生式是否能求出FIRST集,能返回true,否则false
bool canCalFIRST(int i);
//计算能够计算FIRST集的产生式
void calFIRST();
//获取其非终结字符所在的索引
int getNonTerminalIndex(char var);
//检测第i个FIRST集是否有空字
bool hasEmpty(int i);
//判断是否能计算FIRST集(首字符含非终结符)
bool adjustFIRST(int i);
//计算两个集合的并集,即set(i) = set(i) ∪ set(j)
void calSetUnion(int i,int j);
//更新calCount
int reloadCalCount();
//计算FIRST集
void calFIRSTSet();
//输出first集
void printFIRST();
//获取索引(每一个非终结符在产生式的索引,索引保存在容器中)
void getPosition();
//将FIRST集去空加入FOLLOW集,i代表FOLLOW,i代表FIRST集
void calFollowAndFirstUnion(int i,int j);
//计算两个FOLLOW集的并集,即set(i) = set(i) ∪ set(j)
void calFollowAndFollowUnion(int i,int j);
//更新FOLLOW集的calCount
int reloadFOLLOWCalCount();
//计算FOLLOW集
void calFOLLOWSet();
//获取每一个非终结符的FOLLOW集
void getFollowSet();
//打印FOLLOW集
void printFOLLOW();
//获取终结符在Grammar.terminal[]中的索引
int getTerminalIndex(char var);
//构建单个产生式的First集,i,j为相应产生式的索引
set buildFirstForOne(int i,int j);
//将产生式字符转为字符串,i,j为相应产生式的索引
string charToString(int i,int j);
//构建预测分析表
void bulidAnalyseTable();
//打印预测分析表
void printAnalyseTable();
//将vector中的字符转化为字符串
string veToString(vector &vec);
//将字符数组有选择的转化为字符串
string toString(char buf[],int start,int end);
//核心函数,对语法进行分析
void analyseGrammar();
/*
E->TG
G->+TG|@
T->FH
H->*FH|@
F->(E)|i
*/
/*
E->TG
G->+TG|-TG|@
T->FSj
S->*FS|/FS|@
F->(E)|i|@
*/
int main()
{
readGrammar();
calFIRSTSet();
printFIRST();
getFollowSet();
printFOLLOW();
bulidAnalyseTable();
printAnalyseTable();
analyseGrammar();
return 0;
}
//从控制台读取文法并保存
void readGrammar(){
//保存输入的第i行文法
string str;
//把第i行文法转换为字符数组
char buf[100] ={0};
int i=0;
int index = 0;
int count=0;
//临时保存非终结字符
set ter;
cout << "请输入文法(单行输入#回车结束,空字用@代替):" << endl;
cin>>str;
strcpy(buf,str.c_str());
while(str != "#"){
i=0;
count = 0;
grammar.grammarTable[index][count].push_back(buf[i]);
//略去"->"
i+=3;
//检测是否到边界
while((int)buf[i] != 0){
//如果检测到"|"
if((int)buf[i] == 124){
count++;
i++;
//保存起始字符
grammar.grammarTable[index][count].push_back(buf[0]);
//保存产生式的每个字符
grammar.grammarTable[index][count].push_back(buf[i]);
//如果是终结字符则保存
if(isTerminal(buf[i])){
ter.insert(buf[i]);
}
i++;
}
else{
//保存产生式的每个字符
grammar.grammarTable[index][count].push_back(buf[i]);
//如果是终结字符则保存
if(isTerminal(buf[i])){
ter.insert(buf[i]);
}
i++;
}
}
grammar.countEachRow[index] = count+1;
index++;
cin>>str;
strcpy(buf,str.c_str());
}
//保留文法个数
grammar.count = index ;
//保存终结字符
set::iterator it = ter.begin();
for(it;it != ter.end();it++){
grammar.terminalChar[grammar.terNum] = *it;
grammar.terNum++;
}
//注意需要把特殊符号"#",加入
grammar.terminalChar[grammar.terNum] = '#';
grammar.terNum++;
}
//检测一个字符是否为终结字符,注意空字@也不算终结字符
bool isTerminal(char var){
if((!isNonTerminal(var))&&(!isEmpty(var))){
return true;
}
else{
return false;
}
}
//检测一个字符是否为非终结字符
bool isNonTerminal(char var){
if(((int)var > 64)&&((int)var < 91)){
return true;
}
else{
return false;
}
}
//检测一个字符是否为空字
bool isEmpty(char var){
if((int)var == 64){
return true;
}
else{
return false;
}
}
//获取其非终结字符所在的索引
int getNonTerminalIndex(char var){
int index=0;
//获取其终结字符所在的索引
for(index;index::iterator it = first.First[i].begin();
for(it;it!=first.First[i].end();it++){
if((int) *it == 64){
return true;
}
}
return false;
}
//计算两个集合的并集,即set(i) = set(i) ∪ set(j),其中set(j)中去除空字
void calSetUnion(int i,int j){
set::iterator it = first.First[j].begin();
//如果有空字,则去空字
if(hasEmpty(j)){
for(it;it!=first.First[j].end();it++){
if(!isEmpty(*it)){
first.First[i].insert(*it);
}
}
}
else{
for(it;it!=first.First[j].end();it++){
first.First[i].insert(*it);
}
}
}
//更新calCount
int reloadCalCount(){
int count =0;
for(int i=0;i::iterator it = grammar.grammarTable[i][j].begin();
//获取产生式的首字符
it++;
//如果it没有到边界并且是非终结字符并且并且已经计算FIRST集并且FIRST含有空字
while(it != grammar.grammarTable[i][j].end() && isNonTerminal(*it) && first.flag[getNonTerminalIndex(*it)] && hasEmpty(getNonTerminalIndex(*it))){
first.nonTerminal[i] = grammar.grammarTable[i][0].front();
// first.flag[i] = true;
calSetUnion(i,getNonTerminalIndex(*it));
it++;
}
//如果it到边界,说明每个非终结符的FIRST集都已经计算出来,并且都含有空字
if(it == grammar.grammarTable[i][j].end()){
//把空字加入
first.First[i].insert('@');
first.flag[i] = true;
continue;
}
//否则,it没有到边界
else{
//如果*it为终结符
if(isTerminal(*it)){
first.nonTerminal[i] = grammar.grammarTable[i][0].front();
first.flag[i] = true;
//把终结字符保存到FIRST集
first.First[i].insert(*it);
}
//如果是非终结符
else if(isNonTerminal(*it)){
//如果已经计算过FIRST集,则把FIrst集加入
if(first.flag[getNonTerminalIndex(*it)]){
first.nonTerminal[i] = grammar.grammarTable[i][0].front();
first.flag[i] = true;
calSetUnion(i,getNonTerminalIndex(*it));
}
//没有计算过
else{
first.flag[i] = false;
}
}
//如果是空字
else{
first.nonTerminal[i] = grammar.grammarTable[i][0].front();
first.flag[i] = true;
//把终结字符保存到FIRST集
first.First[i].insert(*it);
}
}
}
}
//如果计算FIRST集
else{
continue;
}
}
}
}
//输出first集
void printFIRST(){
cout<<"FIRST集如下:"<::iterator it;
for(it = first.First[i].begin();it!=first.First[i].end();it++){
cout<<*it<<" "; } cout<::iterator it = grammar.grammarTable[i][0].begin();
for(int j=0;j::iterator itp = grammar.grammarTable[j][k].begin();
itp++;
for(itp;itp!=grammar.grammarTable[j][k].end();itp++){
if((int)*it == (int) *itp){
Position pos;
pos.x = j;
pos.y = k;
//记下其位置
follow.position[i].push_back(pos);
}
}
}
}
}
//test
// for(int i=0;i::iterator it = follow.position[i].begin();
// for(it;it!=follow.position[i].end();it++){
// cout<<"("<<(*it).x<<","<<(*it).y<<")";
// }
// cout<::iterator it = first.First[j].begin();
//如果有空字,则去空字
if(hasEmpty(j)){
for(it;it!=first.First[j].end();it++){
if(!isEmpty(*it)){
follow.Follow[i].insert(*it);
}
}
}
else{
for(it;it!=first.First[j].end();it++){
follow.Follow[i].insert(*it);
}
}
}
//更新FOLLOW集的calCount
int reloadFOLLOWCalCount(){
int count =0;
for(int i=0;i::iterator it = follow.Follow[j].begin();
for(it;it!=follow.Follow[j].end();it++){
follow.Follow[i].insert(*it);
}
}
//计算FOLLOW集
void calFOLLOWSet(){
//对于开始符号S,需将"#"加入其FOLLOW集
follow.Follow[0].insert('#');
while(reloadFOLLOWCalCount()!= grammar.count){
for(int i=0;i::iterator it = follow.position[i].begin();
for(it ;it!= follow.position[i].end();it++){
int m = (*it).x;
int n = (*it).y ;
list::iterator itp = grammar.grammarTable[m][n].begin();
//使其指向首字符
itp++;
for(itp;itp!=grammar.grammarTable[m][n].end();itp++){
if((int)(*itp) == (int)grammar.grammarTable[i][0].front()){
itp++;
break;
}
}
//itp不指向结尾,并且是非终结符并FIRST集含有空字,则继续检测
while(itp != grammar.grammarTable[m][n].end() && isNonTerminal(*itp) && hasEmpty(getNonTerminalIndex(*itp))){
int index = getNonTerminalIndex(*itp);
follow.nonTerminal[i] = grammar.grammarTable[i][0].front();
//将非终结符去空字的FIRST集加入FOLLOW集
calFollowAndFirstUnion(i,index);
itp++;
}
//如果itp没有指向end指针,说明该字符为终结字符或非终结字符或空字
if(itp != grammar.grammarTable[m][n].end()){
if(isTerminal(*itp)){
follow.nonTerminal[i] = grammar.grammarTable[i][0].front();
//将非终结字符加入FOLLOW集
follow.Follow[i].insert(*itp);
//标记已经计算该非终结符的FOLLOW集
follow.flag[i] = true;
}
else if(isNonTerminal(*itp)){
int index = getNonTerminalIndex(*itp);
follow.nonTerminal[i] = grammar.grammarTable[i][0].front();
//将非终结符去空字的FIRST集加入FOLLOW集
calFollowAndFirstUnion(i,index);
//标记已经计算该非终结符的FOLLOW集
follow.flag[i] = true;
}
//空字什么也不做
else{
}
}
//itp指向end指针
else{
if(!follow.flag[m]){
//如果没有计算则标记false
follow.flag[i] = false;
}
else{
follow.nonTerminal[i] = grammar.grammarTable[i][0].front();
calFollowAndFollowUnion(i,m);
//标记已经计算该非终结符的FOLLOW集
follow.flag[i] = true;
}
}
}
}
}
}
}
//获取每一个非终结符的FOLLOW集
void getFollowSet(){
getPosition();
calFOLLOWSet();
}
//打印FOLLOW集
void printFOLLOW(){
cout<<"FOLLOW集如下:"<::iterator it;
for(it = follow.Follow[i].begin();it!=follow.Follow[i].end();it++){
cout<<*it<<" "; } cout< buildFirstForOne(int i,int j){
//定义集合
set temp;
list::iterator it = grammar.grammarTable[i][j].begin();
it++;
for(it;it != grammar.grammarTable[i][j].end();it++){
//如果没有出界,并且是非终结字符,并且FIRST集含有空字
while(it != grammar.grammarTable[i][j].end() && isNonTerminal(*it) && hasEmpty(getNonTerminalIndex(*it))){
int index = getNonTerminalIndex(*it);
set::iterator itp = first.First[index].begin();
for(itp;itp!=first.First[index].end();itp++){
//如果不是空字则添加temp集合
if(!isEmpty(*itp)){
temp.insert(*itp);
}
}
it++;
}
//没有出界
if(it != grammar.grammarTable[i][j].end()){
//如果是终结字符或空字,则把终结字符填到FIRST集
if(isTerminal(*it) || isEmpty(*it)){
temp.insert(*it);
return temp;
}
//否则为非终结符
else {
int index = getNonTerminalIndex(*it);
set::iterator itpt = first.First[index].begin();
for(itpt;itpt!=first.First[index].end();itpt++){
temp.insert(*itpt);
}
return temp;
}
}
//如果出界,则退出
else{
//说明都是非终结字符,且都含有空字
temp.insert('@');
return temp;
}
}
}
//将产生式字符转为字符串,i,j为相应产生式的索引
string charToString(int i,int j){
char buf[100] ={0};
int count = 0;
list::iterator it = grammar.grammarTable[i][j].begin();
it++;
for(it;it!=grammar.grammarTable[i][j].end();it++){
buf[count] =*it;
count++;
}
buf[count] = '\0';
string str(buf);
return str;
}
//构建预测分析表
void bulidAnalyseTable(){
bool flag = false;
//遍历每个非终结符
for(int i=0;i firstSet = buildFirstForOne(i,j);
set::iterator it = firstSet.begin();
for(it;it != firstSet.end();it++){
//如果FIRST集存在空字,记上标记
if(isEmpty(*it)){
flag = true;
}
//否则将相应的产生式加入预测分析表
else{
//将文法字符转为字符串
string str =charToString(i,j);
analyseTable[i][getTerminalIndex(*it)] = str;
}
}
//产生式的FIRST集中含有空字
if(flag){
//获取i为索引的非终结字符的FOLLOW集
set::iterator it = follow.Follow[i].begin();
for(it;it != follow.Follow[i].end();it++){
if(isTerminal(*it)){
analyseTable[i][getTerminalIndex(*it)] = (string)"@";
}
}
}
//产生式的FIRST集中不含有空字
else{
//获取i为索引的非终结字符的FOLLOW集
set::iterator it = follow.Follow[i].begin();
for(it;it != follow.Follow[i].end();it++){
analyseTable[i][getTerminalIndex(*it)]=(string)"synch";
}
}
}
}
}
//打印预测分析表
void printAnalyseTable(){
cout<<"预测分析表如下:"< &vec){
char buf[N] ={0};
int index = 0;
vector::iterator it = vec.begin();
for(it;it!=vec.end();it++){
buf[index] = *it;
index++;
}
buf[index] ='\0';
string str(buf);
return str;
}
//将字符数组有选择的转化为字符串
string toString(char buf[],int start,int end){
char temp[N];
int index = 0;
for(start;start <= end;start++){
temp[index] = buf[start];
index++;
}
temp[index] = '\0';
string str(temp);
return str;
}
//核心函数,对语法进行分析
void analyseGrammar(){
cout<<"请输入待分析的字符串:";
string str;
cin>>str;
//将输入的字符串转化为字符数组
char buf[N] ={0};
strcpy(buf,str.c_str());
//计算字符的数目
int count =0;
for(int i=0;buf[i]!=0;i++){
count++;
}
buf[count++] = '#';
cout< analyseStack;
//把'#'和文法开始符号入栈
analyseStack.push('#');
analyseStack.push(grammar.grammarTable[0][0].front());
vector vec;
vec.push_back('#');
vec.push_back(grammar.grammarTable[0][0].front());
//把第一个字符读入a中
char a = buf[0];
//记录步骤
int step = 0;
cout<=0;i--){
analyseStack.push(temp[i]);
vec.push_back(temp[i]);
}
step++;
cout<"+(string)"@"<
测试文法为:E->TG
G->+TG|@
T->FH
H->*FH|@
F->(E)|i
注:’@’代表空字。
运行结果如下:
对不正确的输入串处理的截图如下: