根据上下文无关文法(LL(1)文法),构建预测分析程序,完成给出的输入串的自上而下的语法分析,并返回语法分析结果。
给定文法–>消除左递归–>提左因子–>First集;Follow集–>分析表 M[A,a]矩阵–>预测分析程序
LL(1)文法:
G [E]:E→E+T
E→T
T→T*F
T→F
F→(E)|i
经消去直接左递归之后,得到的文法如下:
G[E]: E -> TE’
-> +TE’ | Ɛ
E
T -> FT’
T`->*FT’| Ɛ
F -> (E) | i
消除回溯和提取左因子:消除回溯必须保证对文法的任何非终结符,当要它去匹配输入串时,能够根据它所面临的输入符号准确的指派它的一个候选去执行任务,并且此候选的工作结果应是确信无疑的。提取左因子就是不断的提取公共左因子,把每个非终结符的所有候选首符集变成亮两两不相交。
对于任何(X,a),总控程序每次都执行下述三种可能的动作之一:
(1)若X=a=’#’,则宣布分析成功,停止分析过程;
(2)若X=a!=‘#’,则把X从栈顶逐出,让a指向下一个输入符号;
(3)若X是一个非终结符,则查看分析表M。
LL(1)分析表:
代码:
#include <bits/stdc++.h>
using namespace std;
map<char, map<char,string> > FORECAST_TABLE;
const int maxn = 500 + 50;
void Init_Table(){
FORECAST_TABLE['E']['i'] = "TG";
FORECAST_TABLE['E']['('] = "TG";
FORECAST_TABLE['G']['+'] = "+TG";
FORECAST_TABLE['G'][')'] = "";
FORECAST_TABLE['G']['#'] = "";
FORECAST_TABLE['T']['i'] = "FH";
FORECAST_TABLE['T']['('] = "FH";
FORECAST_TABLE['H']['+'] = "";
FORECAST_TABLE['H']['*'] = "*FH";
FORECAST_TABLE['H']['#'] = "";
FORECAST_TABLE['H'][')'] = "";
FORECAST_TABLE['F']['i'] = "i";
FORECAST_TABLE['F']['('] = "(E)";
}
char tmpSTACK[maxn];
int stackTOP;
bool Anayse(char *str,int len){
int step = 0;
stackTOP = 0;
stack<char> STACK;
while(!STACK.empty()) STACK.pop();
int pos = 0;
char topChar;
STACK.push('#');
STACK.push('E');
tmpSTACK[stackTOP++] = '#';
tmpSTACK[stackTOP++] = 'E';
while(true){
string tmp = "";
topChar = STACK.top();
STACK.pop();
stackTOP--;
if(topChar == 'i' || topChar == '(' || topChar == ')'
|| topChar == '+' || topChar == '*'){
if(topChar == str[pos]){
pos++;
}
else return false;
}
else if(topChar == '#'){
if(topChar == str[pos]) return true;
else return false;
}
else{
if(FORECAST_TABLE[topChar].count(str[pos]) == 0) return false;
else{
tmp = FORECAST_TABLE[topChar][str[pos]];
int len = tmp.length();
for(int i = len - 1;i >= 0;--i) STACK.push(tmp[i]),tmpSTACK[stackTOP++] = tmp[i];
}
}
printf("%d ",step++);
for(int i = 0;i < stackTOP;++i) printf("%c",tmpSTACK[i]);
printf(" ");
for(int i = 0;i <= len;++i) printf("%c",str[i]);
printf(" ");
cout << tmp << endl;
}
}
int main(){
char str[maxn];
scanf("%s",str);
int len = strlen(str);
str[len] = '#';
Init_Table();
bool res = Anayse(str,len);
if(res) printf("YES\n");
else printf("NO\n");
}
运行结果: