编译原理实验报告Word文档下载推荐.docx

上传人:b****6 文档编号:20006210 上传时间:2023-01-14 格式:DOCX 页数:11 大小:70.70KB
下载 相关 举报
编译原理实验报告Word文档下载推荐.docx_第1页
第1页 / 共11页
编译原理实验报告Word文档下载推荐.docx_第2页
第2页 / 共11页
编译原理实验报告Word文档下载推荐.docx_第3页
第3页 / 共11页
编译原理实验报告Word文档下载推荐.docx_第4页
第4页 / 共11页
编译原理实验报告Word文档下载推荐.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

编译原理实验报告Word文档下载推荐.docx

《编译原理实验报告Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告Word文档下载推荐.docx(11页珍藏版)》请在冰豆网上搜索。

编译原理实验报告Word文档下载推荐.docx

,||,!

==,

print,while,if,else,{,}false,true

各种单词对应的记号如下:

/**/不返回记号

"

while"

WHILE

if"

IF

else"

ELSE

print"

PRINT

false"

INTEGER

true"

INTEGER

[a-z]VARIABLE

[0-9]+INTEGER

-()<

=+*/%;

{}返回本身

="

GE

<

LE

=="

EQ

!

NE

"

AND

||"

OR

NOT

[\t\n]+不返回记号

3.实验基本思想

首先是对输入的程序扫描,进行词法分析,并返回记号。

在c语言头文件中定义了一个结构体,用来存放记号的类型和值(如果有的话)。

在语法分析中,规定了优先级和结合性。

根据输入语句的类型而进行不同的操作。

4.源代码

1.Lex词法分析代码:

%{

#include<

stdlib.h>

#include"

node.h"

myparser.h"

voidyyerror(char*);

%}

%%

/*"

([^\*]|(\*)*[^\*/])*(\*)*"

*/"

;

//注释

{returnWHILE;

}

{returnIF;

{returnELSE;

{returnPRINT;

{yylval.iValue=0;

returnINTEGER;

}

{yylval.iValue=1;

}

[a-z]{yylval.sIndex=*yytext-'

a'

;

returnVARIABLE;

[0-9]+{yylval.iValue=atoi(yytext);

[-()<

{}.]{return*yytext;

{returnGE;

{returnLE;

{returnEQ;

{returnNE;

{returnAND;

{returnOR;

{returnNOT;

[\t\n]+;

/*去除空格,回车*/

.printf("

unknowsymbol:

[%s]\n"

yytext);

intyywrap(void)

{

return1;

2.Yacc语法分析源代码:

%{

#include<

stdio.h>

stdarg.h>

#include"

/*属性操作类型*/

Node*opr(intname,intnum,...);

Node*set_index(intvalue);

Node*set_content(intvalue);

voidfreeNode(Node*p);

intexeNode(Node*p);

intyylexeNode(void);

voidyyerror(char*s);

intVar[26];

/*变量数组*/

%union{

intiValue;

/*变量值*/

charsIndex;

/*变量数组索引*/

Node*nPtr;

/*结点地址*/

%token<

iValue>

VARIABLE

sIndex>

INTEGER

%tokenWHILEIFPRINT

%nonassocIFX

%nonassocELSE

%leftANDORGELEEQNE'

'

'

%rightNOT

%left'

+'

-'

*'

/'

%'

%nonassocUMINUS//不具有结合性

%type<

nPtr>

stmtexprstmt_list

program:

function{exit(0);

}

;

function:

functionstmt{exeNode($2);

freeNode($2);

|/*NULL*/

stmt:

'

{$$=opr('

2,NULL,NULL);

|expr'

{$$=$1;

|PRINTexpr'

{$$=opr(PRINT,1,$2);

|VARIABLE'

='

expr'

{$$=opr('

2,set_index($1),$3);

|WHILE'

('

)'

stmt{$$=opr(WHILE,2,$3,$5);

|IF'

stmt%precIFX{$$=opr(IF,2,$3,$5);

stmtELSEstmt%precELSE{$$=opr(IF,3,$3,$5,$7);

|'

{'

stmt_list'

}'

{$$=$2;

stmt_list:

stmt{$$=$1;

|stmt_liststmt{$$=opr('

2,$2,$1);

expr:

INTEGER{$$=set_content($1);

|VARIABLE{$$=set_index($1);

expr{$$=opr('

2,$1,$3);

|exprGEexpr{$$=opr(GE,2,$1,$3);

|exprLEexpr{$$=opr(LE,2,$1,$3);

|exprNEexpr{$$=opr(NE,2,$1,$3);

|exprEQexpr{$$=opr(EQ,2,$1,$3);

|exprANDexpr{$$=opr(AND,2,$1,$3);

|exprORexpr{$$=opr(OR,2,$1,$3);

|NOTexpr{$$=opr(NOT,1,$2);

expr%precUMINUS{$$=opr(UMINUS,1,$2);

{$$=$2;

#defineSIZE_OF_NODE((char*)&

p->

content-(char*)p)

Node*set_content(intvalue)

Node*p;

size_tsizeNode;

/*分配结点空间*/

sizeNode=SIZE_OF_NODE+sizeof(int);

if((p=malloc(sizeNode))==NULL)

yyerror("

outofmemory"

);

/*复制内容*/

p->

type=TYPE_CONTENT;

content=value;

returnp;

Node*set_index(intvalue)

type=TYPE_INDEX;

index=value;

Node*opr(intname,intnum,...)

va_listvalist;

inti;

sizeNode=SIZE_OF_NODE+sizeof(OpNode)+(num-1)*sizeof(Node*);

type=TYPE_OP;

op.name=name;

op.num=num;

va_start(valist,num);

for(i=0;

i<

num;

i++)

op.node[i]=va_arg(valist,Node*);

va_end(valist);

voidfreeNode(Node*p)//释放节点空间

if(!

p)return;

if(p->

type==TYPE_OP)

{

for(i=0;

op.num;

freeNode(p->

op.node[i]);

free(p);

voidyyerror(char*s)

fprintf(stdout,"

%s\n"

s);

intmain(void)

yyparse();

return0;

3.自己定义的头文件node.h中代码:

typedefenum{TYPE_CONTENT,TYPE_INDEX,TYPE_OP}NodeEnum;

/*操作符*/

typedefstruct{

intname;

/*操作符名称*/

intnum;

/*操作元个数*/

structNodeTag*node[1];

/*操作元地址可扩展*/

}OpNode;

typedefstructNodeTag{

NodeEnumtype;

/*树结点类型*/

/*Union必须是最后一个成员*/

union{

intcontent;

/*内容*/

intindex;

/*索引*/

OpNodeop;

/*操作符对象*/

};

}Node;

externintVar[26];

5.运行结果

四则运算:

布尔运算:

If语句:

While:

6.心得体会

通过本次实验,我查阅了许多资料,对编译器的运行原理有了一定程度的掌握。

自己编写的编译器功能简单,通过和使用的各种编译器对比后发现我们现在使用的编译器的非常的复杂。

同时,为以后在编写代码的时候防止错误的发生和找错的时候奠定了一定基础,可以更快找出部分错误。

同时,和队友在一起讨论的过程中也收获了一些知识,增进了和队友的友情。

 

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

当前位置:首页 > 人文社科 > 文化宗教

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

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