【实验目的】
掌握算符优先分析法的原理,利用算符优先分析法将赋值语句进行语法分析。
【实验内容】
(1)输入一个文法根据算符优先分析法,将表达式进行语法分析,判断一个表达式是否为算符优先文法
(2)输入一个句子进行分析
【实验要求】
1、根据文法求FIRSTVT集和LASTVT集
给定一个上下文无关文法,根据算法设计一个程序,求文法中每个非终结符的FirstVT 集和LastVT 集。
可参考算法描述如下:
/*求 FirstVT 集的算法*/
PROCEDURE insert(P,a);
IF not F[P,a] then
begin
F[P,a] = true; //(P,a)进栈
end;
Procedure FirstVT;
Begin
for 对每个非终结符 P和终结符 a do
F[P,a] = false
for 对每个形如 P a…或 P→Qa…的产生式 do
Insert(P,a)
while stack 非空
begin
栈顶项出栈,记为(Q,a)
for 对每条形如 P→Q…的产生式 do
insert(P,a)
end;
end.
同理,可构造计算LASTVT的算法。
2、构造算符优先分析表
依据文法和求出的相应FirstVT和 LastVT 集生成算符优先分析表。
参考算法描述如下:
for 每个形如 P->X1X2…Xn的产生式 do
for i =1 to n-1 do
begin
if Xi和Xi+1都是终结符 then
Xi = Xi+1
if i<= n-2, Xi和Xi+2 是终结符, 但Xi+1 为非终结符 then
Xi = Xi+2
if Xi为终结符, Xi+1为非终结符 then
for FirstVT 中的每个元素 a do
Xi < a ;
if Xi为非终结符, Xi+1为终结符 then
for LastVT 中的每个元素 a do
a > Xi+1 ;
end
3、构造控制程序
参考 算法描述如下:
stack S;
k = 1; //符号栈S的使用深度
S[k] = ‘#’
REPEAT
把下一个输入符号读进a中;
If S[k] VT then j = k else j = k-1;
While S[j] > a do
Begin
Repeat
Q = S[j];
if S[j-1] VT then j = j-1 else j = j-2
until S[j] < Q;
把S[j+1]…S[k]归约为某个N,并输出归约为哪个符号;
K = j+1;
S[k] = N;
end of while
if S[j] < a or S[j] = a then
begin k = k+1; S[k] = a end
else error //调用出错诊察程序
until a = ‘#’
4、对给定的表达式,给出准确与否的分析过程
5、给出表达式的计算结果。
【实验结果】
图为参考,要求包含firstvt和lastvt集,算符优先表或优先函数表及句子分析过程。
实验截图:
代码:
1 Mian.cpp: 2 #include <stdio.h> 3 #include <math.h> 4 #include <string.h> 5 #include <stdlib.h> 6 #include <iostream> 7 #include <sstream> 8 #include <algorithm> 9 #include <set> 10 #include <queue> 11 #include <stack> 12 #include <map> 13 #include <bitset> 14 #pragma comment(linker, "/STACK:102400000,102400000") 15 typedef long long LL; 16 const int inf = 0x3f3f3f3f; 17 const double pi = acos(-1.0); 18 const double esp = 1e-6; 19 using namespace std; 20 21 const int Maxn = 110; 22 const int maxn = 20; 23 char str[maxn][Maxn];//输入文法 24 char st[maxn];//输入串 25 char stac[maxn];//模拟栈的数组 26 char nstr[maxn][maxn];//储存转化文法 27 char mstr[maxn][maxn]; 28 char fin[maxn];//存储终结符 29 char firstvt[maxn][maxn], lastvt[maxn][maxn]; 30 char cmp[maxn][maxn];//存储表中的比较符 31 int firstflag[maxn], lastflag[maxn];//非终结符的firstvt,lastvt是否求出 32 int fcnt[maxn], lcnt[maxn];//非终结符firsvt和lastvt的个数 33 int is_fin(char c) { //判断终结符 34 for (int i = 0; fin[i] != '