当前位置:首页 » 编程软件 » 编译原理ll0文法

编译原理ll0文法

发布时间: 2022-05-26 17:43:03

编译原理文法分析

改完了,能文法分析出来了!!
大概 跟你说下 你的错误吧:
出错地点:
1.声明的stack[50]没有初始化;
2.stack的入栈是错误的,按照你的方式,如果原来有TM,再加入T->FN,则M就被挤出来了.(这里很关键,你对照我给你改的再看看)
3.s指针在你入栈操作以后并没有指向栈顶,而是保持了不变,这肯定是有问题的.(传入push函数的时候直接传参数s就好了.)
4.if(*s==*p){***}else{}的else的右括号管辖的范围 有错误

不嫌弃的话,可以去http://blog.csdn.net/fangguanya,我的BLOG,不怎么充实,呵呵,有这个程序的运行结果的. 谢谢 呵呵.
总之你对照我给你改的再看看吧. 我把我的测试输出 也给保留了.你好对照点.
(PS.我用的vs2005,用的时候你改下头申明,其他一样)

// grammar.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include<iostream>
using namespace std;

char * spush(char *stack,char *pt);
bool analyse(char *p);

void main()
{
//将分析串存放在二维数组中
char input[5][10]={"i+i#",
"i*(i+i)#",
"i*i+i#",
"i+*#",
"+i*i#"};
bool flag; //定义一个布尔型的标记量
for(int h=0;h<5;++h)
{
flag=analyse(input[h]);
if(flag) cout<<"恭喜你!"<<input[h]<<"语法分析成功,合法!"<<endl;
else cout<<"对不起!"<<input[h]<<"语法分析失败,非法!"<<endl;
}
int aaa;
cin>>aaa;
}
//定义各一将串逆序入栈的函数
char * spush(char *stack,char *pt)
{
int l=0;
//while循环的作用是将指针指向字符串的末尾,然后再由后向前入栈,从而实现逆序
while(*pt!='\0')
{
pt++;
l++;
}

if (*stack == '#')
{
stack++;
}
while(l)
{
pt--;
char cTempIntoStack = (*pt);
*stack=cTempIntoStack;
stack++;
l--;
}
stack--; //由于前面向前加了一位,要返回
////////////////
return stack;
///////////////////////////////////

}

/*LL(1)分析表
i + * ( ) #
E TM +TM
F i (E)
M TM e e
N e *FN e e
T FN FN
*/

//分析函数
bool analyse(char *p){
char analyseTable[5][6][4]={
"TM", "", "", "TM", "", "",
"i", "", "", "(E)", "", "",
"", "+TM", "", "", "e", "e",
"", "e", "*FN", "", "e", "e",
"FN", "", "", "TN", "", ""
};
char *stack = new char[50]; //定义一个栈空间
for (int iStack = 0;iStack<50 ;iStack++)
{
stack[iStack] = 0;
}
char *s=stack; //用指针*s指向栈的起始地址
*s='#'; //将“#”入栈
s++; //指针加1
*s='E'; //将“E”入栈
//下面的while循环实现字符串的词法分析操作

int count = 0;

while(*s!='#' || *p!='#'){
count++;
char * temp = s;
cout<<"NO."<<count<<endl;
cout<<"STACK"<<endl;
while (*temp != '#')
{
cout<<*temp<<" ";
temp--;
}
cout<<endl;

int x,y;
//若果栈顶数据和分析串的字符匹配,则将符号栈的栈顶数据出栈(即将栈顶指针减1)
if(*s==*p){
cout<<"Before :"<<*s<<endl;
s--;
p++;
cout<<"After :"<<*s<<endl;
}
//当符号栈和分析串的字符不匹配时,查分析表
else {
switch(*s){
case 'E':x=0;break;
case 'F':x=1;break;
case 'M':x=2;break;
case 'N':x=3;break;
case 'T':x=4;break;
default:return false;
}
switch(*p){
case 'i':y=0;break;
case '+':y=1;break;
case '*':y=2;break;
case '(':y=3;break;
case ')':y=4;break;
case '#':y=5;break;
default:return false;
}
//若果对应的为空,则分析串非法,退出
if(analyseTable[x][y][0]=='\0') return false;
//若查表所对应的为'e',则将符号栈的栈顶数据出栈
else if(analyseTable[x][y][0]=='e') s--;
//其它,这时将查表所得的项逆序入符号栈
else {
s=spush(s,analyseTable[x][y]);
}
}
}
return true; //分析成功,返回
}

㈡ 编译原理的LL(1)文法是什么意思

L表明自顶向下分析是从左向右扫描输入串,第2个L表明分析过程中将用最左到推倒,1表明只需向右看一个符号便可决定如何推倒即选择哪个产生式(规则)进行推导,类似也可以有LL(k)文法,也就是需要向前查看k个符号才能确定选用哪个产生式、、

㈢ 编译原理 对一个文法进行改写,然后判断改写后的文法是不是LL(1)文法,请问改写方式的不同是否影响结果

楼上的答案是错误的。对同一种文法,可能同时存在两种改写方法,其中一种使改写后的新文法为LL(1)文法,而另外一种使改写后的新文法不为LL(1)文法。

㈣ 编译原理的文法是什么

文法是描述语言规则的形式规则。实际上就是用一个四元组G=(VT,VN,S,P)定义的一个推理方式。其中VT是终结符,VN是非终结符,S是开始符号,P是一组产生规则。

㈤ 编译原理的LL(1)文法是什么意思

1.文法不含左递归,没有公共左因子
2.对于文法中的每个非终结符A的产生式的候选首符集两两不相交。
3.对于文法中的每个非终结符A,它存在某个候选首符集包括ε,则FIRST(A)∩FOLLOW(A)=空
满足以上条件的文法为LL(1)文法

㈥ 编译原理中,LR(0)文法的项目集规范族的I0,I1,I2,I3…………是怎么求的~

先举个例子:

}

将其命名为I1。

其他可类似推出。

㈦ 编译原理全部的名词解释

书上有别那么懒!。。。。
编译过程的六个阶段:词法分析,语法分析,语义分析,中间代码生成,代码优化,目标代码生成
解释程序:把某种语言的源程序转换成等价的另一种语言程序——目标语言程序,然后再执行目标程序。解释方式是接受某高级语言的一个语句输入,进行解释并控制计算机执行,马上得到这句的执行结果,然后再接受下一句。
编译程序:就是指这样一种程序,通过它能够将用高级语言编写的源程序转换成与之在逻辑上等价的低级语言形式的目标程序(机器语言程序或汇编语言程序)。
解释程序和编译程序的根本区别:是否生成目标代码
句子的二义性(这里的二义性是指语法结构上的。):文法G[S]的一个句子如果能找到两种不同的最左推导(或最右推导),或者存在两棵不同的语法树,则称这个句子是二义性的。
文法的二义性:一个文法如果包含二义性的句子,则这个文法是二义文法,否则是无二义文法。
LL(1)的含义:(LL(1)文法是无二义的; LL(1)文法不含左递归)
第1个L:从左到右扫描输入串 第2个L:生成的是最左推导
1 :向右看1个输入符号便可决定选择哪个产生式
某些非LL(1)文法到LL(1)文法的等价变换: 1. 提取公因子 2. 消除左递归
文法符号的属性:单词的含义,即与文法符号相关的一些信息。如,类型、值、存储地址等。
一个属性文法(attribute grammar)是一个三元组A=(G, V, F)
G:上下文无关文法。
V:属性的有穷集。每个属性与文法的一个终结符或非终结符相连。属性与变量一样,可以进行计算和传递。
F:关于属性的断言或谓词(一组属性的计算规则)的有穷集。断言或语义规则与一个产生式相联,只引用该产生式左端或右端的终结符或非终结符相联的属性。
综合属性:若产生式左部的单非终结符A的属性值由右部各非终结符的属性值决定,则A的属性称为综合属
继承属性:若产生式右部符号B的属性值是根据左部非终结符的属性值或者右部其它符号的属性值决定的,则B的属性为继承属性。
(1)非终结符既可有综合属性也可有继承属性,但文法开始符号没有继承属性。
(2) 终结符只有综合属性,没有继承属性,它们由词法程序提供。
在计算时: 综合属性沿属性语法树向上传递;继承属性沿属性语法树向下传递。
语法制导翻译:是指在语法分析过程中,完成附加在所使用的产生式上的语义规则描述的动作。
语法制导翻译实现:对单词符号串进行语法分析,构造语法分析树,然后根据需要构造属性依赖图,遍历语法树并在语法树的各结点处按语义规则进行计算。
中间代码(中间语言)
1、是复杂性介于源程序语言和机器语言的一种表示形式。
2、一般,快速编译程序直接生成目标代码。
3、为了使编译程序结构在逻辑上更为简单明确,常采用中间代码,这样可以将与机器相关的某些实现细节置于代码生成阶段仔细处理,并且可以在中间代码一级进行优化工作,使得代码优化比较容易实现。
何谓中间代码:源程序的一种内部表示,不依赖目标机的结构,易于代码的机械生成。
为何要转换成中间代码:(1)逻辑结构清楚;利于不同目标机上实现同一种语言。
(2)便于移植,便于修改,便于进行与机器无关的优化。
中间代码的几种形式:逆波兰记号 ,三元式和树形表示 ,四元式
符号表的一般形式:一张符号表的的组成包括两项,即名字栏和信息栏。
信息栏包含许多子栏和标志位,用来记录相应名字和种种不同属性,名字栏也称主栏。主栏的内容称为关键字(key word)。
符号表的功能:(1)收集符号属性 (2) 上下文语义的合法性检查的依据: 检查标识符属性在上下文中的一致性和合法性。(3)作为目标代码生成阶段地址分配的依据
符号的主要属性及作用:
1. 符号名 2. 符号的类型 (整型、实型、字符串型等))3. 符号的存储类别(公共、私有)
4. 符号的作用域及可视性 (全局、局部) 5. 符号变量的存储分配信息 (静态存储区、动态存储区)
存储分配方案策略:静态存储分配;动态存储分配:栈式、 堆式。
静态存储分配
1、基本策略
在编译时就安排好目标程序运行时的全部数据空间,并能确定每个数据项的单元地址。
2、适用的分配对象:子程序的目标代码段;全局数据目标(全局变量)
3、静态存储分配的要求:不允许递归调用,不含有可变数组。
FORTRAN程序是段结构,不允许递归,数据名大小、性质固定。 是典型的静态分配
动态存储分配
1、如果一个程序设计语言允许递归过程、可变数组或允许用户自由申请和释放空间,那么,就需要采用动态存储管理技术。
2、两种动态存储分配方式:栈式,堆式
栈式动态存储分配
分配策略:将整个程序的数据空间设计为一个栈。
【例】在具有递归结构的语言程序中,每当调用一个过程时,它所需的数据空间就分配在栈顶,每当过程工作结束时就释放这部分空间。
过程所需的数据空间包括两部分
一部分是生存期在本过程这次活动中的数据对象。如局部变量、参数单元、临时变量等;
另一部分则是用以管理过程活动的记录信息(连接数据)。
活动记录(AR)
一个过程的一次执行所需要的信息使用一个连续的存储区来管理,这个区 (块)叫做一个活动记录。
构成
1、临时工作单元;2、局部变量;3、机器状态信息;4、存取链;
5、控制链;6、实参;7、返回地址
什么是代码优化
所谓优化,就是对代码进行等价变换,使得变换后的代码运行结果与变换前代码运行结果相同,而运行速度加快或占用存储空间减少。
优化原则:等价原则:经过优化后不应改变程序运行的结果。
有效原则:使优化后所产生的目标代码运行时间较短,占用的存储空间较小。
合算原则:以尽可能低的代价取得较好的优化效果。
常见的优化技术
(1) 删除多余运算(删除公共子表达式) (2) 代码外提 +删除归纳变量+ (3)强度削弱; (4)变换循环控制条件 (5)合并已知量与复写传播 (6)删除无用赋值
基本块定义
程序中只有一个入口和一个出口的一段顺序执行的语句序列,称为程序的一个基本块。

给我分数啊。。。

㈧ 关于LL(1)文法的编译原理题目

判断是不是LL(1),首先看候选式的首字符有没有相同的,第二判断首字符迭代进去是否会构成左递归。
如果首字符不相同,也没用左递归就说明此文法是LL(1)
M→MaH|H
H→(M)|b(M)|b
第一个产生式中存在左递归:M->MaH
第二个产生式中存在首字符相同:H->b(M) ,
H->b
怎么改呢?
对第一个产生式,消除左递归就是要变成右递归,把右边剩下的符号提到前面:
M->aHM'

M'->aHM'
对第二个产生式,提出公共因子
H->b( (M)|ε)
=>
H->bH'

H'->(M)|ε

㈨ 编译原理中的语法和文法一样吗

编译原理中的语法和文法是不一样的,但却融会贯通。
在计算机科学中,文法是编译原理的基础,是描述一门程序设计语言和实现其编译器的方法。
文法分成四种类型,即0型、1型、2型和3型。这几类文法的差别在于对产生式施加不同的限制。
形式语言,这种理论对计算机科学有着深刻的影响,特别是对程序设计语言的设计、编译方法和计算复杂性等方面更有重大的作用。
多数程序设计语言的单词的语法都能用正规文法或3型文法(3型文法G=(VN,VT,P,S)的P中的规则有两种形式:一种是前面定义的形式,即:A→aB或A→a其中A,B∈VN ,a∈VT*,另一种形式是:A→Ba或A→a,前者称为右线性文法,后者称为左线性文法。正规文法所描述的是VT*上的正规集)来描述。
四个文法类的定义是逐渐增加限制的,因此每一种正规文法都是上下文无关的,每一种上下文无关文法都是上下文有关的,而每一种上下文有关文法都是0型文法。称0型文法产生的语言为0型语言。上下文有关文法、上下文无关文法和正规文法产生的语言分别称为上下文有关语言、上下文无关语言和正规语言。

㈩ 编译原理中的语法和文法一样吗

编译原理中的语法和文法是不一样的,但却融会贯通。
在计算机科学中,文法是编译原理的基础,是描述一门程序设计语言和实现其编译器的方法。
文法分成四种类型,即0型、1型、2型和3型。这几类文法的差别在于对产生式施加不同的限制。
形式语言,这种理论对计算机科学有着深刻的影响,特别是对程序设计语言的设计、编译方法和计算复杂性等方面更有重大的作用。
多数程序设计语言的单词的语法都能用正规文法或3型文法(3型文法G=(VN,VT,P,S)的P中的规则有两种形式:一种是前面定义的形式,即:A→aB或A→a其中A,B∈VN ,a∈VT*,另一种形式是:A→Ba或A→a,前者称为右线性文法,后者称为左线性文法。正规文法所描述的是VT*上的正规集)来描述。
四个文法类的定义是逐渐增加限制的,因此每一种正规文法都是上下文无关的,每一种上下文无关文法都是上下文有关的,而每一种上下文有关文法都是0型文法。称0型文法产生的语言为0型语言。上下文有关文法、上下文无关文法和正规文法产生的语言分别称为上下文有关语言、上下文无关语言和正规语言。

热点内容
java返回this 发布:2025-10-20 08:28:16 浏览:705
制作脚本网站 发布:2025-10-20 08:17:34 浏览:968
python中的init方法 发布:2025-10-20 08:17:33 浏览:676
图案密码什么意思 发布:2025-10-20 08:16:56 浏览:828
怎么清理微信视频缓存 发布:2025-10-20 08:12:37 浏览:737
c语言编译器怎么看执行过程 发布:2025-10-20 08:00:32 浏览:1076
邮箱如何填写发信服务器 发布:2025-10-20 07:45:27 浏览:308
shell脚本入门案例 发布:2025-10-20 07:44:45 浏览:188
怎么上传照片浏览上传 发布:2025-10-20 07:44:03 浏览:875
python股票数据获取 发布:2025-10-20 07:39:44 浏览:829