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

上传人:b****5 文档编号:19010754 上传时间:2023-01-03 格式:DOCX 页数:16 大小:31.90KB
下载 相关 举报
编译原理实验报告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

//false表示当前字符未处于注释中。

while(cinf.read(&

cur_c,sizeof(char))){//从文件读一个字符

switch(in_comment){

casefalse:

if(old_c=='

/'

&

&

cur_c=='

*'

){//进入多行注释

i--;

//去除已存入扫描缓冲区的字符'

in_comment=true;

}

else{

if(old_c=='

){//进入行注释

p=1;

//去除已存入扫描缓冲区的字符'

}

else{

\\'

\n'

)//发现续行

i--;

\'

else{

if(cur_c>

='

A'

cur_c<

Z'

)//大写变小写

cur_c+=32;

if(cur_c=='

\t'

||cur_c=='

)//空格取代TAB换行

cur_c='

'

;

buf[i++]=cur_c;

}}}

break;

casetrue:

if((old_c=='

))//离开注释

in_comment=false;

if(cur_c=='

p==1)in_comment=false;

}//endofswitch

old_c=cur_c;

//保留前一个字符

}//endofwhile

buf[i++]='

#'

//在源程序尾部添加字符'

4、结果的输入与输出

Source.txt

Begin/*S=2*3.14*R*R+2*3.14*

R*H*/

RealR,h,s;

s=2*3\

14*r*(r+++h)kmoiulEnd

运行结果如下:

实验二

1、程序设计思路:

编写一个自动机(DFA)识别程序,判断一个字符序列是否为一个DFA所识别。

首先在试验一的基础上,对输入的字符序列进行预处理,然后在输入字符,看其是否能被指定的DFA识别。

构造DNA状态转换矩阵,由输入的字符,确定其是否有后继状态,即是否能被识别。

2、实现过程

DFA的主要函数是:

scanner(char*);

核心代码如下:

while(buf[i]=='

)i++;

{intcur_state=0;

while(DFA[cur_state][col(buf[i])]){//存在后继状态

cur_state=DFA[cur_state][col(buf[i])];

//进入下一状态

if(buf[++i]=='

)break;

//指向下一字符,判缓冲区内字符是否处理完。

string.h>

stdlib.h>

conio.h>

constshortWORDLEN=20;

structcode_val{

charcode;

charval[WORDLEN];

//单词编码表

constcharcode[]="

{}ac=+$*,;

()#"

//DFA列字符

constcharCOL_CHAR[]="

a0=+*,;

()#"

//状态转换矩阵(DFA)

constintDFA[][11]={//strlen("

)=11

{1,2,3,4,5,6,7,8,9,10,0},{11,11},0,12},{0},{0,0,0,13},{0},{0},{0},{0},{0},{0},{11,11},{0,12},{0}

//预处理函数原型

//扫描函数原型

code_valscanner(char*);

//主函数

voidmain()

{charbuf[4048]={'

//扫描缓冲区

//预处理

//显示buf

cout<

//单词识别

code_valt;

//临时变量

do{

t=scanner(buf);

//调用一次扫描器获得一个单词二元式

cout<

t.code<

t.val<

//在屏幕显示单词二元式

}while(t.code!

);

"

Endoflexicalanalysis!

getch();

intcol(char);

//转换函数

charsearch_table(char[]);

//查单词二元式编码表函数

structcode_valscanner(char*buf)//扫描函数,每调用一次,返回一个单词的二元式。

{

staticinti=0;

//buf指针

structcode_valt={'

"

NUL"

chartoken[WORDLEN]="

//用于拼接单词

//去除前导空格

//开始识别单词

intcur_state=0;

}

returnt;

//返回当前单词的二元式

intcol(charc)

if(c>

a'

c<

z'

)c='

0'

9'

//constcharCOL_CHAR[]="

for(inti=0;

i<

=(int)strlen(COL_CHAR);

i++)

if(c==COL_CHAR[i])returni;

Errorchar>

exit(0);

//程序终止运行

}//预处理函数

voidpro_process(char*buf)

ifstreamcinf("

inti=0;

charold_c='

//计数器,前一个字符,当前字符。

//状态标志,false表示当前字符未处于注释中。

cur_c,sizeof(char))){//从文件读一个字符

){//进入注释

//去除已存入扫描缓冲区的字符'

)//去除续行符'

,包括后续换行符。

else{

)cur_c+=32;

if(cur_c=='

||cur_c=='

)cur_c='

//空格

buf[i++]=cur_c;

}}

)//离开注释

//保留前一个字符

buf[i]='

输入内容在source.txt中,如下:

egin/*S=2*3.14*R*R+2*3.14*R*H*/

14*r*(r+++h)kmoiul

End

{NUL

cNUL

ir

NUL

ih

is

NUL

=NUL

x2

*NUL

x314

(NUL

$NUL

+NUL

)NUL

ikmoiul

}NUL

#NUL

实验三

在自上而下预测分析控制程序的基础上,根据文法规则进行语法分析,如字串是句子,写出文法的最左推导。

根据表达式文法的预测分析表,对输入的符号串进行分析。

输入的符号串需是单词二元式。

若产生式匹配,则输出产生式。

X存放当前栈顶符号的工作单元,当X是终结符时,读入下一个符号;

当X是非终结符时,判断其是否为#,若不是,则判断其M[X,a]是否是产生式(匹配),匹配则逆序出栈,然后按最左推导输出。

具体代码如下:

for(i=strlen(p[M[lin(X)][col(t.code)]])-1;

i>

=0;

i)

{stack[++top]=*(p[M[lin(X)][col(t.code)]]+i);

X<

->

p[M[lin(X)][col(t.code)]]<

charcode;

charval[20];

constchar*p[]={//指向产生式右部符号串

TD"

+TD"

FS"

*FS"

(E)"

i"

x"

y"

//0.E→TDD代表E'

//1.D→+TD

//2.D→ε

//3.T→FSS代表T'

//4.S→*FS

//5.S→ε

//6.F→(E)

//7.F→i

//8.F→x

//9.F→y

constcharT[]="

+*()ixy#"

//分析表的列符

constcharNT[]="

EDTSF"

//分析表的行符,行符为EE'

TT'

F。

constintM[][8]={

/*在预测分析表M中存放指针数组p的下标x,设M[i][j]=x,通过p[M[i][j]]=p[x]获取右部符号串。

*/

{-1,-1,0,-1,0,0,0,-1},//p[0]指向第0个产生式右部符号串"

,-1表示出错。

{1,-1,-1,2,-1,-1,-1,2},

{-1,-1,3,-1,3,3,3,-1},

{5,4,-1,5,-1,-1,-1,5},

{-1,-1,6,-1,7,8,9,-1}

//函数原型

intlin(char);

//非终结符转换为行号

intcol(char);

//终结转换为列号

boolisNT(char);

//isNT判断是否是非终结符

boolisT(char);

//isT判断是否是终结符。

voidmain(void)

inti,j=0;

lex_r.txt"

//从文件lex_r.txt输入数据

ofstreamcout("

par_r.txt"

out);

//结果输出至文件par_r.txt(cout重定义)

structcode_valt;

//定义结构变量,存放单词二元式。

cinf>

>

t.code>

t.val;

//读一个单词的二元式

charstack[20]={'

'

E'

inttop=1;

//栈赋初值

charX='

//用于显示,并非必要。

step"

stack"

X"

t.code"

//用于显示,并非必要。

j<

)'

//用于显示,并非必要。

while

(1){

for(i=0;

=top;

i++)cout<

stack[i];

//用于显示,并非必要。

X=stack[top--];

//出栈

++j<

//用于显示,并非必要。

//用于显示,并非必要。

if(X=='

){

if(X==t.code){cout<

\tAcc"

break;

//跳出循环}

else{cout<

Errin#>

}//endofif(X=='

if(isT(X)){//是否是终结符

if(X==t.code)

cinf>

//读下一单词二元式

ErrinT>

continue;

}//endofif(isT(X))

if(isNT(X)){//是否是非终结符

if(M[lin(X)][col(t.code)]==-1){

cout<

ErrinNT>

else{for(i=strlen(p[M[lin(X)][col(t.code)]])-1;

i--)

stack[++top]=*(p[M[lin(X)][col(t.code)]]+i);

}//endofif(isNT(X))

Errinmain()>

}//endofwhile

}//endofmain

intlin(charc)//将EDTSF分别转换为01234

{for(inti=0;

(int)strlen(NT);

if(c==NT[i])returni;

Errinlin()>

intcol(charc)//将+*()ixy#分别转换为01234567

{or(inti=0;

(int)strlen(T);

i++)if(c==T[i])returni;

Errincol()>

boolisNT(charc)//是否是非终结符

{for(inti=0;

i++)if(c==NT[i])returntrue;

returnfalse;

boolisT(charc)//是否是终结符(不包括'

(int)strlen(T)-1;

i++)if(c==T[i])returntrue;

文件lex_r.txt输入数据,如下:

ia+nulib#nul

结果输出至文件par_r.txt,如下:

stepstackXt.code

0)#Ei

1)#Ei

E->

TD

#DTi

2)#DTi

T->

FS

#DSFi

3)#DSFi

F->

i

#DSii

4)#DSii

#DS+

5)#DS+

S->

#D+

6)#D+

D->

+TD

#DT++

7)#DT++

8)#DTi

9)#DSFi

10)#DSii

#DS#

11)#DS#

#D#

12)#D#

##

13)##

Acc

实验四

在LR语法分析器的控制程序的基础上,添加语义栈,在对字符串进行分析的同时,也翻译字符串。

当action<

0时,进行归约,action为-n,则

,即归约编号为n的产生式。

若action=-1,则归约产生式E→E+T。

语义栈的栈顶yu[top]应变为当前位置与其后第二个位置的和,如下:

case-1:

yu[top]=yu[top]+yu[top+2];

同理,其余产生式的语义翻译也如下:

case-2:

yu[top]=yu[top];

case-3:

yu[top]=yu[top]*yu[top+2];

case-4:

case-5:

yu[top]=yu[top+1];

case-6:

最后,当程序接受acc之后,输出翻译结果,即输入栈顶元素。

structcode_val{charcode;

constchar*p[]={"

S→E"

E→E+T"

E→T"

T→T*F"

T→F"

F→(E)"

F→i"

};

constcharTNT[]="

+*()i#ETF"

//LR分析表列的字符

constintM[][9]={//LR分析表数字化,列字符+*()i#ETF用数字012345678标识。

{0,0,4,0,5,0,1,2,3},//0表示出错,s4用4表示。

{6,0,0,0,0,99},//Acc用99表示

{-2,7,0,-2,0,-2},//r2用-2表示

{-4,-4,0,-4,0,-4},

{0,0,4,0,5,0,8,2,3},

{-6,-6,0,-6,0,-6},

{0,0,4,0,5,0,0,9,3},

{0,0,4,0,5,0,0,0,10},

{6,0,0,11},

{-1,7,0,-1,0,-1},

{-3,-3,0,-3,0,-3},

{-5,-5,0,-5,0,-5}

//列定位函数原型

{intstate[50]={0};

//状态栈初值

intyu[50]={0};

charsymbol[50]={'

//符号栈初值

inttop=0;

//栈顶指针初值

//语法分析结果输出至文件par_r.txt

ifstreamcin("

//lex_r.txt存放词法分析结果,语法分析器从该文件输入数据。

//结构变量,存放单词二元式。

cin>

//读一单词

intaction;

//输出时使用的计数器,并非必要。

状态栈"

符号栈"

输入符号"

//do{

j++<

//输出

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

当前位置:首页 > PPT模板 > 其它模板

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

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