END:
;
}
return0;
}
2.4程序运行截图
2.5小结
在程序中要跳出多层语句只能用goto语句实现。
用枚举类型表示各个终结符与非终结符,再用关联容器生成预测分析表即可方便地实现此算法。
3算符优先分析
3.1算符优先文法
E→T|E+T|E-T(注:
该文法为示例,可更改)
T→F|T*F|T/F
F→(E)|i
3.2算符优先关系表
+
-
*
/
(
)
i
#
+
>
>
<
<
<
>
<
>
-
>
>
<
<
<
>
<
>
*
>
>
>
>
<
>
<
>
/
>
>
>
>
<
>
<
>
(
<
<
<
<
<
=
<
)
>
>
>
>
>
>
i
>
>
>
>
>
>
#
<
<
<
<
<
<
=
3.3分析程序代码
#include
#include
#include
#include
usingnamespacestd;
enumSymbols{
//终结符号
TS_PLUS,//+
TS_MINUS,//-
TS_MULTIPLY,//*
TS_DIVISION,///
TS_L_PARENS,//(
TS_R_PARENS,//)
TS_I,//i
TS_EOS,//#,'\0'
TS_INVALID,//非法字符
};
map>table;
enumSymbolslexer(charc)
{
switch(c)
{
case'+':
returnTS_PLUS;
case'-':
returnTS_MINUS;
case'*':
returnTS_MULTIPLY;
case'/':
returnTS_DIVISION;
case'(':
returnTS_L_PARENS;
case')':
returnTS_R_PARENS;
case'i':
returnTS_I;
case'#':
returnTS_EOS;//栈底:
#终结符号
default:
returnTS_INVALID;
}
}
//初始化算符优先关系表,0、1、2分别表示=、〈、〉,-1表示不存在
voidsetup()
{
table[TS_PLUS][TS_PLUS]=2;
table[TS_PLUS][TS_MINUS]=2;
table[TS_PLUS][TS_MULTIPLY]=1;
table[TS_PLUS][TS_DIVISION]=1;
table[TS_PLUS][TS_L_PARENS]=1;
table[TS_PLUS][TS_R_PARENS]=2;
table[TS_PLUS][TS_I]=1;
table[TS_PLUS][TS_EOS]=2;
table[TS_MINUS][TS_PLUS]=2;
table[TS_MINUS][TS_MINUS]=2;
table[TS_MINUS][TS_MULTIPLY]=1;
table[TS_MINUS][TS_DIVISION]=1;
table[TS_MINUS][TS_L_PARENS]=1;
table[TS_MINUS][TS_R_PARENS]=2;
table[TS_MINUS][TS_I]=1;
table[TS_MINUS][TS_EOS]=2;
table[TS_MULTIPLY][TS_PLUS]=2;
table[TS_MULTIPLY][TS_MINUS]=2;
table[TS_MULTIPLY][TS_MULTIPLY]=2;
table[TS_MULTIPLY][TS_DIVISION]=2;
table[TS_MULTIPLY][TS_L_PARENS]=1;
table[TS_MULTIPLY][TS_R_PARENS]=2;
table[TS_MULTIPLY][TS_I]=1;
table[TS_MULTIPLY][TS_EOS]=2;
table[TS_DIVISION][TS_PLUS]=2;
table[TS_DIVISION][TS_MINUS]=2;
table[TS_DIVISION][TS_MULTIPLY]=2;
table[TS_DIVISION][TS_DIVISION]=2;
table[TS_DIVISION][TS_L_PARENS]=1;
table[TS_DIVISION][TS_R_PARENS]=2;
table[TS_DIVISION][TS_I]=1;
table[TS_DIVISION][TS_EOS]=2;
table[TS_L_PARENS][TS_PLUS]=1;
table[TS_L_PARENS][TS_MINUS]=1;
table[TS_L_PARENS][TS_MULTIPLY]=1;
table[TS_L_PARENS][TS_DIVISION]=1;
table[TS_L_PARENS][TS_L_PARENS]=1;
table[TS_L_PARENS][TS_R_PARENS]=0;
table[TS_L_PARENS][TS_I]=1;
table[TS_L_PARENS][TS_EOS]=-1;
table[TS_R_PARENS][TS_PLUS]=2;
table[TS_R_PARENS][TS_MINUS]=2;
table[TS_R_PARENS][TS_MULTIPLY]=2;
table[TS_R_PARENS][TS_DIVISION]=2;
table[TS_R_PARENS][TS_L_PARENS]=-1;
table[TS_R_PARENS][TS_R_PARENS]=2;
table[TS_R_PARENS][TS_I]=-1;
table[TS_R_PARENS][TS_EOS]=2;
table[TS_I][TS_PLUS]=2;
table[TS_I][TS_MINUS]=2;
table[TS_I][TS_MULTIPLY]=2;
table[TS_I][TS_DIVISION]=2;
table[TS_I][TS_L_PARENS]=-1;
table[TS_I][TS_R_PARENS]=2;
table[TS_I][TS_I]=-1;
table[TS_I][TS_EOS]=2;
table[TS_EOS][TS_PLUS]=1;
table[TS_EOS][TS_MINUS]=1;
table[TS_EOS][TS_MULTIPLY]=1;
table[TS_EOS][TS_DIVISION]=1;
table[TS_EOS][TS_L_PARENS]=1;
table[TS_EOS][TS_R_PARENS]=-1;
table[TS_EOS][TS_I]=1;
table[TS_EOS][TS_EOS]=0;
}
intmain()
{
setup();//初始化优先关系表
while
(1)
{
cout<<"输入一个以#结束的符号串"<constchar*p;
stringstr;
cin>>str;
p=str.c_str();
stackss;
ss.push(TS_EOS);
while
(1)
{
if(lexer(*p)==TS_INVALID)//读取到不在集合中的非法字符
{
cout<<"×不是给定算符优先文法的句子"<break;
}
if(ss.top()==TS_EOS&&lexer(*p)==TS_EOS)//成功规约
{
cout<<"√是给定算符优先文法的句子"<break;
}
else
{
if(table[ss.top()][lexer(*p)]==1||table[ss.top()][lexer(*p)]==0)
{
//继续读入字符,暂不规约
ss.push(lexer(*p));
++p;
}
elseif(table[ss.top()][lexer(*p)]==2)//符合规约要求,开始规约
{
enumSymbolstemp;
while
(1)
{
temp=ss.top();
ss.pop();
if(table[ss.top()][temp]==1)
break;
}
}
else//语法错误
{
cout<<"×不是给定算符优先文法的句子"<break;
}
}
}
}
return0;
}
3.4程序运行截图
3.5小结
此方法初始化优先关系法显得有点繁琐,有待改进。
4LR分析
4.1LR文法
(0)S'→S(注:
该文法为示例,可更改)
(1)S→BB
(2)B→aB
(3)B→b
4.2LR分析表
ACTION
GOTO
a
b
#
S
B
0
S3
S4
1
2
1
acc
2
S3
S4
5
3
S3
S4
6
4
r3
r3
r3
5
r1
r1
r1
6
r2
r2
r2
4.3分析程序代码
#include
#include
#include
#include
usingnamespacestd;
enumSymbols{
//终结符号
TS_A,//A
TS_B,//B
TS_EOS,//#,'\0'
TS_INVALID,//非法字符
//非终结符号
NTS_SS,//S'
NTS_S,//S
NTS_B,//B
//状态status
S_0,
S_1,
S_2,
S_3,
S_4,
S_5,
S_6,
S_ACC,
//GOGO
G_S,
G_B,
//规约式
R_1,
R_2,
R_3,
};
enumSymbolslexer(charc)
{
switch(c)
{
case'a':
returnTS_A;
case'b':
returnTS_B;
case'#':
returnTS_EOS;//栈底:
#终结符号
default:
returnTS_INVALID;
}
}
map>table;
intmain()
{
while
(1)
{
cout<<"输入一个以#结束的字符串"<constchar*p;
stringstr;
cin>>str;
p=str.c_str();
stackstatus;
//设置LR分析表
table[S_0][TS_A]=S_3;
table[S_0][TS_B]=S_4;
table[S_0][NTS_S]=S_1;
table[S_0][NTS_B]=S_2;
table[S_1][TS_EOS]=S_ACC;
table[S_2][TS_A]=S_3;
table[S_2][TS_B]=S_4;
table[S_2][NTS_B]=S_5;
table[S_3][TS_A]=S_3;
table[S_3][TS_B]=S_4;
table[S_3][NTS_B]=S_6;
table[S_4][TS_A]=R_3;
table[S_4][TS_B]=R_3;