当前位置:文档之家› 合肥工业大学编译原理 LL(1)自上而下文法分析

合肥工业大学编译原理 LL(1)自上而下文法分析

#define max 100
class sign
{
public:
sign(){}
sign(int check,char fu)
{
if(check!=0&&check!=1) //符号属性只有0和1
{
cout<<"error sign creat!"<<endl;
}
else
{
identity=check; //设置符号属性
}
}
bool exit_endsign(char sg) //终结符表是否有sg
{
int x;
for(x=0;x<endsignnumber;x++)
{if(endsign[x].id==sg)
return true;
}
return false;
}
bool exit_unendsign(char sg) //非终结符表是否有sg
结果被存储在数据结构,再次“你的选择。”
然后,这些集合被显示在屏幕上
图注释:Calcul des ensembles « premiers » et « suivants »计算“第一个”和“其后”的集合
Affichage des ensembles显示集合premiers第一个suivants其后
首先实现集合FIRST(X)构造算法和集合FOLLOW(A)构造算法,再实现教材P.79给出的预测分析表构造算法。程序显示输出预测分析表或输出到指定文件中。
对文法按教材P.76表4.1构造出G的预测分析程序,程序显示输出如P.78那样的匹配过程。
三、实验环境与工具
操作系统:Windows 7
开发语言:C++
{
for(int x=0;x<follownumber;x++)
{
if(follow[x]==q)
{
for(int y=x;y<follownumber-1;y++)
follow[y]=follow[y+1];
follownumber--;
x--;//为了接着上次检查点
}
}
}
void add_first(char q)//向first添加元素
unendsign[unendsignnumber-1].funnumber++;
//cout<<rule<<endl;
}
}
void addendsign(char sg) //添加终结符
{
for(int x=0;x<endsignnumber;x++)
{
if(endsign[x].id==sg)
return;
char first[max];//first集
int firstnumber;
char follow[max];//follow集
int follownumber;
};
class cell //分析表的单元格结构
{
public: char cell_unendsign;//终结符
char cell_endsign;//非终结符
ifs.open(sourcefile);
char buf[max];
for(x=0;x<max;x++)
buf[x]='\0';
while(ifs.getline(buf,sizeof(buf))) //一行一行读取
{
unendsign[unendsignnumber]=sign(0,buf[0]);
{
for(int x=0;x<unendsignnumber;x++)
{
if(unendsign[x].id==sg)
return true;
}
return false;
}
sign get_unendsign(char sg)//从非终结符表中得到非终结符为sg的实例
{
for(int x=0;x<unendsignnumber;x++)
输入字符串的分析
最后一步:你的程序读取输入(键盘)的表达和分析。指出,结果是否符合语法。你要尽可能准确的鉴定结果:定位错误在没有辨认出表达式的情况下。
其次,你的程序必须能够完成对输入多个字符串作为输入,不要忘记重新启动你的程序。
五、程序实现
六、程序代码
/*
不支持规则源文件中有空格
注意使用#表示空产生式使用$表示结束符#
四、开发过程
1)字符要求:
你的程序必须能够根据以下字符来处理语法:
-终Байду номын сангаас字符:字母,数字,符号例如“+”,“—”,…;
-非终端字母表中的大写字母。
符号“=”,“|”和“#”(替换“ε”,因为它更容易输入到文本文件)被保留用于语法的描述中,因此不能被用作终端。
2)初始状态
您的程序通过读取一个文件中的“文本”格式开始。
这个文件的结构可以随意构建,不做要求,但建议做成简单的<simple>。
例如,程序描述以下语句:
E = E + T |T
T = T * F |F
F =(E)| 0 |1
在这种情况,我们可以很容易确定E,T和F是非终端,而符号“(”,“)”,“*”和“+”和数字“0”和“1”是在终端。
第一个非终端(第一衍生物)被认为是语法的公理。
构造一程序,实现教材P.78的FIRST(X)集合的构造算法。对任一给定的文法G,程序输出所有非终结符P的FIRST(P)。构造一程序,实现教材P.78的FIRST(X)集合的构造算法。对任一给定的文法G,程序输出所有非终结符P的FIRST(P)。在此基础上,构造一程序,实现教材P.79的FOLLOW(A)集合的构造算法。对任一给定的文法G,程序输出所有非终结符A的FOLLOW (A)。对于给定的一个LL(1)文法,假定所有非终结符号P的集合FIRST(P)和集合FOLLOW(P)都已知,构造其预测分析表(实现教材P.79给出的预测分析表构造算法)。对教材P.79给出的例4.7构造出预测分析表。程序显示输出预测分析表或输出到指定文件中。
{
for(int x=0;x<firstnumber;x++)
{
if(first[x]==q)return;
}
first[firstnumber]=q;
firstnumber++;
}
void add_follow(char q)//向follow添加元素
{
for(int x=0;x<follownumber;x++)
{
if(q>=funnumber||q<0)
{
cout<<"error wrong delete fun in sign!";
return;
}
for(int x=q;x<funnumber-1;x++)
fun[x]=fun[x+1];
funnumber--;
}
void pop_first(char q)//从first集删除某一节点
{
if(follow[x]==q)return;
}
follow[follownumber]=q;
follownumber++;
}
int identity; //符号属性0为非终结符1为终结符
char id; //符号
string fun[max];//符号产生规则
int funnumber; //符号产生规则数量
{
for(int z=0;z<unendsign[x].fun[y].length();z++)
{
char kk=unendsign[x].fun[y][z];
if(int(kk)>=65&&int(kk)<=90)continue; //A到Z为非终结符
else addendsign(kk);
}
}
sign endsign[max];//终结点集合
int endsignnumber=0;
void readsource(const char*sf) //读取源文件ma_grammaira.txt
{
int x;
unendsignnumber=0;
endsignnumber=0;
ifstream ifs;
id=fu; //设置非终结符符号
funnumber=0;//设置符号规则数为0
firstnumber=0;
follownumber=0;
}
}
void add(string sl)//添加产生规则
{
fun[funnumber]=sl;
funnumber++;
}
void pop(int q)//删除某一规则
}
endsign[endsignnumber].id=sg;
endsign[endsignnumber].identity=1;
endsignnumber++;
}
void dealend()//由非终结符产生式得到终结符
{
for(int x=0;x<unendsignnumber;x++)
{
for(int y=0;y<unendsign[x].funnumber;y++)
相关主题