IFELSE条件语句翻译程序设计方案LR方法输出元式Word格式文档下载.docx
- 文档编号:22090807
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:28
- 大小:170.10KB
IFELSE条件语句翻译程序设计方案LR方法输出元式Word格式文档下载.docx
《IFELSE条件语句翻译程序设计方案LR方法输出元式Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《IFELSE条件语句翻译程序设计方案LR方法输出元式Word格式文档下载.docx(28页珍藏版)》请在冰豆网上搜索。
=E.false}
T->
CSelse
{q:
=nextstat
Emit(‘GOTO’—)
Backpatch(C.clain,nextstat)
T.clain:
=merge(S.clain,q)}
3语法分析方法描述及语法分析表设计
3.1语法分析方法描述
3.1.1LR方法的基本思想
一个LR分析器实质上是一个带先进后出存储器的确定有限状态自动机。
我们将把“历史”和“展望”材料综合地抽象成某些“状态”。
分析栈用来存放状态。
栈里的每个状态概括了从分析开始直到某一归约阶段的全部“历史”和“展望”资料。
任何时候,栈顶的状态都代表了整个的历史和已推测出的展望。
因此,在任何时候都可从栈顶状态得知所想了解的一切,而绝对没有必要从称底而上翻阅整个栈。
LR分析器的每一步工作都是由栈顶
状态和现行输入符号所唯一决定的。
为了有助于明确归约手续,我们把已归约出
的文法符号串也同时放在栈里。
于是,我们可以把栈的结构看成是:
栈的每一项内容包括状态S和文法符号X两部分。
(S0,#)为分析开始前预先放到栈里的初始状态和句子括号。
栈顶状态为SM,符号串X1X2….XM是至今已移进归约出的部分。
3.1.2LR分析器模型
LR分析器模型如下图:
LR分析器的核心部分是一张分析表。
这张分析表包括两部分,一是“动作”(ACTION)表,另一个是“状态转换表”(GOTO)表。
它们都是二维数组。
ACTION[s,a]规定了当状态s面临输入符号a时应采取什么动作。
GOTO[s,a]规定了状态s面对文法符号X(终结符或非终结符)时下一个状态是什么。
显然GOTO[S,x]定义了一个以文法符号为字母表的DFA。
每一项ACTION[s,a]所规定的动作不外是下述四种可能之一:
1.移进把(S,A)的下一状态S=GOTO[S,A]和输入符号A推进栈,下一输入符号变成现行输入状态。
2.规约指用某一产生式A->
进行规约。
假若的长度为r,归约动作是A,去除栈顶的r个项,使状态Sm-r变成栈顶状态,然后把(Sm-r,A)的下一状态S1=GOTO[Sm-r,A]和文法符号A推进栈。
归约动作不改变现行输入符号。
执行归约动作意味着(=Xm-r+1….Xm)已呈现于栈顶而且是一个相对于A的句柄。
3.接受宣布分析成功,停止分析器的工作。
4.报错发现源程序含有错误,调用出错处理程序。
LR分析器的总控程序本身的工作是非常简单。
它的任何一步只需要按栈顶状态和现行输入符号a执行ACTION[S,a]所规定的动作。
不管什么分析表,总控程序都是一样地工作。
一个LR分析器的工作过程可看成是栈里的状态序列,已归约串和输入串所构成的三元式的变化过程。
分析地的初始三元式(S0,#,a1a2…an#)其中,S0为分析器的初态;
#为句子的左括号;
a1a2…an为输入串;
其后的#为结束符。
分析过程每步的结果可表示为(s0s1…sm,#X1X2…,ai….an#)分析器的下一步动作是由栈顶状态Sm和现行输入符号ai所唯一决定。
即,执行ACTION[Sm,ai]所规定的动作。
经执行每种可能的动作之后,三元式的变化的情形是:
(1)若ACTION[Sm,ai]为移进,且S=GOTO[Sm,ai],则三元式变成:
(S0S1…Sm,#X1X2…Xmaian#)
(2)若ACTION[Sm,ai]={A->
},则按产生式A->
进行归约。
此时三元式变为
(S0S1…Sm-rS,#X1…Xm-rA,aiai+1…an#)
此处S=GOTO[Sm-r,A],r为的长度,=Xm-r+1…Xm。
(3)若ACTION[Sm,ai]为:
接受,则三元式不再变化,变化过程终止,宣布分析成功。
(4)若ACTION[Sm,ai]为“报错”,则三元式的变化过程终止,报告错误。
一个LR分析器的工作过程就是一步一步地变换三元式,直至执行“接受”或“报错”为止。
3.2语法分析表设计
在做语法分析前需建立SLR
(1)语法分析表
ACTION
GOTO
i
t
e
E
#
S
C
T
S5
S4
S1
S2
S3
1
ACC
2
S6
3
S10
4
r3
5
S8
6
S7
r1
7
r5
8
S9
9
r4
10
r2
此表中引用记号的意义是:
(1)Sj把下一状态j和现行输入符号移进栈;
(2)rj按第j个产生式进行规约;
(3)acc接受;
(4)空白格出错标志,报错;
4中间代码形式的描述及中间代码序列的结构设计
4.1中间代码形式的描述
四元式是一种比较普遍采用的中间代码形式。
四元式的四个组成部分是:
操作符OP,第一个和第二个运算对象ARG1和ARG2及运算结果RESULT。
运算对象和运算结果有时指用户自己定义的变量,有时指编译程序引进的临时变量。
例如a:
=b*c+b*d的四元式表示如下:
(1)(*,b,c,t1)
(2)(*,b,d,t2)
(3)(+,t1,t2,t3)
(4)(:
=,t3,-,a)
4.2中间代码序列的结构设计
IfEthenA1elseA2
100(关于E的布尔表达式)
101(goto,-,-,104)
102(关于A1的赋值表达式)
103(goto,-,-,105)
104(关于A2的赋值表达式)
105exit
5编译系统的概要设计
本课程设计需要写一个条件语句的LR文法及其属性文法,运用LR分析方法对此文法进行语法和语义分析,中间代码采用四元式输出。
在这个条件语句的翻译分析程序设计中,主要通过以下四个过程来完成:
1.词法分析。
由于编译程序是在单词的级别上来分析和翻译源程序的,那么在这里,词法分析的任务是:
从左至右逐个字符地对源程序进行扫描,产生一个一个的单词符号,把作为字符串的源程序改造成为单词符号串的中间程序。
所以词法分析是编译的基础。
在此程序中是将词法分析作为一遍处理的,通过一次分析把全部的字符串都分析完成,并将其保存在数组中便于下一步进行语法分析。
2.语法分析。
在完成词法分析的基础上对条件语句进行语法分析,在这里我采用了自下而上分析法SLR
(1)分析方法,来分析判定程序的语法结构是否符合语法规则,在分析前首先要构造SLR
(1)分析表,然后在进行语法分析,在此程序中,以‘;
’为结束符号来判断一条条的条件语句,并且独立的对每条语句进行语法分析。
并把算法中的移近、规约操作
3.语义分析、输出四元式。
在进行语法分析的同时进行语义分析,在此次设计中式将二者结合起来作为一遍进行处理的。
在进行语义时同时生成中间语言四元式。
4.出错处理。
如果在词法分析时遇到非法字符就会输出出错信息,同时输出从出错点开始往后的一串字符,但是它仍然能跳过该非法字符继续分析;
如果在语法分析中有错误的话,就会显示在DOS环境下输出“ERROR”,但是它能跳过出错的地方继续往后执行,分析出一部分结果并保存在文件中。
6详细的算法描述
6.1系统流程图
6.2算法描述
本程序中,选用C++程序设计语言的部分常用的单词作为词法分析的对象,词法分析后,将识别的所有单词符号以及相关信息保存在数组中,以便后面语法分析和语意分析及中间代码生成使用,同时将识别出的单词符号输出到文件中,并分类别地存储到相应的数组中一便进行查看。
采用SLR
(1)分析法,生成状态表,然后根据栈的移近、移出生成分析过程表。
在经过语法、语义分析之后,生成中间代码四元式,同时进行出错管理。
voidinitGrammar()。
//初始化产生式表
boolisJchar(charc)//检测是否为分界符
intword()//进行词法分析,并存到fenxi.txt文件中
wnode*lexcial(wnode*head)//把词法分析得来的词分类别放到表达式数组
intcheck(ints,charv)。
//查LR分析表
voidgammarAnalysis(wnode*head)。
//语法分析及进行相应的语义操作并产生四元式
voidshowS(intopS[],inttops,charopC[],inttopc,wnode*hp)。
//显示分析栈的内
源程序代码:
#include<
iostream>
#include<
fstream>
math.h>
string>
iomanip>
usingnamespacestd。
charFilename[100]。
structwnode
{
charid。
intn。
//编号
chartext[20]。
wnode*next。
}。
structGnode//存储产生式
stringgen。
intid。
Gnodegrammar[6]。
wnode*lexcial(wnode*head)。
//显示分析栈的内容
//用于if-else分析
intLR[11][9]={
//________ACTION_________|___GOTO___
//iteAE#SCT
{105,0,0,104,0,0,101,102,103},//0
{0,0,0,0,0,-1,0,0,0},//1
{105,0,0,104,0,0,106,102,103},//2
{105,0,0,104,0,0,110,102,103},//3
{0,0,3,0,0,3,0,0,0},//4
{0,0,0,0,108,0,0,0,0},//5
{0,0,107,0,0,1,0,0,0},//6
{5,0,0,5,0,0,0,0,0},//7
{0,109,0,0,0,0,0,0,0},//8
{4,0,0,4,0,0,0,0,0},//9
{0,0,2,0,0,2,0,0,0}//10
voidinitGrammar()
grammar[0].gen="
S'
->
S"
。
grammar[0].id=0。
grammar[1].gen="
CS"
grammar[1].id=1。
grammar[2].gen="
TS"
grammar[2].id=2。
grammar[3].gen="
A"
grammar[3].id=3。
grammar[4].gen="
ifEthen"
grammar[4].id=4。
grammar[5].gen="
CSelse"
grammar[5].id=5。
cout<
<
"
所用文法:
endl。
inti,j。
for(i=1。
i<
6。
i++)
cout<
grammar[i].id-1<
'
\t'
grammar[i].gen<
5"
else"
注:
i--ift--thene--else"
E——布尔表达式(在语法分析中看成是终结符)"
A——赋值语句(在语法分析中看成是终结符)"
SLR
(1)分析表:
setw(22)<
ACTION"
setw(18)<
|"
setw(10)<
GOTO"
setw(8)<
i"
setw(6)<
t"
e"
E"
<
#"
C"
T"
for(i=0。
11。
{
setw
(2)<
i。
for(j=0。
j<
9。
j++)
{
if(LR[i][j]>
=110)
cout<
setw(4)<
LR[i][j]-100。
elseif(LR[i][j]>
100)
setw(5)<
0)
r"
LR[i][j]。
elseif(LR[i][j]==0)
"
ACC"
}
}
}
boolr=false。
switch(c)
case'
'
:
\n'
r=true。
break。
default:
returnr。
intword()
charch='
intnum=0。
ifstreamsource("
source.txt"
)。
ofstreamfenxi("
fenxi.txt"
charyunsuanfu[11]={'
+'
'
-'
*'
/'
>
='
!
%'
&
|'
charjiefu[9]={'
('
)'
{'
}'
['
]'
#'
char*guanjianzi[20]={"
int"
"
if"
then"
do"
while"
break"
continue"
switch"
return"
when"
for"
double"
main"
include"
short"
long"
float"
char"
}。
char*biaoshifu[100]={"
\0"
/////////////////////////////////
while(!
source.eof())
source.get(ch)。
charshuzi[20]="
inti=1。
if(ch>
0'
ch<
9'
)//判断数字
shuzi[0]=ch。
source.get(ch)。
while(((ch>
)||ch=='
.'
)&
{
ch。
shuzi[i++]=ch。
source.get(ch)。
}
fenxi<
shuzi<
数字"
=10。
i++)//运算符判断
if(ch==yunsuanfu[i])
fenxi<
运算符"
}
i++)//界符
if(ch==jiefu[i])
界符"
}
}
a'
z'
)//关键字判断
{
charstr1[20]。
intsign=0。
intn=0。
)||(ch>
_'
{
str1[n]=ch。
n++。
str1[n]='
\0'
20。
if(!
strcmp(str1,guanjianzi[i]))
str1<
关键字"
sign=1。
if(sign==0)
标识符"
{
}
}
}
}
fenxi.close()。
source.close()。
return0。
wnode*lexcial(wnode*head)
stringstr。
intloc=-1。
charc。
inti,k=0,mark=0。
intAcount=0,Ecount=0。
wnode*p,*q。
p=head。
q=newwnode。
q->
text[0]='
n=0。
next=NULL。
fstreaminfile(Filename)。
//根据输入的路径名来打开这个文件
while(infile.get(c))
if(isJchar(c))
if(mark==1)
q->
text[k]='
q->
text[i]!
if(q->
text[i]=='
)
loc=i。
if(p->
id=='
i'
{q->
id='
E'
n=++Ecount。
elseif(loc!
=-1)
A'
n=++Acount。
q->
id=q->
text[0]。
head->
n++。
p->
next=q。
p=q。
mark=0。
}else
if(mark==0)
q=newwnode。
loc=-1。
k=0。
mark=1。
text[k++]=c。
//在末尾加上一个'
p->
returnhead。
//语法分析
voidgammarAnalysis(wnode*head)
charE[20]。
charA[20]。
charr,d1,d2。
inttn=0,en=head->
n。
ofstreamtable。
table.open("
siyuanshi.txt"
table)
Cannotopenoutputfile!
exit
(1)。
语法分析过程:
分析栈输入串操作"
intopS[20]。
//记录状态,状态栈
charopC[20]。
//记录符号,符号栈
intmark=-1,i,count=0。
intloc=99。
//指示程序指令地址
wnode*p。
p=head->
next。
inttops=0。
inttopc=0。
opS[tops]=0。
opC[topc]='
while(p)
showS(opS,tops
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- IFELSE 条件 语句 翻译 程序设计 方案 LR 方法 输出