编译原理LL(1)文法

编译原理LL1文法

在上次介绍了词法分析之后,这次介绍如何将一个普通文法,消除左递归,提取左因子,从而得到LL1文法。先贴出最终的效果图
这里写图片描述

这里给出具体的实现要求

1、将一个可转换非LL(1)文法转换为LL(1)文法,要经过两个阶段,1)消除文法左递归,2)提取左因子,消除回溯。
2、提取文法左因子算法:
1)对文法G的所有非终结符进行排序
2)按上述顺序对每一个非终结符Pi依次执行:
for( j=1; j< i-1;j++)
将Pj代入Pi的产生式(若可代入的话);
消除关于Pi的直接左递归:
Pi -> Piα|β ,其中β不以Pi开头,则修改产生式为:
Pi —> βPi′
Pi′—> αPi′|ε
3)化简上述所得文法。
3、提取左因子的算法:
A —> δβ1|δβ2|…|δβn|γ1|γ2|…|γm
(其中,每个γ不以δ开头)
那么,可以把这些产生式改写成
A —> δA′|γ1| γ2…|γm
A′—>β1|β2|…|βn
4、利用上述算法,实现构造一个LL(1)文法:
1)从文本文件g.txt中读入文法
2)设计函数remove_left_recursion()和remove_left_gene()实现消除左递归和提取左因子算法,分别对文法进行操作,消除文法中的左递归和提出左因子;
3)整理得到的新文法;
4)在一个新的文本文件newg.txt输出文法,文法输出按照一个非终结符号一行,开始符号引出的产生式写在第一行,同一个非终结符号的候选式用“|”分隔的方式输出。

输入数据:
编辑一个文本文文件g.txt,在文件中输入如下内容:
S->Qc|c|cab;
Q->Rb|b;
R->Sa|a;

正确结果:
本实验的输出结果是不唯一的,根据消除左递归是选择非终结符号的顺序不同,或选择新的非终结符号的不同,可能会得到不同的结果,下面只是可能的一个结果:
S- >Qc|cT;
T->@|ab; //由于无法输出ε,用@代替
Q->Rb|b;
R->bcaU|caU|cabaU|aU;
U->bcaU|@;

下面以C++代码实现

///
/Author:Jameslong
/Date:4/20/2017
//
#include<iostream>
#include <fstream>
#include<string>
#include<list>
using namespace std;

list<string> vf;
list<list<string>> ListVf;

list<list<string>>::iterator it_i;
list<list<string>>::iterator it_j;
list<string>::iterator it_k;
list<string>::iterator it_m;

char ch;//每个要比对的字符
string str = "";//每个要分析的单词
ifstream in;//文件输入流
char buf[1024]; //缓存
char
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值