编译原理实验报告Word文档格式.docx

上传人:b****2 文档编号:14186043 上传时间:2022-10-19 格式:DOCX 页数:50 大小:537.50KB
下载 相关 举报
编译原理实验报告Word文档格式.docx_第1页
第1页 / 共50页
编译原理实验报告Word文档格式.docx_第2页
第2页 / 共50页
编译原理实验报告Word文档格式.docx_第3页
第3页 / 共50页
编译原理实验报告Word文档格式.docx_第4页
第4页 / 共50页
编译原理实验报告Word文档格式.docx_第5页
第5页 / 共50页
点击查看更多>>
下载资源
资源描述

编译原理实验报告Word文档格式.docx

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

编译原理实验报告Word文档格式.docx

2、语法分析程序设计与实现

选择对各种常见高级程序设计语言都较为通用的语法结构——算术表达式的一个简化子集——作为分析对象,根据如下描述其语法结构的BNF定义G2[<

算术表达式>

],任选一种学过的语法分析方法,针对运算对象为无符号常数和变量的四则运算,设计并实现一个语法分析程序。

G2[<

]:

<

→<

项>

|<

+<

-<

因式>

*<

/<

运算对象>

|(<

若将语法范畴<

、<

和<

分别用E、T、F和i代表,则G2可写成:

G2[E]:

E→T|E+T|E-TT→F|T*F|T/FF→i|(E)

由实验一输出的单词串,例如:

UCON,PL,UCON,MU,ID·

·

若输入源程序中的符号串是给定文法的句子,则输出“RIGHT”,并且给出每一步分析过程;

若不是句子,即输入串有错误,则输出“ERROR”,并且显示分析至此所得的中间结果,如分析栈、符号栈中的信息等,以及必要的出错说明信息。

对文法G2[<

]中的产生式添加语义处理子程序,完成运算对象是简单变量(标识符)和无符号数的四则运算的计值处理,将输入的四则运算转换为四元式形式的中间代码。

包含测试用例(由标识符、无符号数和+、−、*、/、(、)构成的算术表达式)的源程序文件。

将源程序转换为中间代码形式表示,并将中间代码序列输出到文件中。

若源程序中有错误,应指出错误信息

二、设计思路

1)单词分类

为了编程的实现。

我们假定要编译的语言中,全部关键字都是保留字,程序员不得将它们作为源程序中的标识符;

作了这些限制以后,就可以把关键字和标识符的识别统一进行处理。

即每当开始识别一个单词时,若扫视到的第一个字符为字母,则把后续输入的字母或数字字符依次进行拼接,直至扫视到非字母、数字字符为止,以期获得一个尽可能长的字母数字字符串,然后以此字符串查所谓保留字表(此保留字表要事先造好),若查到此字符串,则取出相应的类别码;

反之,则表明该字符串应为一标识符。

表1语言中的各类单词符号及其分类码表

单词符号

类别编码

类别码的助记符

单词值

begin

1

BEGIN

end

2

END

if

3

IF

then

4

THEN

else

5

ELSE

标识符

6

ID

字母打头的字母数字串

无符号常数

7

UCON

机内二进制表示

8

LT

=

9

LE

10

EQ

>

11

NE

12

GT

13

GE

:

14

IS

+

15

PL

-

16

MI

*

17

MU

/

18

DI

2)词法分析器的设计

函数GETCHAR:

每调用一次,就把扫描指示器当前所指示的源程序字符送入字符变量ch,然后把扫描指示器前推一个字符位置。

字符数组TOKEN:

用来依次存放一个单词词文中的各个字符。

函数CAT:

每调用一次,就把当前ch中的字符拼接于TOKEN中所存字符串的右边。

函数LOOKUP:

每调用一次,就以TOKEN中的字符串查保留字表,若查到,就将相应关键字的类别码赋给整型变量c;

否则将c置为零。

函数RETRACT:

每调用一次,就把扫描指示器回退一个字符位置(即退回多读的那个字符)。

函数OUT:

一般仅在进入终态时调用此函数,调用的形式为OUT(c,VAL)。

图1识别表I所列语言中的部分单词的DFA及相关的语义过程

3)词法分析程序的实现

编写的扫描器:

charTOKEN[20],TOKEND[20],TOKENDO[20];

intlookup(char*);

voidout(int,char*);

voidreport_error(void);

//externvoidLEX(void);

intsiagn=0;

//标志位

FILE*fp1;

char*KeyWordTable[MAX_KEY_NUMBER]={"

begin"

"

end"

"

if"

then"

else"

KEY_WORD_END};

/*查保留字表,判断是否为关键字*/

intlookup(char*token)

{

intn=0;

while(strcmp(KeyWordTable[n],KEY_WORD_END))/*strcmp比较两串是否相同,若相同返回0*/

{

if(!

strcmp(KeyWordTable[n],token))/*比较token所指向的关键字和保留字表中哪个关键字相符*/

{

returnn+1;

/*根据单词分类码表I,设置正确的关键字类别码,并返回此类别码的值*/

break;

}

n++;

}

return0;

}

voidscanner_example(FILE*fp)

charch;

inti,c,isd,cpoint;

doubleo;

ch=fgetc(fp);

//fgetc函数在文件中读取一个字符

if(isalpha(ch))/*itmustbeaidentifer!

它必须是一个标识符判断字符ch是否为英文字母,若为小写字母,返回2,若为大写字母,返回1。

若不是字母,返回0*/

TOKEN[0]=ch;

ch=fgetc(fp);

i=1;

while(isalnum(ch)||ch=='

.'

)//isalnum函数判断ch是否为空当ch为数字0-9或字母a-z及A-Z时,返回非零值,否则返回零

if(ch=='

){

cpoint=-1;

//标志字符串中有小数点

}

TOKEN[i]=ch;

i++;

ch=fgetc(fp);

TOKEN[i]='

\0'

;

if(ch=='

'

||ch=='

='

){

fseek(fp,-2,1);

siagn=1;

elsefseek(fp,-1,1);

//fseek(fp,-1,1);

/*retractfseek函数每调用一次,就把扫描指示器回退一个字符位置(即退回多读的那个字符)*/

i=0;

if(TOKEN[i]=='

o'

||TOKEN[i]=='

O'

{ i++;

if(TOKEN[i]=='

x'

X'

{

i++;

while(TOKEN[i]!

{

if(!

isdigit(TOKEN[i])||TOKEN[i]!

a'

||TOKEN[i]!

b'

c'

d'

e'

f'

||TOKEN[i]!

A'

B'

C'

D'

E'

F'

{

isd=-1;

}

isd=16;

//标志字符串十六进制

i++;

}

elseif(TOKEN[i]=='

0'

1'

2'

3'

4'

5'

6'

7'

isd=8;

//标志字符串八进制

if(TOKEN[i]!

isd=8;

}

if(isd==8){

strncpy(TOKEND,TOKEN+1,strlen(TOKEN)-1);

//拷贝函数

//printf("

%o"

atof(TOKEND));

o=octal(TOKEND);

%g"

o);

sprintf(TOKENDO,"

octal(TOKEND));

out(OCTAL,TOKENDO);

elseif(isd==16){

strn

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

当前位置:首页 > 高等教育 > 其它

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

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