语法分析器设计Word文档下载推荐.docx
《语法分析器设计Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《语法分析器设计Word文档下载推荐.docx(18页珍藏版)》请在冰豆网上搜索。
![语法分析器设计Word文档下载推荐.docx](https://file1.bdocx.com/fileroot1/2023-1/11/d503fd1e-51f3-40a4-bc04-daea81e3682e/d503fd1e-51f3-40a4-bc04-daea81e3682e1.gif)
S
A
B
C
D
E
F
G
H
I
J
K
L
M
}
;
#
2
1
8
3
Ac
-3
4
5
-4
6
7
-5
-2
10
9
-1
25
11
13
15
12
-6
14
-8
-7
16
17
20
-12
19
18
-15
-9
21
22
-13
23
24
-14
-11
1.2.2程序核心代码和注释:
publicvoidanalyzer()
{
//***************************
//循环读取grammar.txt
//***************************
/*此处代码略*/
//循环读取lengh.txt
/*此处代码略*/
//****************************
//读入文件,进行语法分析
stringstrReadFile;
strReadFile="
input.txt"
myTextRead.myStreamReader=newStreamReader(strReadFile);
stringstrBufferText;
intwid=0;
Console.WriteLine("
分析读入程序(记号ID):
\n"
);
do
{
strBufferText=myTextRead.myStreamReader.ReadLine();
if(strBufferText==null)
break;
foreach(StringsubStringinstrBufferText.Split())
{
if(subString!
="
"
)
{
intll;
if(subString!
=null)
{
ll=subString.Length;
//每一个长度
}
else
break;
inta=ll+1;
char[]b=newchar[a];
StringReadersr=newStringReader(subString);
sr.Read(b,0,ll);
//把substring读到char[]数组里
intsort=(int)b[0];
//word[i]和wordNum[i]对应
//先识别出一整个串,再根据开头识别是数字还是字母
Word[wid]=subString;
if(subString.Equals("
void"
))
{wordNum[wid]=0;
else
if(subString.Equals("
main"
{wordNum[wid]=1;
else
{
if(subString.Equals("
()"
{wordNum[wid]=2;
else
{
if(subString.Equals("
{"
{wordNum[wid]=3;
else
{
if(subString.Equals("
int"
{wordNum[wid]=4;
else
{
if(subString.Equals("
{wordNum[wid]=6;
else
{
if(subString.Equals("
}"
{wordNum[wid]=22;
else
{
if(subString.Equals("
{wordNum[wid]=23;
else//识别变量和数字
{
if(sort>
47&
sort<
58)
{wordNum[wid]=7;
else
{wordNum[wid]=5;
}
}
}
}
}
}
}
Console.Write(subString+"
("
+wordNum[wid]+"
)"
+"
"
wid++;
}
}
Console.WriteLine("
}while(strBufferText!
=null);
wordNum[wid]=24;
myTextRead.myStreamReader.Close();
//*********************************
//读入LR分析表
//
//***********************************
int[]state=newint[100];
string[]symbol=newstring[100];
state[0]=0;
symbol[0]="
#"
intp1=0;
intp2=0;
\n按文法规则归约顺序如下:
//***************
//归约算法如下所显示
while(true)
{
intj,k;
j=state[p2];
k=wordNum[p1];
t=LR[j,k];
//当出现t为0的时候
if(t==0)
//错误类型
stringerror;
if(k==0)
error="
else
if(k==1)
if(k==2)
if(k==3)
if(k==4)
if(k==6)
if(k==22)
if(k==23)
其他错误符号"
Console.WriteLine("
\n检测结果:
代码中存在语法错误"
错误状况:
错误状态编号为"
+j+"
读头下符号为"
+error);
else
if(t==-100)//-100为达到接受状态
Console.WriteLine("
代码通过语法检测"
break;
if(t<
0&
&
t!
=-100)//归约
stringm=grammar[-t];
Console.Write(m+"
//输出开始符
intlength=lengh[-t];
p2=p2-(length-1);
SearchmySearch=newSearch();
intright=mySearch.search(m);
if(right==0)
Console.WriteLine("
代码中有语法错误"
inta=state[p2-1];
intLRresult=LR[a,right];
state[p2]=LRresult;
symbol[p2]=m;
if(t>
0)
p2=p2+1;
state[p2]=t;
symbol[p2]=Convert.ToString(wordNum[p1]);
p1=p1+1;
}
Console.Read();
}
示例:
voidmain()
inti=8;
intaa=10;
intj=9;
intqi=8;
对于intqi=8中intq这个错误类型,词法分析通过,而语法分析正确识别出了错误,达到预期目标
产生出错信息:
运行显示如下:
1.3中间代码生成器设计
进入编译程序的第三阶段:
中间代码产生阶段。
为了使编译程序有较高的目标程序质量,或要求从编译程序逻辑结构上把与机器无关和与机器有关的工作明显的分开来时,许多编译程序都采用了某种复杂性介于源程序语言和机器语言之间的中间语言。
常用的几种中间语言有:
逆波兰式、四元式、三元式、树表示。
本课程设计主要实现逆波兰式的生成。
1.3.1逆波兰式的定义和设计思想及算法
1、逆波兰式定义:
将运算对象写在前面,而把运算符号写在后面。
用这种表示法表示的表达式也称做后缀式。
逆波兰式的特点在于运算对象顺序不变,运算符号位置反映运算顺序。
采用逆波兰式可以很好的表示简单算术表达式,其优点在于易于计算机处理表达式。
2、生成逆波兰式的设计思想及算法
(1)首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。
(2)读入一个用中缀表示的简单算术表达式,为方便起见,设该简单算术表达式的右端多加上了优先级最低的特殊符号“#”。
(3)从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符是数字,则分析到该数字串的结束并将该数字串直接输出。
(4)如果不是数字,该字符则是运算符,此时需比较优先关系。
做法如下:
将该字符与运算符栈顶的运算符的优先关系相比较。
如果该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。
倘若不是的话,则将此运算符栈顶的运算符从栈中弹出,将该字符入栈。
(5)重复上述操作
(1)-
(2)直至扫描完整个简单算术表达式,确定所有字符都得到正确处理,我们便可以将中缀式表示的简单算术表达式转化为逆波兰表示的简单算术表达式。
1.3.2核心代码及其结果显示
#include<
stdio.h>
math.h>
#definemax100
charex[max];
voidtrans()
charstr[max];
charstack[max];
charch;
intsum,j,t,top=0;
inti=0;
/*计数器*/
printf("
*****************************************\n"
*说明:
以#号为结束标志.\n"
******************************************\n"
表达示:
do
{
i++;
scanf("
%c"
&
str[i]);
/*注:
str[0]没有数据*/
if(i>
=max)printf("
表达式长度过长!
}while(str[i]!
='
#'
&
i!
=max);
sum=i;
/*数组长度,即表达式长度*/
t=1;
i=1;
ch=str[i];
i++;
while(ch!
switch(ch)
{
case'
('
:
top++;
stack[top]=ch;
break;
)'
while(stack[top]!
{
ex[t]=stack[top];
top--;
t++;
top--;
+'
-'
while(top!
=0&
stack[top]!
top++;
*'
/'
while(stack[top]=='
||stack[top]=='
'
break;
default:
while(ch>
0'
ch<
9'
ex[t]=ch;
ch=str[i];
i++;
i--;
ex[t]='
'
t++;
ch=str[i];
}
=0)
if(stack[top]!
ex[t]=stack[top];
t++;
top--;
}
else
printf("
error"
exit(0);
ex[t]='
\n原表达式是:
for(j=1;
j<
sum;
j++)
printf("
str[j]);
\n后缀表达式是:
t;
ex[j]);
voidcompvalue()
{
floatstack[max],d;
intt=1,top=0;
ch=ex[t];
t++;
{
stack[top-1]=stack[top-1]+stack[top];
/*根据运算符,进行四则运算*/
stack[top-1]=stack[top-1]-stack[top];
stack[top-1]=stack[top-1]*stack[top];
if(stack[top]!
stack[top-1]=stack[top-1]/stack[top];
printf("
\n\tchu0error!
exit(0);
d=0;
/*判断是否为数字,是则将数字字符转化为对应的数值,并入栈*/
while(ch>
d=10*d+ch-'
ch=ex[t];
stack[top]=d;
ch=ex[t];
t++;
\n计