PL0编译程序实现的简要回顾
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
"+"|"-"|"*"|"/" printf( "An operator: %s\n", yytext );
%%
main(int argc, char ** argv )
{ ++argv, --argc; /* skip over program name */
if ( argc > 0 ) yyin = fopen( argv[0], "r" );
%right '^' /* exponentiation
*/
❖ 五、二义性及移进/规约冲突
❖ 六、出错处理
❖ 目标代码pcode是一种假想栈式计算机的汇编语言。
const
a=10;
var
b,c;
0 jmp 0 8 1 jmp 0 2
procedure
p;
begin
2 int 0 3
c:=b+a;
3 lod 1 3
end;
4 lit 5 opr 6 sto 7 opr 8 int 9 opr
0 10
begin
0 2 次栈顶与栈顶相加
read(b);
14
call
p;
00 05 0 16
在运行栈中申请5个栈空间 从命令行读入输入置于栈顶
write(c); end.
10 sto 0 3 将栈顶值存入变量
11 cal 0 2 调用过程
12 lod 0 4 将变量取至栈顶
13 opr 0 14 栈顶值输出至屏幕
14 opr 0 15 换行
NUM
{ $$ = $1;
}
| exp '+' exp
{ $$ = $1 + $3; }
| exp '-' exp
{ $$ = $1 - $3; }
| exp '*' exp
{ $$ = $1 * $3; }
| exp '/' exp
{ $$ = $1 / $3; }
| '-' exp %prec NEG { $$ = -$2;
❖词法分析程序的生成器,其输入是描述三型语言 的正规式,输出是一个相应正规表达式的词法分 析程序。
输入
词法规则(.l文件)
语法规则(.y文件)
Lex yylex()
Yacc yyparse()
输出
{definitions} %% {rules} %% {user subroutines}
实例:一个Java编译 器的Lex程序
else
yyin = stdin;
yylex();
}
Lex文件格式中应注意的问题
正规表达式:
IDENTIFIER DIGIT HEXDIGIT HEXNUMBER
[A-Za-z][A-Za-z0-9]* [0-9] [A-Fa-f0-9] 0[Xx]{HEXDIGIT}+
语义动作:
{ID}
{
"+"|"-"|"*"|"/" {
一个简单实例
BISON DECLARATIONS
实例:一个Java编译器的 Yacc程序
%% GRAMMAR RULES %%
ADDITIONAL C CODE
Yacc文件格式中应注意的问题
❖ 一、TOKEN的定义 %token NUM
%token <id> IDENT
❖ 二、语法规则与语义动作
exp:
VAR
A
;
BEGIN
READ (
A)
移进 规约 接受 错误
END .
YACC&LEX介绍及实 例分析
清华大学计算机系软件研究所 赖辉旻
简要介绍
❖ Yacc ( Yet Another Compiler-Compiler )
基于LALR(1)的语法分析程序的生成器
❖ Lex (A Lexical Analyzer Generator)
Lex文件格式
பைடு நூலகம்%{
#include <math.h>
%}
DIGIT [0-9]
ID
[a-z][a-z0-9]*
%%
{DIGIT}+ {
printf(“An integer: %s (%d)\n”,
yytext,atoi(yytext));}
{ID}
printf( "An identifier: %s\n", yytext );
<分程序> <变量说明部分> VAR <标识符>
A
<程序> .
<语句>
; <复合语句>
BEGIN
<语句>
END
<读语句>
READ ( <标识符> )
A
VAR A; 自底向上的语法分<程析序>
BEGIN READ(A)
END.
<分程序>
<语句>
<复合语句>
<变量说明部分> <标识符>
<语句> <读语句> <标识符>
实现 ❖ 步骤5、 PL/0编译程序代码生成的实现 ❖ 步骤6、 PL/0编译程序语法错误处理的实现 ❖ 步骤7、 pcode代码解释器的设计与实现
❖ PL/0语言:PASCAL语言的子集,功能简单,结构清 晰,可读性强,具备了一般高级语言的必备部分
❖ PL/0程序示例 ❖ PL/0的非形式描述 ❖ PL/0的语法描述图 ❖ PL/0语言文法的EBNF表示
}
| exp '^' exp
{ $$ = pow ($1, $3); }
| '(' exp ')'
{ $$ = $2;
}
Yacc文件格式中的关键问题
❖ 四、算符的优先级与结合率
%left '-' '+’
%left '*' '/’
%left NEG
/* negation--unary minus */
PL/0源程序
PL/0编译程序
pcode代码
注:此处的pcode代码专指PL/0的目标码,注意与传统pcode的区别
pcode解释程序
❖ 步骤1、 认识源语言PL/0与目标代码pcode及它 们之间的映射
❖ 步骤2、 PL/0编译程序的总体设计 ❖ 步骤3、 PL/0编译程序词法分析的设计与实现 ❖ 步骤4、 PL/0编译程序语法语义分析的设计与
printf( “An identifier: %s\n”, yytext ); strcpy(yylval.id,yytext); return ID } printf( "An operator: %s\n", yytext ); return OPR }
Yacc文件格式
%{ C DECLARATIONS %}
15 opr 0 0
RA 12 DL 0 SL 0 变量2 变量1 RA 0 DL 0
SL:静态链
SL 0 0
DL:动态链
运行栈
RA:返回地址
出错处理程序 表格管理程序
PL/0源程序 词法分析程序 语法语义分析程序 代码生成程序
目标程序
自顶向下的语法分析
VAR A; BEGIN
READ(A) END.