编译原理实验报告PL0.docx

上传人:b****2 文档编号:17061527 上传时间:2023-07-21 格式:DOCX 页数:10 大小:49.67KB
下载 相关 举报
编译原理实验报告PL0.docx_第1页
第1页 / 共10页
编译原理实验报告PL0.docx_第2页
第2页 / 共10页
编译原理实验报告PL0.docx_第3页
第3页 / 共10页
编译原理实验报告PL0.docx_第4页
第4页 / 共10页
编译原理实验报告PL0.docx_第5页
第5页 / 共10页
编译原理实验报告PL0.docx_第6页
第6页 / 共10页
编译原理实验报告PL0.docx_第7页
第7页 / 共10页
编译原理实验报告PL0.docx_第8页
第8页 / 共10页
编译原理实验报告PL0.docx_第9页
第9页 / 共10页
编译原理实验报告PL0.docx_第10页
第10页 / 共10页
亲,该文档总共10页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

编译原理实验报告PL0.docx

《编译原理实验报告PL0.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告PL0.docx(10页珍藏版)》请在冰点文库上搜索。

编译原理实验报告PL0.docx

编译原理实验报告PL0

PL/0语言编译器分析实验报告

 

学院:

运算机学院

学号:

95

姓名:

夏建鑫

课程名称:

编译原理

 

一、实验目的

通过阅读与解析一个实际编译器(PL/0语言编译器)的源代码,加深对编译阶段(包括词法分析、语法分析、语义分析、中间代码生成等)和编译系统软件结构的理解,并达到提高学生学习兴趣的目的。

二、实验要求

(1)要求掌握大体的程序设计技能(C语言)和阅读较大规模程序源代码的能力;

(2)理解并掌握编译进程的逻辑阶段及各逻辑阶段的功能;

(3)要求能把握整个系统(PL/0语言编译器)的体系结构,各功能模块的功能,各模块之间的接口;

(4)要求能总结出实现编译进程各逻辑阶段功能采用的具体算法与技术。

三、实验步骤

(1)按照PL/0语言的语法图,理解PL/0语言各级语法单位的结构,掌握PL/0语言合法程序的结构;

(2)从整体上分析整个系统的体系结构、各功能模块的功能、各模块之间的挪用关系、各模块之间的接口;

(3)详细分析各子程序和函数的代码结构、程序流程、采用的主要算法及实现的功能;

(4)撰写分析报告,主要内容包括系统结构框图、模块接口、主要算法、各模块程序流程图等。

四、报告内容

PL/0语言语法的BNF表示-1,对语法描述图的解析

<程序>→<程序体>.

<程序体>→[<常量说明部份>][变量说明部份>][<进程说明部份>]<语句>

<常量说明部份>→const<常量概念>{,<常量概念>};

<常量概念>→<标识符>=<无符号整数>

<无符号整数>→<数字>{<数字>}

<变量说明部份>→var<标识符>{,<标识符>};

<标识符>→<字母>{<字母>|<数字>}

<进程说明部份>→<进程首部><程序体>{;<进程说明部份>};

<进程首部>→procedure<标识符>;

<语句>→<赋值语句>|<条件语句>|<当型循环语句>|<进程挪用语句>|

<复合语句>

<赋值语句>→<标识符>:

=<表达式>

<复合语句>→begin<语句序列>end

<语句序列>→<语句>{;<语句>}

<条件>→<表达式><关系运算符><表达式>|odd<表达式>

<表达式>→[+|-]<项>{<加法运算符><项>}

<项>→<因子>{<乘法运算符><因子>}

<因子>→<标识符>|<无符号整数>|'('<表达式>')'

<加法运算符>→+|-

<乘法运算符>→*|/

<关系运算符>→=|<>|<|<=|>|>=

<条件语句>→if<条件>then<语句>

<进程挪用语句>→call<标识符>

<当型循环语句>→while<条件>do<语句>

<字母>→a|b|...|x|y|z

<数字>→0|1|2|...|8|9

编译程序整体流程图

 

 

Pl/0词法分析程序Getsym

识别的单词:

(类别,值)

保留字:

如:

BEGIN、END、IF、THEN等

运算符:

如:

+、-、*、/、:

=、#、>=、<=等

标识符:

用户概念的变量名、常数名、进程名

常数:

如:

10、2五、100等整数

界符:

如:

‘,’、‘.’、‘;’、‘(’、‘)’等

读字符子程序(getch)

〈表达式〉的递归子程序实现

procedureexpr;

begin

ifsymin[plus,minus]then

begingetsym;term;

end

elseterm;

whilesymin[plus,minus]do

begin

getsym;term;

end

end;

〈因子〉∷=〈标识符〉|〈无符号整数〉|‘(’〈表达式〉‘)’

〈因子〉的递归子程序实现

procedurefactor;

begin

ifsym<>identthen

begin

ifsym<>numberthen

begin

ifsym=‘(‘then

begin

getsym;

expr;

ifsym=‘)’then

getsym

elseerror

end

elseerror

end

elsegetsym

end

elsegetsym

end;

常量概念语句的处置语法:

<常量说明部份>:

:

=const<常量概念>{,<常量概念>};

<常量概念>:

:

=<标识符>=<无符号整数>

<无符号整数>:

:

=<数字>{<数字>}

ifsym=constsymthen

begin

getsym;(*获取下一个token,正常应为用作常量名的标识符*)

repeat(*反复进行常量声明*)

constdeclaration;(*声明以当前token为标识符的常量*)

whilesym=commado(*若是碰到了逗号则反复声明下一常量*)

begin

getsym;(*获取下一个token,这里正好应该是标识符*)

constdeclaration(*声明以当前token为标识符的常量*)

end;

ifsym=semicolonthen(*若是常量声明结束,应碰到分号*)

getsym(*获取下一个token,为下一轮循环做好预备*)

else

error(5)(*提示5号错误*)

untilsym<>ident(*若是碰到非标识符,则常量声明结束*)

end;

常量说明处置

procedureconstdeclaration;

begin

ifsym=identthen

begin

getsym;

ifsymin[eql,becomes]then(*若是是等号或赋值号*)

ifsym=becomesthen(*若是是赋值号(常量生明中应该是等号)*)

error

(1);(*提示1号错误*)

getsym;(*获取下一个token,等号或赋值号后应接上数字*)

ifsym=numberthen(*若是的确是数字*)

begin

enter(constant);(*把那个常量登岸到符号表*)

getsym(*获取下一个token,为后面作预备*)

end

elseerror

(2)(*若是等号后接的不是数字,提示2号错误*)

elseerror(3)(*如常量标识符后不是等号或赋值号,提示3号错误*)

end

elseerror(4)

end(*constdeclaration*);

变量概念语句的处置语法:

<变量说明部份>:

:

=var<标识符>{,<标识符>};

ifsym=varsymthen

begin

getsym;

repeat

vardeclaration;(*变量说明处置*)

whilesym=commado

begin

getsym;

vardeclaration

end;

ifsym=semicolonthen

getsym

elseerror(5)

untilsym<>ident;

end;

变量说明处置procedureardeclaration;

begin

ifsym=identthen

begin

enter(variable);

getsym

end

elseerror(4)

end(*vardeclaration*);

进程概念语句的处置程序:

whilesym=procsymdo(*循环声明各子进程*)

begin

getsym;(*获取下一个token,此处正常应为作为进程名的标识符*)

ifsym=identthen(*若是token确为标识符*)

begin

enter(procedur);(*把那个进程登录到名字表中*)

getsym(*获取下一个token,正常情形应为分号*)

end

else

error(4);(*不然提示4号错误*)

ifsym=semicolonthen(*若是当前token为分号*)

getsym(*获取下一个token,预备进行语法分析的递归挪用*)

else

error(5);(*不然提示5号错误*)

解释执行的流程图

PL/0源程序的扩充

扩充FORTO和FORDOWNTO语句,此功能的关键是如何判断条件是不是成立,并如何进行程序跳转.在这里用到了几条指令,和地址回填技术.扩充程序如下:

caseFORSYM:

GetSym();

if(SYM!

=IDENT)Error(31);IND!

=VARIABLE){/*ASSIGNMENTTONON-VARIABLE*/

Error(12);TABLE[i].;TABLE[i].;TABLE[i].;=CX;

}

elseif(SYM==TOSYM)

{

CX1=CX;GetSym();

GEN(STO,LEV-TABLE[i].,TABLE[i].;TABLE[i].;/从头调入栈顶

EXPRESSION(SymSetAdd(DOSYM,FSYS),LEV,TX);TABLE[i].;

GEN(LIT,0,1);

GEN(OPR,0,2);

if(SYM==DOSYM){

GetSym();

STATEMENT(FSYS,LEV,TX);

}

GEN(JMP,0,CX1);

CODE[CX2].A=CX;//回填地址

}

elseError(35);

break;

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

当前位置:首页 > 经管营销 > 经济市场

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

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