项 因子
因子 * / 因子 ident number ( 表达式 ) 5
2. PL/0语言编译器
本书所提供的PL/0语言编译器的基本工作流程如图1-1所示:
源程序
词法分析 语法分析 符号表管理语义分析 错误诊断处理 代码生成 代码执行 执行结果
图1-1 PL/0编译器基本工作流程
6
2.1 词法分析
PL/0的语言的词法分析器将要完成以下工作: (1) 跳过分隔符(如空格,回车,制表符); (2) 识别诸如begin,end,if,while等保留字;
(3) 识别非保留字的一般标识符,此标识符值(字符序列)赋给
全局量id,而全局量sym赋值为SYM_IDENTIFIER。 (4) 识别数字序列,当前值赋给全局量NUM,sym则置为
SYM_NUMBER;
(5) 识别:=,<=,>=之类的特殊符号,全局量sym则分别被赋值
为SYM_BECOMES,SYM_LEQ,SYM_GEQ等。
相关过程(函数)有getsym(),getch(),其中getch()为获取单
个字符的过程,除此之外,它还完成: (1) 识别且跳过行结束符; (2) 将输入源文件复写到输出文件;
(3) 产生一份程序列表,输出相应行号或指令计数器的值。
2.2 语法分析
我们采用递归下降的方法来设计PL/0编译器。以下我们给出该语言的FIRST和FOLLOW集合。
非终结符(S) FIRST(S) 程序体 const var procedure ident call if begin while 语句 ident call begin if while 条件 odd + - ( ident number 表达式 + - ( ident number 项 ident number (
7
FOLLOW(S) . ; . ; end then do . ; ) R end then do . ; ) R + - end then do 因子 ident number ( . ; ) R + - * / end then do 注:表中R代表六个关系运算符。 不难证明,PL/0语言属于LL(1)文法。(证明从略。) 以下是我们给出如何结合语法图编写(递归下降)语法分析程序的一般方法。假定图S所对应的程序段为T(S),则:
(1) 用合适的替换将语法约化成尽可能少的单个图;
(2) 将每一个图按下面的规则(3)-(7)翻译成一个过程说明; (3) 顺序图对应复合语句:
S1 S2 Sn
对应:begin T(S1); T(S2); ...; T(Sn) end
(4) 选择:
S1 S2 S3
对应:case语句或者条件语句:
case ch of if ch in L1 then T(S1) else L1: T(S1); if ch in L2 then T(S2) else L2: T(S2); 或 ...
... if ch in Ln then T(Sn) else Ln: T(Sn); error
其中Li∈FIRST(Si),ch为当前输入符号。(下同) (5) 循环
S 对应:while ch in L do T(S)
(6) 表示另一个图A的图:
A 8
对应:过程调用A。
(7) 表示终结符的单元图: x 对应:if ch == x then read(ch) else error
相关过程有:
block(), constdeclaration(), vardeclaration(), condition(), expression(), term(), factor()等。 它们之间依赖关系如图1-2:
程序 程序体 语句 条件 表达式 项 因子
图1-2 语法分析过程依赖关系
9
statement(),