编译原理实验报告Word格式文档下载.doc

上传人:wj 文档编号:6942125 上传时间:2023-05-07 格式:DOC 页数:15 大小:283.77KB
下载 相关 举报
编译原理实验报告Word格式文档下载.doc_第1页
第1页 / 共15页
编译原理实验报告Word格式文档下载.doc_第2页
第2页 / 共15页
编译原理实验报告Word格式文档下载.doc_第3页
第3页 / 共15页
编译原理实验报告Word格式文档下载.doc_第4页
第4页 / 共15页
编译原理实验报告Word格式文档下载.doc_第5页
第5页 / 共15页
编译原理实验报告Word格式文档下载.doc_第6页
第6页 / 共15页
编译原理实验报告Word格式文档下载.doc_第7页
第7页 / 共15页
编译原理实验报告Word格式文档下载.doc_第8页
第8页 / 共15页
编译原理实验报告Word格式文档下载.doc_第9页
第9页 / 共15页
编译原理实验报告Word格式文档下载.doc_第10页
第10页 / 共15页
编译原理实验报告Word格式文档下载.doc_第11页
第11页 / 共15页
编译原理实验报告Word格式文档下载.doc_第12页
第12页 / 共15页
编译原理实验报告Word格式文档下载.doc_第13页
第13页 / 共15页
编译原理实验报告Word格式文档下载.doc_第14页
第14页 / 共15页
编译原理实验报告Word格式文档下载.doc_第15页
第15页 / 共15页
亲,该文档总共15页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

编译原理实验报告Word格式文档下载.doc

《编译原理实验报告Word格式文档下载.doc》由会员分享,可在线阅读,更多相关《编译原理实验报告Word格式文档下载.doc(15页珍藏版)》请在冰点文库上搜索。

编译原理实验报告Word格式文档下载.doc

输出符号表;

输出常数表;

有限自动机的状态转换图:

e

ddd

+|--1/+/-

11

+①d②.③d④e⑤⑥d⑦

d-

-1/+/-

l/d-1/+/-

12

-1

l⑧-

13

-1

b⑨b⑩-

14

-1

-

15

-1

-

其中:

d为数字,l为字母,b为界符,-1代表其它符号(如在状态8处遇到了非字母或数字的其它符号,会变换到状态12)。

关键字表和界符表:

Program

;

Begin

:

End

Var

While

Do

=

Repeat

+

Until

-

For

*

To

/

If

>

Then

Else

==

<

四、主要数据结构

①状态转换矩阵:

intaut[10][7]={2,0,0,0,8,9,15,

2,3,5,11,0,0,11,

4,0,0,0,0,0,0,

4,0,5,11,0,0,11,

7,0,0,6,0,0,0,

7,0,0,0,0,0,0,

7,0,0,11,0,0,11,

8,0,0,0,8,0,12,

0,0,0,0,0,10,14,

0,0,0,0,0,0,13};

②关键字表:

charkeywords[30][12]={“program”,”begin”,”end”,”var”,”while”,”do”,

”repeat”,”until”,”for”,”to”,”if”,”then”,”else”,“;

”,”:

”,”(“,”)”,”,”,”:

=”,”+”,”-“,”*”,”/”,

”>

”,”>

=”,”==”,“<

”,“<

=”};

③符号表:

charID[50][12];

//表中存有源程序中的标识符

④常数表:

floatC[20];

⑤其它变量:

structtoken

{intcode;

intvalue};

//Token结构

structtokentok[100];

//Token数组

ints;

//当前状态

intn,p,m,e,t;

//尾数值,指数值,小数位数,指数符号,类型

floatnum;

//常数值

charw[50];

//源程序缓冲区

inti;

//源程序指针,当前字符为w[i]

charstrTOKEN[12];

//当前已经识别出的单词

五、实验核心代码

intmain(intargc,char*argv[])

FILE*fp;

ints;

//当前状态*有限自动机中的状态

fp=fopen("

exa.txt"

"

r"

);

while(!

feof(fp))

{

fgets(w,50,fp);

i=0;

//*处理一行

do

{

printf("

%c"

w[i]);

//测试显示每个token的首字母

//*处理一个token

while(w[i]=='

'

)//滤空格

i++;

if(w[i]>

='

a'

&

w[i]<

z'

)//判定单词类别*是字母(关键字或标识符)

{

ptr=col2;

num_map=2;

}

elseif(w[i]>

0'

9'

)//*是数字(常量的开头)

ptr=col1;

num_map=4;

elseif(strchr(col3[0].str,w[i])==NULL)//*其他字符算为非法字符

printf("

非法字符%c\n"

continue;

else//界符

ptr=col3;

num_map=1;

i--;

//*向后退一个字符

s=1;

//开始处理一个单词

while(s!

=0)

act(s);

if(s>

=14)//*判断是否是终止状态*是终止状态,则形成一个token

break;

//getchar()*读取下一个字符

s=find(s,w[i]);

//状态转换

if(s==0)

strTOKEN[i_str]='

\0'

;

词法错误:

%s\n"

strTOKEN);

}while(w[i]!

=10);

}

printf("

关键字表:

"

//输出结果

for(i=0;

i<

30;

i++)

printf("

%s"

keywords[i]);

printf("

\n"

Token序列:

num_token;

(%d,%d)"

tok[i].code,tok[i].value);

符号表:

num_ID;

ID[i]);

常数表:

num_C;

%d"

C[i]);

fclose(fp);

HelloWorld!

return0;

//*状态转换后,达到新的状态之后,记录的变化

voidact(ints)

intcode;

switch(s)

case1:

n=0;

m=0;

p=0;

t=0;

e=1;

num=0;

i_str=0;

strTOKEN[i_str]='

//其它变量初始化

break;

case2:

n=10*n+w[i]-48;

break;

case3:

t=1;

case4:

m++;

case5:

case6:

if(w[i]=='

-'

)e=-1;

case7:

p=10*p+w[i]-48;

case8:

strTOKEN[i_str++]=w[i];

//将ch中的符号拼接到strTOKEN的尾部;

break;

case9:

case10:

//将ch中的符号拼接到strTOKEN的尾部;

case11:

num=n*pow(10,e*p-m);

//计算常数值

tok[i_token].code=2;

tok[i_token++].value=InsertConst(num);

//生成常数Token

num_token++;

break;

case12:

strTOKEN[i_str]='

code=Reserve(strTOKEN);

//查关键字表

if(code)

{tok[i_token].code=code;

tok[i_token++].value=0;

}//生成关键字Token

else

{tok[i_token].code=1;

tok[i_token++].value=InsertID(strTOKEN);

}//生成标识符Token

num_token++;

case13:

//查界符表

{tok[i_token].code=code;

}//生成界符Token

else

strTOKEN[strlen(strTOKEN)-1]='

//单界符

i--;

code=Reserve(strTOKEN);

//查界符表

tok[i_token].code=code;

//生成界符Token

num_token++;

case14:

code=Reserve(strTOKEN);

//查界符表

tok[i_token].code=code;

//生成界符Token

//*状态转换

intfind(ints,charch)

inti,col=7;

structmap*p;

p=ptr;

num_map;

if(strchr((p+i)->

str,ch))

col=(p+i)->

col;

}

returnaut[s][col];

//*向常量表中插入常量

intInsertConst(doublenum)

inti;

if(num==C[i])

returni;

C[i]=(int)num;

num_C++;

returni;

intReserve(char*str)

num_key;

if(!

strcmp(keywords[i],str))

return(i+3);

//*向符号表中插入新的符号

intInsertID(char*str)

for(i=0;

strcmp(ID[i],str))//*符号已经存在,则返回地址

strcpy(ID[i],str);

num_ID++;

六、实验结果

实验思考题:

1.扫描器的任务是什么?

答:

词法分析程序又称扫描器,任务有:

(1)识别单词

——从用户的源程序中把单词分离出来;

(2)翻译单词

——把单词转换成机内表示,便于后续处理。

2.扫描器、识别器、翻译器三者之间的关系是怎样的?

扫描器、识别器、翻译器三者之间的关系是:

扫描器的实现要通过识别器和翻译器

1.为什么说有限自动机是词法分析的基础?

因为词法分析的包括:

识别---识别单词的有限自动机。

和翻译---根据有限自动机所识别出的对象,完成从单词串到单词的TOKEN串的翻译。

我们可以看出,不论是识别还是分析,都是应用有限自动机,所以可以说有限自动机是词法分析的基础。

实验2:

中间代码生成器的设计

熟悉算术表达式的语法分析与中间代码生成原理。

(1)设计语法制导翻译生成表达式的四元式的算法;

(2)编写代码并上机调试运行通过。

输入——算术表达式

输出——语法分析结果

相应的四元式序列

(3)本实验已给出递归子程序法的四元式属性翻译文法的设计,鼓励学生在此基础上进行创新,即设计LL

(1)分析法或LR(0)分析法的属性翻译文法,并根据这些属性翻译文法,使用扩展的语法分析器实现语法制导翻译。

三、设计概要

(1)算术表达式文法

G(E):

Eω0T|T

Tω1F|F

i|(E)

(2)文法变换

G’(E)Eà

T{ω0T}

F{ω1F}

(3)属性翻译文法:

T{ω0“push(SYN,w)”T“QUAT”}

F{ω1“push(SYN,w)”F“QUAT”}

i“push(SEM,entry(w))”|(E)

push(SYN,w)—当前单词w入算符栈SYN;

·

push(SEM,entry(w))—当前w在符号表中的入口值压入语义栈SEM;

·

QUAT—生成四元式函数

i.T=newtemp;

ii.QT[j]=(SYN[k],SEM[s-1],SEM[s],T);

j++;

iii.pop(SYN,_);

pop(SEM,_);

push(SEM,T);

(4)递归下降子程序:

·

数据结构:

SYN—算符栈;

SEM—语义栈;

E:

入口T:

入口

TF

nω0?

nω1?

yy

出口push(SYN,w)出口push(SYN,w)

read(w)QUATread(w)QUAT

F:

入口主程序:

E

(?

ni?

nerr

read(w)read(w)

push(SEM,entry(w))E

E

errn#?

errn)?

y

y输出四元式序列

read(w)

结束

开始

出口

四、实验核心代码

voidmain()//主函数

{ t=1;

cout<

<

输入表达式,以#结束:

endl;

Z();

stringits(inta){ //整形变成字符串形函数

stringd;

charb='

c;

while(a!

=0){

i=a%10;

a=a/10;

c=(int)b+i;

d=c+d;

returnd;

charF(charw){ //F自动机

stringtheWord;

if(w>

w<

||w>

A'

Z'

){

theWord=w;

//当前字符是字母

markStack.push(theWord);

//则压栈

elseif(w=='

('

){ //是左括号

cin>

>

w;

//则读取下一字符

w=E(w);

if(w!

)'

){//不是右括号则输入有误,报错

cerr<

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

当前位置:首页 > 幼儿教育 > 幼儿读物

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2