完整word版IFELSE条件语句的翻译程序设计LR方法输出四元式.docx

上传人:b****5 文档编号:5856120 上传时间:2023-01-01 格式:DOCX 页数:25 大小:168.13KB
下载 相关 举报
完整word版IFELSE条件语句的翻译程序设计LR方法输出四元式.docx_第1页
第1页 / 共25页
完整word版IFELSE条件语句的翻译程序设计LR方法输出四元式.docx_第2页
第2页 / 共25页
完整word版IFELSE条件语句的翻译程序设计LR方法输出四元式.docx_第3页
第3页 / 共25页
完整word版IFELSE条件语句的翻译程序设计LR方法输出四元式.docx_第4页
第4页 / 共25页
完整word版IFELSE条件语句的翻译程序设计LR方法输出四元式.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

完整word版IFELSE条件语句的翻译程序设计LR方法输出四元式.docx

《完整word版IFELSE条件语句的翻译程序设计LR方法输出四元式.docx》由会员分享,可在线阅读,更多相关《完整word版IFELSE条件语句的翻译程序设计LR方法输出四元式.docx(25页珍藏版)》请在冰豆网上搜索。

完整word版IFELSE条件语句的翻译程序设计LR方法输出四元式.docx

完整word版IFELSE条件语句的翻译程序设计LR方法输出四元式

10本科生课程设计成绩评定表……………………………………………………………………………………………….22

IF-ELSE条件语句的翻译程序设计

(LR方法、输出四元式)

1系统描述(问题域描述)

对条件语句:

if〈布尔表达式〉then〈赋值语句〉else〈赋值语句〉,进行词法,LR

(1)语法分析,并根据语法制导翻译方法将条件语句翻译成四元式中间代码形式,最后输出翻译后的四元式代码。

2文法及属性文法的描述

2.1文法

G[S]:

S->CS

S->TS

S->A

C->ifEthen

T->CSelse

T->else

其中,E代表布尔表达式,可由界符()括起来,A代表赋值表达式。

在这里E、A都代表终结符,具体的表达式在程序会判断其类型。

2.2属性文法

S->CS

{S.clain:

=merge(C.clain,S.clain)}

S->TS

{S.clain:

=merge(T.clain,S.clain)}

S->A

{S.clain:

0/*空链*/}

C->ifEthen

{backpatch(E.true,nextstat)C.clain:

=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

A

E

#

S

C

T

0

S5

S4

S1

S2

S3

1

ACC

2

S5

S4

S6

S2

S3

3

S5

S4

S10

S2

S3

4

r3

r3

5

S8

6

S7

r1

7

r5

r5

8

S9

9

r4

r4

10

r2

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

#include

#include

#include

#include

#include

usingnamespacestd;

charFilename[100];

structwnode

{

charid;

intn;//编号

chartext[20];

wnode*next;

};

structGnode//存储产生式

{

stringgen;

intid;

};

Gnodegrammar[6];

voidinitGrammar();//初始化产生式表

wnode*lexcial(wnode*head);

intcheck(ints,charv);//查LR分析表

voidgammarAnalysis(wnode*head);//语法分析及进行相应的语义操作并产生四元式

voidshowS(intopS[],inttops,charopC[],inttopc,wnode*hp);//显示分析栈的内容

//用于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="S->CS";

grammar[1].id=1;

grammar[2].gen="S->TS";

grammar[2].id=2;

grammar[3].gen="S->A";

grammar[3].id=3;

grammar[4].gen="C->ifEthen";

grammar[4].id=4;

grammar[5].gen="T->CSelse";

grammar[5].id=5;

cout<<"所用文法:

"<

inti,j;

for(i=1;i<6;i++)

cout<

cout<<"5"<<'\t'<<"T->else"<

cout<<"注:

i--ift--thene--else"<

cout<<"E——布尔表达式(在语法分析中看成是终结符)"<

cout<<"A——赋值语句(在语法分析中看成是终结符)"<

cout<<"SLR

(1)分析表:

"<

cout<

cout<

<

for(i=0;i<11;i++)

{

cout<

(2)<

for(j=0;j<9;j++)

{

if(LR[i][j]>=110)

cout<

elseif(LR[i][j]>100)

cout<

elseif(LR[i][j]>0)

cout<

elseif(LR[i][j]==0)

cout<

else

cout<

}

cout<

}

}

boolisJchar(charc)//检测是否为分界符

{

boolr=false;

switch(c)

{

case'':

case'\n':

case';':

r=true;break;

default:

;

}

returnr;

}

intword()

{

charch='';

intnum=0;

ifstreamsource("source.txt");

ofstreamfenxi("fenxi.txt");

charyunsuanfu[11]={'+','-','*','/','<','>','=','!

','%','&','|'};

charjiefu[9]={',',';','(',')','{','}','[',']','#'};

char*guanjianzi[20]={"int","if","else","then","do","while","break","continue","switch","return","when","for","double","main","break","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>='0'&&ch<='9')||ch=='.')&&!

source.eof())

{

cout<

shuzi[i++]=ch;

source.get(ch);

}

fenxi<

}

for(i=0;i<=10;i++)//运算符判断

{

if(ch==yunsuanfu[i])

{

fenxi<

}

}

for(i=0;i<9;i++)//界符

{

if(ch==jiefu[i])

{

fenxi<

}

}

if(ch>='a'&&ch<='z')//关键字判断

{

charstr1[20];

intsign=0;

intn=0;

while(((ch>='a'&&ch<='z')||(ch>='0'&&ch<='9')||ch=='_')&&!

source.eof())

{

str1[n]=ch;

source.get(ch);

n++;

}

str1[n]='\0';

for(i=0;i<20;i++)

{

if(!

strcmp(str1,guanjianzi[i]))

{

fenxi<

sign=1;

}

}

if(sign==0)

{

fenxi<

}

for(i=0;i<=10;i++)//运算符判断

{

if(ch==yunsuanfu[i])

{

fenxi<

}

}

for(i=0;i<9;i++)//界符

{

if(ch==jiefu[i])

{

fenxi<

}

}

}

}

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]='\0';

q->n=0;

q->next=NULL;

fstreaminfile(Filename);//根据输入的路径名来打开这个文件

while(infile.get(c))

{

if(isJchar(c))

{

if(mark==1)

{

q->text[k]='\0';

for(i=0;q->text[i]!

='\0';i++)

if(q->text[i]=='=')

loc=i;

if(p->id=='i')

{q->id='E';q->n=++Ecount;}

elseif(loc!

=-1)

{q->id='A';q->n=++Acount;}

else

{

q->id=q->text[0];

if(q->id=='i')

head->n++;

}

p->next=q;

p=q;

mark=0;

}

}else

{

if(mark==0)

{

q=newwnode;

q->n=0;

q->next=NULL;

loc=-1;

k=0;

mark=1;

}

q->text[k++]=c;

}

}

//在末尾加上一个'#'

q=newwnode;

q->next=NULL;

q->id='#';

q->text[0]='\0';

q->n=0;

p->next=q;

returnhead;

}

//语法分析

voidgammarAnalysis(wnode*head)

{

charE[20];

charA[20];

charr,d1,d2;

inttn=0,en=head->n;

ofstreamtable;

table.open("siyuanshi.txt");

if(!

table)

{

cout<<"Cannotopenoutputfile!

"<

exit

(1);

}

cout<<"语法分析过程:

"<

cout<<"分析栈输入串操作"<

intopS[20];//记录状态,状态栈

charopC[20];//记录符号,符号栈

intmark=-1,i,count=0;

intloc=99;//指示程序指令地址

charc;

wnode*p;

p=head->next;

inttops=0;

inttopc=0;

opS[tops]=0;

opC[topc]='#';

while(p)

{

showS(opS,tops,opC,topc,p);

if(tops

c=opC[tops+1];

else

{

c=p->id;

if(c=='E')

{

for(i=0;i<20&&p->text[i]!

='\0';i++)

E[i]=p->text

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1