一、实验目的
理解语法分析器的任务和工作原理;掌握计算机语言语法分析程序的设计方法,使用某种高级编程语言实现其语法分析器。
二、实验内容
对于只含有 +、* 运算的算术表达式,编写相应的语法分析程序,要求:
- 用表驱动的预测分析法进行语法分析。
- 采用某种高级程序设计语言,设计并实现语法分析程序。
- 设计恰当的测试用例对语法分析程序进行测试。
三、实验原理及步骤
1. 构造LL(1)分析表
假设存在以下文法:
E→TE`
E`→+TE`|ϵ
T→FT`
T`→*FT`|ϵ
F→(E)|id
产生式E→TE`被加到M[E,( ]和[E,id ]
产生式E`→+TE`被加到M[E`,+],E`→ϵ被加到M[E`,) ]和M[E`,$]
产生式T→FT`被加到M[T,( ]和M[T,id]
产生式T`→*FT`被加到M[T`,*],T`→ϵ被加到M[T`,+]M[T`,)]和M[T`,$]
产生式F→(E)被加到M[F,( ],F→id被加到M[F,id]
2. 语法分析程序设计思路
(1)定义分析表并输入字符串,将输入串首字符读入a。
(2)令X等于栈顶符号,并输出栈符号和剩余字符串。
(3)判断X是否为终结符。如果是,再判断X是否等于a。如果不等于a则报错,
否则再判断X是否等于$。如果不等于$,则ip+1并读入下一符号到a,同
时返回步骤(2),否则结束程序。
(4)如果X不是终结符,那么X就为非终结符。再判断M[X,a]是不是产生式,
如果是,则输出该产生式弹出栈顶的非终结符号并将产生项逆序入栈,
否则产生语法错误。
(5)因为使用的是do...while循环,所以最后判断X是否等于$,也就是栈是
否已经空了。如果等于则说明输入缓冲区的符号已经读取完毕,语法分
析过程完成,否则接着循环,返回到步骤(2)。
3. 流程图
4. 数据结构
定义两个数组存储终结符和非终结符。字符串数组form[]存储产生式。二维数组M[][]存放LL(1)分析表。stack栈存储文法符号。top为栈顶指针,其指向的栈顶符号会赋给X,因此X代表栈顶符号。ip为输入串指针,一般指向输入串的首字符,并将其赋给a,a为当前输入的字符。str存放输入的字符串。
5. 错误恢复策略
(1)预测分析表中的错误检测——两种情况下可以检测到错误:
- 栈顶的终结符和当前输入符号不匹配;
- 栈顶非终结符与当前输入符号在预测分析表对应项中的信息为空。
(2)预测分析表中的错误恢复——可以使用恐慌模式:
- 忽略输入中的一些符号,直到输入中出现由设计者选定的同步词法单元集合中的某个词法单元,集合的选取应该使得语法分析器能从实际遇到的错误中快速恢复。
- 如果终结符在栈顶而不能匹配,一个简单的办法就是弹出此终结符。
四、源代码(包含完整注释)
#include<iostream>
#include<string>
#include <conio.h>
#include<string.h>
#include<stdlib.h>
#define max 100
using namespace std;
int i;
char non_sign[10] = {
'E','A','T','B','F' };//存放非终结符号
char ter_sign[10] = {