实验五编译用语法制导方式生成中间代码生成器Word格式文档下载.docx

上传人:b****8 文档编号:21964819 上传时间:2023-02-02 格式:DOCX 页数:16 大小:162.58KB
下载 相关 举报
实验五编译用语法制导方式生成中间代码生成器Word格式文档下载.docx_第1页
第1页 / 共16页
实验五编译用语法制导方式生成中间代码生成器Word格式文档下载.docx_第2页
第2页 / 共16页
实验五编译用语法制导方式生成中间代码生成器Word格式文档下载.docx_第3页
第3页 / 共16页
实验五编译用语法制导方式生成中间代码生成器Word格式文档下载.docx_第4页
第4页 / 共16页
实验五编译用语法制导方式生成中间代码生成器Word格式文档下载.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

实验五编译用语法制导方式生成中间代码生成器Word格式文档下载.docx

《实验五编译用语法制导方式生成中间代码生成器Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《实验五编译用语法制导方式生成中间代码生成器Word格式文档下载.docx(16页珍藏版)》请在冰豆网上搜索。

实验五编译用语法制导方式生成中间代码生成器Word格式文档下载.docx

="

>

!

=="

{filloperator(&

yylval,yytext);

return(REL);

}

if{return(IF);

else{return(ELSE);

while{return(WHILE);

do{return(DO);

for{return(FOR);

switch{return(SWITCH);

case{return(CASE);

default{return(DEFAULT);

break{return(BREAK);

true{return(TRUE);

false{return(FALSE);

int{return(INT);

long{return(LONG);

char{return(CHAR);

bool{return(BOOL);

float{return(FLOAT);

double{return(DOUBLE);

&

{return(AND);

||"

{return(OR);

{return('

'

);

++"

{return(INC);

--"

{return(DEC);

+"

+'

);

-"

-'

*"

*'

/"

/'

='

{"

{'

}"

}'

["

['

]"

]'

("

('

)"

)'

;

{ws}{}

{id}{filllexeme(&

return(ID);

{number}{filllexeme(&

return(NUMBER);

{real}{filllexeme(&

return(REAL);

在代码中,先定义正则定义,即对letter,digit,专用符号,空格进行声明;

接着在转换规则中,定义一些识别规则的代码。

完成词法分析后,就可以将获取的每一个词素用于语法分析器使用。

将mylex.l与myyacc.y相结合的方法是在每获得一个词素,则用return语句返回,即如果获得的是if,则return(if),并且在头文件中加入#include"

myYacc.tab.h"

,则在myyacc中定义的类型在mylex中可利用,否则会出现返回的单元未定义的错误。

3.用文本编译器编辑相应的bison文件myyacc.y,myyacc.y文件中,在每个生成式后加上语法制导翻译,主要是依据truelist和falselist来实现回填功能。

编写完后,在myyacc.y中以头文件的方式加入自己编写的myyacc.h文件,编译即可。

Myyacc.y的代码如下所示:

Myyacc.y

myyacc.h"

#defineYYSTYPEnode

intyyerror();

intyyerror(char*msg);

externintyylex();

codelist*list;

%tokenBASICNUMBERREALIDTRUEFALSE

%tokenINTLONGCHARBOOLFLOATDOUBLE

%tokenREL

%tokenIFELSEWHILEDOBREAKFORSWITCHCASEDEFAULT

%tokenORAND

%leftOR

%leftAND

%right'

%left'

'

%rightUMINUS

%rightINCDEC

program:

block{}

;

block:

declsstatementlist'

{}

decls:

declsdecl{}

|{}

decl:

typeID'

{}

type:

type'

NUMBER'

|BASIC{}

statementlist:

statementlistMstatement{backpatch(list,$1.nextlist,$2.instr);

$$.nextlist=$3.nextlist;

|statement{$$.nextlist=$1.nextlist;

;

Statement:

IF'

boolean'

MstatementELSENMstatement{backpatch(list,$3.truelist,$5.instr);

backpatch(list,$3.falselist,$9.instr);

$6.nextlist=merge($6.nextlist,$8.nextlist);

$$.nextlist=merge($6.nextlist,$10.nextlist);

}

|IF'

Mstatement{backpatch(list,$3.truelist,$5.instr);

$$.nextlist=merge($3.falselist,$6.nextlist);

|WHILEM'

Mstatement{backpatch(list,$7.nextlist,$2.instr);

backpatch(list,$4.truelist,$6.instr);

$$.nextlist=$4.falselist;

gen_goto(list,$2.instr);

|DOMstatementMWHILE'

M'

{backpatch(list,$3.nextlist,$4.instr);

backpatch(list,$7.truelist,$9.instr);

$$.nextlist=$7.falselist;

|FOR'

assignment'

Mboolean'

Massignment'

NMstatement{backpatch(list,$6.truelist,$12.instr);

backpatch(list,$11.nextlist,$5.instr);

backpatch(list,$13.nextlist,$8.instr);

$$.nextlist=$6.falselist;

gen_goto(list,$8.instr);

|BREAK'

{}

|'

statementlist'

{$$.nextlist=$2.nextlist;

|assignment'

{$$.nextlist=NULL;

assignment:

ID'

boolean{copyaddr(&

$1,$1.lexeme);

gen_assignment(list,$1,$3);

loc:

loc'

|ID{copyaddr(&

$$,$1.lexeme);

boolean:

booleanORMboolean{backpatch(list,$1.falselist,$3.instr);

$$.truelist=merge($1.truelist,$4.truelist);

$$.falselist=$4.falselist;

|booleanANDMboolean{backpatch(list,$1.truelist,$3.instr);

$$.truelist=$4.truelist;

$$.falselist=merge($1.falselist,$4.falselist);

boolean{$$.truelist=$1.falselist;

$$.falselist=$1.truelist;

{$$.truelist=$1.truelist;

$$.falselist=$1.falselist;

|expressionRELexpression{$$.truelist=new_instrlist(nextinstr(list));

$$.falselist=new_instrlist(nextinstr(list)+1);

gen_if(list,$1,$2.oper,$3);

gen_goto_blank(list);

|TRUE{copyaddr(&

$$,"

TRUE"

|FALSE{copyaddr(&

FALSE"

|expression{copyaddr_fromnode(&

$$,$1);

M:

{$$.instr=nextinstr(list);

N:

{$$.nextlist=new_instrlist(nextinstr(list));

expression:

expression'

expression{new_temp(&

$$,get_temp_index(list));

gen_3addr(list,$$,$1,"

$3);

|expression'

expression%precUMINUS{new_temp(&

gen_2addr(list,$$,"

$2);

|loc{copyaddr_fromnode(&

|NUMBER{copyaddr(&

|REAL{copyaddr(&

intyyerror(char*msg)

{

printf("

\nERRORwithmessage:

%s\n"

msg);

return0;

}

intmain()

list=newcodelist();

freopen("

text.in"

"

rt+"

stdin);

text.out"

wt+"

stdout);

yyparse();

print(list);

fclose(stdin);

fclose(stdout);

在代码中,先定义一些头文件,externintyylex();

externintyyerror();

这两个语句是必须的,引用全局变量是为了能够使用之前词法分析器所获取的词素。

并且调用一个yyerror函数用来当发生错误时能够报告错误。

接着定义一些终结符号,比如说%tokenNUM。

yacc规定每个终结符都有一个唯一的编号(tokennumber)。

当我们用上面的方式定义终结符时,终结符的编号由yacc内部决定,其编号规则是从257开始依次递增,每次加1。

为了能够联合词法分析器和语法分析器,词法分析程序名字必须是yylex,调法分析程序向语法分析程序提供当前输入的单词符号。

yylex提供给yyparse的不是终结符本身,而是终结符的编号,即tokennumber,如果当前的终结符有语义值,yylex必须把它赋给yylval。

接着是翻译规则部分,这个翻译规则由一个文法产生式和一个相关联的语义动作组成,在这里在每个生成式后边加上语法制导翻译以实现回填的功能。

4.另外编写一个头文件myyacc.h将其加入到myyacc.y文件中去

文件如下所示:

Myyacc.h

#ifndefCP_H

#defineCP_H

#include<

stdio.h>

string.h>

malloc.h>

typedefstructlistele

intinstrno;

structlistele*next;

}listele;

listele*new_listele(intno)

{

listele*p=(listele*)malloc(sizeof(listele));

p->

instrno=no;

next=NULL;

returnp;

typedefstructinstrlist

listele*first,*last;

}instrlist;

instrlist*new_instrlist(intinstrno)

instrlist*p=(instrlist*)malloc(sizeof(instrlist));

first=p->

last=new_listele(instrno);

instrlist*merge(instrlist*list1,instrlist*list2)

instrlist*p;

if(list1==NULL)p=list2;

else

{

if(list2!

=NULL)

{

if(list1->

last==NULL)

{

list1->

first=list2->

first;

last=list2->

last;

}elselist1->

last->

next=list2->

list2->

last=NULL;

free(list2);

}

p=list1;

}

typedefstructnode

instrlist*truelist,*falselist,*nextlist;

charaddr[256];

charlexeme[256];

charoper[3];

intinstr;

}node;

intfilloperator(node*dst,char*src)

strcpy(dst->

oper,src);

return0;

intfilllexeme(node*dst,char*yytext)

lexeme,yytext);

intcopyaddr(node*dst,char*src)

addr,src);

intnew_temp(node*dst,intindex)

sprintf(dst->

addr,"

t%d"

index);

intcopyaddr_fromnode(node*dst,nodesrc)

addr,src.addr);

typedefstructcodelist

intlinecnt,capacity;

inttemp_index;

char**code;

}codelist;

codelist*newcodelist()

codelist*p=(codelist*)malloc(sizeof(codelist));

linecnt=0;

capacity=1024;

temp_index=0;

code=(char**)malloc(sizeof(char*)*1024);

intget_temp_index(codelist*dst)

returndst->

temp_index++;

intnextinstr(codelist*dst){returndst->

linecnt;

intGen(codelist*dst,char*str)

if(dst->

linecnt>

=dst->

capacity)

dst->

capacity+=1024;

code=(char**)realloc(dst->

code,sizeof(char*)*dst->

capacity);

if(dst->

code==NULL)

printf("

shortofmemeory\n"

return0;

dst->

code[dst->

linecnt]=(char*)malloc(strlen(str)+20);

linecnt],str);

linecnt++;

chartmp[1024];

intgen_goto_blank(codelist*dst)

sprintf(tmp,"

goto"

Gen(dst,tmp);

intgen_goto(codelist*dst,intinstrno)

goto%d"

instrno);

intgen_if(codelist*dst,nodeleft,char*op,noderight)

if%s%s%sgoto"

left.addr,op,right.addr);

intgen_1addr(codelist*dst,nodeleft,char*op)

%s%s"

left.addr,op);

intgen_2addr(codelist*dst,nodeleft,char*op,noderight)

%s=%s%s"

Gen(dst,tmp

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

当前位置:首页 > 总结汇报 > 学习总结

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

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