编译原理-针对任意文法的递归下降分析
提示:本文内容均为原创,请勿转载。
前言
提示:本文实现的主要功能如下
☆从文件中读入若干个符号串, 依次输出语法分析的结果
★☆实现错误恢复
★★输出语法分析树
★★扩展LL.c , 可以针对任意文法进行预测分析
First集、Follow集、预测分析表手工求出;文法和分析表从文件读入
提示:以下是本篇文章正文内容,下面案例可供参考
文尾提供中间版本(简单版)
读者若有问题可咨询qq:1780224087
一、什么是递归下降分析
所谓递归下降分析就是从起始符开始针对当前表达式中分析到的非终结符进行表达式匹配,如此层层开展看上去就是一个多层的递归调用
二、如何实现任意文法的递归下降分析
我们知道对一个给定的文法进行分析时我们只需给出每一个非终结符可能匹配的情况从一个分析函数里根据匹配条件选定下一个函数进行递归调用。
当我们进行自动化的分析时只需要一个自动化分析的程序主体框架和一个程序驱动表。程序下一步如何执行只需去查表。而如何构造这样的分析表有很多灵活的选择比如结构体数组、二维数组等。
这里我们给出二维数组驱动表的构造方案,首先我们给出一个消除回溯后的文法:
G‘: S → aA|(T) //----0|①
S’ →+S|^ //-----------②|③
T → SB //-------------④
T’ →,SB|^ //----------⑤|⑥
所以表达式均已经编号方便构造其驱动表
首先给出此文法的预测分析表,此处first,follow,select集不再给出
根据这个表可以看出:在某个非终结符的分析过程中我们可以根据当前输入的字符去选择它的某一个特定的表达式,该表达式中遇到终结符匹配取下一个字符,遇到非终结符则继续查表。如此一个程序递归调用自身便可实现这样一个自动分析程序。
下边我们给出引入错误恢复后的程序驱动表
错误恢复策略这里不再陈述给出具体执行:
可推空的在原空白处写入表达式对应的空序号,-1标识FOLLOW集,-2标识不在FOLLOW且无对应表达式
其它涉及到的恢复策略读者可在程序中自行体会。
三、代码
代码如下:
#include<stdlib.h>
#include <stdio.h>
#include<string.h>
#define ERROR -1
#define ERROR2 -2
int VN_n;
int VT_n;
int expression_n;
char sym,a[50];
int ip=0;
int analysis[20][20];
char VN [20];
char VT [20];
char expression[20][10];
struct node * S(int p, int s);
struct node *createTree(char c);
void printfT( struct node *T );
int flag=1;//默认正确
struct node{
char data;
int cnt;
// int height;
struct node *next[6];
}root;
void getNextSym()
{
sym=a[++ip];
printf(" sym=%c\n",sym);
}
//================================================
void read(){
/*文法读入函数*/
FILE * fp;
int i,j;
fp=fopen(".//test2.txt", "r");
//fgets(VN,100,fp);
fscanf(fp,"%s",VN);
VN_n=strlen(VN);
//fgets(VT,100,fp);
fscanf(fp,"%s",VT);
VT_n=strlen(VT);
fscanf(fp,"%d",