Problem Description
预测分析法是自顶向下分析的一种方法,一个预测分析程序是由三个部分组成:
(1) 预测分析程序
(2) 先进后出栈
(3) 预测分析表
现给出表达式文法:
E→TG
G→+TG | ε
T→FS
S→*FS | ε
F→(E) | i
该表达式文法是LL(1)文法,其预测分析表为:
请根据该预测分析表构造预测分析程序,完成对表达式的语法分析,对给定的输入串,判断其是否为合法表达式,给出所使用的产生式序列。
Input
给定输入串(长度不超过50个符号,以#号结束,符号保证是终结符或#)。
例如:
i+i*i# 是合法表达式
i+i*(i+i)# 是合法表达式
ii+i*i# 不是合法表达式
i*(i+i# 不是一个合法的表达式。
Output
要求输出分析过程中使用的所有产生式,产生式按使用顺序各占一行,每行有两个数据,使用顺序号(从1开始编号)及产生式本身,中间用一个空格分开,最后一行表示语法分析是否成功结束,如果成功分析结束输出acc!,表示该输入串是合法表达式,否者输出error!,表示该输入串不是合法表达式。
注:其中^符号代表文法中的ε符号。
针对输入串i+i*i#,因为分析过程使用了11次产生式,且该输入串是合法表达式,输出如下:
1 E->TG
2 T->FS
3 F->i
4 S->^
5 G->+TG
6 T->FS
7 F->i
8 S->*FS
9 F->i
10 S->^
11 G->^
acc!
针对输入串i*(i+i#,因为分析过程使用了14次产生式后,发现语法错误,该输入串不是合法表达式,输出如下:
1 E->TG
2 T->FS
3 F->i
4 S->*FS
5 F->(E)
6 E->TG
7 T->FS
8 F->i
9 S->^
10 G->+TG
11 T->FS
12 F->i
13 S->^
14 G->^
error!
Sample Input
i+i*i#
Sample Output
1 E->TG
2 T->FS
3 F->i
4 S->^
5 G->+TG
6 T->FS
7 F->i
8 S->*FS
9 F->i
10 S->^
11 G->^
acc!
code:
#include <stdio.h>
#include <string>
#include <iostream>
#include <algorithm>
#include <stack>
using namespace std;
int num;
stack<char> A;
stack<char> B;
int opration(char x, char y)
{
if(x == 'E'&&(y == 'i'||y == '('))
{
printf("%d E->TG\n", num);
A.pop();
A.push('G');
A.push('T');
num++;
return 1;
}
else if(x == 'G'&&y=='+')
{
printf("%d G->+TG\n", num);
A.pop();
A.push('G');
A.push('T');
A.push('+');
num++;
return 1;
}
else if(x == 'G'&&(y == ')'||y == '#'))
{
printf("%d G->^\n", num);
A.pop();
num++;
return 1;
}
else if(x == 'T'&&(y == 'i'||y == '('))
{
printf("%d T->FS\n", num);
A.pop();
A.push('S');
A.push('F');
num++;
return 1;
}
else if(x == 'S'&&y == '*')
{
printf("%d S->*FS\n", num);
A.pop();
A.push('S');
A.push('F');
A.push('*');
num++;
return 1;
}
else if(x =='S' && (y ==')' || y == '#'||y=='+'))
{
printf("%d S->^\n", num);
A.pop();
num++;
return 1;
}
else if(x == 'F' && y == 'i')
{
printf("%d F->i\n", num);
A.pop();
A.push('i');
num++;
return 1;
}
else if(x == 'F' && y == '(')
{
printf("%d F->(E)\n", num);
A.pop();
A.push(')');
A.push('E');
A.push('(');
num++;
return 1;
}
else
{
if(x == y)
{
A.pop();
B.pop();
return 1;
}
else
{
return 0;
}
}
}
void Init()
{
num = 1;
while(!A.empty())
{
A.pop();
}
A.push('#');
A.push('E');
while(!B.empty())
{
B.pop();
}
}
int main()
{
string str;
cin>>str;
Init();
int len = str.length();
for(int i = len-1; i>=0; i--)
{
B.push(str[i]);
}
while(1)
{
if(A.top() == '#'&&B.top() == '#')
{
printf("acc!\n");
break;
}
else
{
int flag = opration(A.top(), B.top());
if(flag == 0)
{
printf("error!\n");
break;
}
}
}
return 0;
}
本文深入探讨预测分析法,一种自顶向下的语法分析方法,详细解释了预测分析程序、先进后出栈和预测分析表的概念,并通过具体实例展示了如何利用预测分析法进行表达式语法分析,判断输入串是否为合法表达式。
707

被折叠的 条评论
为什么被折叠?



