语法分析器的构造

本文档详述了如何构建语法分析程序,通过预测分析法处理文法和输入串,涉及文法定义、错误处理、预测分析表的计算与应用,以及实际的语法分析过程。同时,文中列举了实验中遇到的问题,如输出格式和空串分析的挑战。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、实验目的
通过预测分析算法的设计与实现,加深对自上而下语法分析方法的理解;能够采用一种编程语言实现简单的语法分析程序;能够使用自己编写的分析程序对简单的程序段进行语法翻译;加深对语法分析器工作过程的理解。
二、实验内容
用预测分析法编制语法分析程序,输入文法及待分析的输入串,输出其预测分析过程及结果。
三、实验要求
1.对语法规则有明确的定义;
2.编写的分析程序能够对输入的文法和待分析串进行正确的语法分析;
3.对于遇到的语法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成语法分析过程;
4.实验报告要求对语法定义做出详细说明,说明语法分析程序的工作过程。
四、实验步骤
1.定义目标语言的语法规则;
2.判断文法的左递归性,将左递归文法转换成非左递归文法。(该步骤可以省略,直接输入非左递归文法);
3.根据文法求FIRST集和FOLLOW集;
4.求解预测分析方法需要的分析表;
5.输入文法及待分析的输入串,输出其预测分析过程及结果。
五、实验内容
1.编程思路、源代码
编程思路:
语法分析是编译程序的核心。它的作用是识别由词法分析给出的单词符号串是否是给定文法的正确句子(程序)。通过求给定的表达式文法的First集和Follow集,然后得出预测分析表,输入串根据预测分析表进行分析,输出分析过程 。
源代码:
#include <stdio.h>
#include <stdlib.h>
#define MaxRuleNum 8
#define MaxVnNum 5 //非终结符个数
#define MaxVtNum 5 //终结符个数
#define MaxStackDepth 20
#define MaxPLength 20 //
#define MaxStLength 50 //输入串长度
struct pRNode /* 产生式右部结构 /
{
int rCursor;
struct pRNode next;
};
struct pNode
{
int lCursor;
int rLength; /
右部长度 /
struct pRNode rHead; / 右部结点头指针 /
};
char Vn[MaxVnNum + 1]; /
非终结符集 /
int vnNum;
char Vt[MaxVtNum + 1]; /
终结符集 /
int vtNum;
struct pNode P[MaxRuleNum];
int PNum;
char buffer[MaxPLength + 1];
char ch;
char st[MaxStLength]; /
要分析的符号串 /
struct collectNode
{
int nVt;
struct collectNode next;
};
struct collectNode
first[MaxVnNum + 1]; /first 集/
struct collectNode
follow[MaxVnNum + 1]; /follow 集/
int analyseTable[MaxVnNum + 1][MaxVtNum + 1 + 1];
int analyseStack[MaxStackDepth + 1]; /
分析栈 /
int topAnalyse; /
分析栈顶 /
void Init();/
初始化 /
int IndexCh(char ch); //
void InputVt(); /
输入终结符 /
void InputVn();/
输入非终结符 /
void ShowChArray(char
collect, int num);/
输出 Vn 或 Vt 的内容 /
void InputP(); /
产生式输入 /
bool CheckP(char * st);/
判断产生式正确性 /
void First(int U);
void AddFirst(int U, int nCh); /
加入 first 集*/
bool HaveEmpty(int nVn);
void Follow(int V);/* 计算 follow 集*/
void AddFollow(int V, int nCh, int kind);
void ShowCollect(struct collectNode collect);/ 输出 first 或 follow集/
void FirstFollow();/* 计算 first 和 follow*/
void CreateAT();/* 构造预测分析表 /
void ShowAT();/
输出分析表 /
void Identify(char st);
void InitStack();
void ShowStack();
void Pop();
void Push(int r);
int main()
{ char todo,ch;
printf(" 语法分析器
\n");
Init();
InputVn(); //输入非终结符
InputVt();//输入终结符
InputP();
getchar();
FirstFollow();
printf(“所有的非终结符 first 集为: “);
ShowCollect(first);
printf(“所有的非终结符 follow 集为: “);
ShowCollect(follow);
CreateAT();
ShowAT();
todo = ‘y’;
while(‘y’ == todo)
{ printf(”\n 是否继续进行句型分析? (y / n):”);
todo = getchar();
while(‘y’ != todo && ‘n’ != todo)
{
printf(”\n(y / n)? “);
todo = getchar();
}
if(‘y’ == todo)
{ int i;
InitStack();
printf(“请输入符号串 (以#结束 ) : “);
ch = getchar();
i = 0;
while(’#’ != ch && i < MaxStLength)
{
if(’ ’ != ch && ‘\n’ != ch)
{ st[i++] = ch;
}
ch = getchar();
}
if(’#’ == ch && i < MaxStLength)
{ st[i] = ch;
Identify(st);
}

这个里面的都是测试数据,总共得分5分。从控制台输入,不能从文件中读取。实现了基本功能,加分项目都没有去实现,没有函数数组这些的实现。这是用C++语言写的,新建parser类别要选C++,其他对于VS的配置和C语言一样。for语句用的是枚举所有情况,你可以自行修改。 对预备工作中自然语言描述的简化C编译器的语言特性的语法,设计上下文无关文法进行描述 借助Yacc工具实现语法分析器 考虑语法树的构造: 1.语法树数据结构的设计:节点类型的设定,不同类型节点应保存哪些信息,多叉树的实现方式 2.实现辅助函数,完成节点创建、树创建等功能 3.利用辅助函数,修改上下文无关文法,设计翻译模式 4.修改Yacc程序,实现能构造语法树的分析器 考虑符号表处理的扩充 1.完成语法分析后,符号表项应增加哪些标识符的属性,保存语法分析的结果 2.如何扩充符号表数据结构,Yacc程序如何与Lex程序交互,正确填写符号表项 以一个简单的C源程序验证你的语法分析器,可以文本方式输出语法树结构,以节点编号输出父子关系,来验证分析器的正确性,如下例: main() { int a, b; if (a == 0) a = b + 1; } 可能的输出为: 0 : Type Specifier, integer, Children: 1 : ID Declaration, symbol: a Children: 2 : ID Declaration, symbol: b Children: 3 : Var Declaration, Children: 0 1 2 4 : ID Declaration, symbol: a Children: 5 : Const Declaration, value:0, Children: 6 : Expr, op: ==, Children: 4 5 7 : ID Declaration, symbol: a Children: 8 : ID Declaration, symbol: b Children: 9 : Const Declaration, value:1, Children: 10: Expr, op: +, Children: 8 9 11: Expr, op: =, Children: 7 10 12: if statement, Children: 6 11 13: compound statement, Children: 3 12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啥啥都知道

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值