**
任务说明
**
1. 实验目的
给出 PL/0 文法规范,要求编写 PL/0 语言的语法分析程序。
通过设计、编制、调试一个典型的自上而下语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。
选择最有代表性的语法分析方法,如递归下降分析法、预测分析法;
选择对各种常见程序语言都具备的语法结构,如赋值语句,特别是表达式,作为分析对象。
2. 实验准备
微机安装好 C 语言,或 C++,或 Visual C++.
3.实验内容
已给 PL/0 语言文法,构造表达式部分的语法分析器。
分析对象〈算术表达式〉的 BNF 定义如下:
<表达式> ::= [+|-]<项>{<加法运算符> <项>}
<项> ::= <因子>{<乘法运算符> <因子>}
<因子> ::= <标识符>|<无符号整数>| ‘(’<表达式>‘)’
<加法运算符> ::= +|-
<乘法运算符> ::= *|/
<关系运算符> ::= =|#|<|<=|>|>=
4. 实验要求
将实验一“词法分析”的输出结果,作为表达式语法分析器的输入,进行语法解析,对于语法正确的表达式,报告“语法正确”;对于语法错误的表达式,报告“语法错误”, 指出错误原因。
把语法分析器设计成一个独立一遍的过程。
采用递归下降分析法或者采用预测分析法实现语法分析。
5. 输入输出
输入:
PL/0 表达式,用实验一的输出形式作为输入。 例如: 对于 PL/0 表达式,(a+15)b 用下列形式作为输入:
(lparen,()
(ident,a)
(plus,+)
(number,15)
(rparen,))
(times,)
(ident,b)
输出:
对于语法正确的表达式,报告“语法正确”;
对于语法错误的表达式,报告“语法错误”, 指出错误原因。
具体实现
设计思想
扩充的巴科斯范式
<表达式> ::= [+|-]<项>{<加法运算符> <项>}
<项> ::= <因子>{<乘法运算符> <因子>}
<因子> ::= <标识符>|<无符号整数>| ‘(’<表达式>‘)’
<加法运算符> ::= +|-
<乘法运算符> ::= |/
普通的巴科斯范式
为表示方便:
表达式E、项X、因子Y、标识符b,无符号整数z,加法运算符A,乘法运算符C
E->AX|X|EAX
X->Y|XCY
Y->b|z|(E)
A->+|-
C->|/
消除左递归
E->XE’|AXE’
E’->AXE’|ε
X->YX’
X’->CYX’|ε
Y->b|z|(E)
A->+|-
C->|/
改进后的文法满足LL(1)文法条件,所以该文法是LL(1)的。
FIRST和FOLLOW集合
FIRST(E)={b,z,(,+,-} FOLLOW(E)={#,)}
FIRST(E’)={ε,+,-} FOLLOW(E’)={#,)}
FIRST(X)={b,z,(} FOLLOW(X)={+,-,#,)}
FIRST(X’)={ε,,/} FOLLOW(X’)={+,-,#,)}
FIRST(Y)={b,z,(} FOLLOW(Y)={
,/,+,-,#}
FIRST(A)={+,-} FOLLOW(A)={b,z,(}
FIRST©={
,/} FOLLOW©={b,z,(}
算法流程
代码
#include <iostream>
#include <string>
using namespace std;
int flag=1; //记录分析状态
int p=-1; //指针作用
//分析的单词,s1为编码,s2为单词符号
struct strs
{
string s1,s2;
};
strs analystr;//当前分析的单词
//扫描下一个单词
void Advance(strs *S)
{
p++;
analystr = S[p];
}
void X(strs