编译原理LR0分析实验报告
A. 编译原理课程设计:证明一个文法是LR(0)文法 求大神帮忙啊
这个很简单呀,如果一个项目集中不存在既含移进项目又含规约项目或者含有多个规约项目的情况,则该文发是一个LR(0)文法。多以就是要先构造你面临的项目的项目集。然后逐个检查项目集中的各个项目。有不会的继续追问。
B. 编译原理lr0和slr1的区别
语法分析有自上而下和自下而上两种分析方法其中自上而下:递归下降,LL(1)自下而上:LR(0),SLR(1),LR(1),LALR(1)
LR需要构造一张LR分析表,此表用于当面临输入字符时,将它移进,规约(即自下而上分析思想),接受还是出错。
LR(0)找出句柄前缀,构造分析表,然后根据输入符号进行规约。 SLR(1)使用LR(0)时若有冲突,不知道规约,移进,活移进哪一个,所以需要向前搜索,则只把有问题的地方向前搜索一次。 LR(1)1.在每个项目中增加搜索符。2.举个列子如有A->α.Bβ,则还需将B的规则也加入。 LALR(1)就是假如两个产生式集相同则将它们合并为一个,几合并同心集。
C. 编译原理中,LR(0)文法的项目集规范族的I0,I1,I2,I3…………是怎么求的~
先举个例子:
}
将其命名为I1。
其他可类似推出。
D. 编译原理——LR分析表
自底向上的语法分析
LR分析表的结构如上,其分为两个部分 Action Goto
两个参数状态i,终结符号a(s(i)代表第i个状态,r(i)代表第i条表达式)
Goto[i,A]=j
文法
容易得知这个文法可以推出 0 1 00 01 等的字符串。因为它是 左递归 。不适用于 LL 文法分析,只能使用 LR 分析。
因为本题入口有两个—— S → L·L S → L ,所以需要构造额外的产生式 S'->S
2.1 第一次遍历
我们从 [S -> . L·L] 开始,构造这个状态的闭包,也就是加上所有能从这个产生式推出的表项。
首先,判断 . 后面是否为 非终结符号A 。如果是,那我们就得找所有由 A-> 推出的产生式,并将它们添加进入 闭包 里(也就是State包里)。循环做即可。
因此我们可以得到 State 0 有
下一步,就是我的 . 往下一位移动。对每个符号X后有个 . 的项,都可以从 State 0 过渡到其他状态。
由以上6条式子可以得知下一位符号可以是 S L B 0 1 。所以自然可以得到5个状态。
State 1 是由 State 0 通过 S 转移到这里的,所以我们找出所有 State 0 中在 S 前有 . 的项。
此状态作为结束状态 Accept ,不需要继续状态转移了。
State 2 是由 State 0 通过 L 转移到这里的,所以我们找出所有 State 0 中在 L 前有 . 的项。
S -> . L·L S -> . L L -> . LB
有3条式子,现在我们将 . 向后推一格,就得到 State 1 的项了。
但是 . 之后的符号分别是 · $ B , B 为非终结符号,我们得包含 B -> 的项
State 3 是由 State 0 通过 B 转移到这里的,所以我们找出所有 State 0 中在 B 前有 . 的项。
因为 . 后没有其他符号了,因此这个状态不需要继续转移了。
State 4 是由 State 0 通过 0 转移到这里的,所以我们找出所有 State 0 中在 0 前有 . 的项。
因为 . 后没有其他符号了,因此这个状态不需要继续转移了。
很简单,同样的道理找 State 5
State 5 是由 State 0 通过 1 转移到这里的,所以我们找出所有 State 0 中在 1 前有 . 的项。
因为 . 后没有其他符号了,因此这个状态不需要继续转移了。
好的,现在我们第一次遍历完成。
2.2 第二次遍历
第二次遍历自然从 State 2 开始。
我们回到 State2 ,可以看出 . 之后的符号有 · B 0 1 。
State 6 是由 State 2 通过 · 转移到这里的,所以我们找出所有 State 2 中在 · 前有 . 的项。
S -> L. ·L 只有1条,我们往后移发现 L 又为非终结符号,参考 State 0 做的操作,我们得找出所有的式子。
共有5条式子,共同组成 State 6 ,由上面的式子可以看出我们还得继续下一次遍历。先不管着,我们进行下一次状态查找。
State 7 是由 State 2 通过 B 转移到这里的,所以我们找出所有 State 2 中在 B 前有 . 的项。
L -> L. B 也是只有1条,我们往后移发现没有非终结符号了,那就不需要再继续添加其他式子了。
这个状态也不需要继续进行转移了。
接下来很关键,因为我们通过 State2 的 . 后的符号找出了 State 6 State 7 ,接下来还差符号 0 1 ,那么是否像之前一样按例添加状态呢, 答案是不是的 ,因为我们发现通过 0 1 找到的闭包集分别是 B -> 0 B -> 1 ,这与我们的之前的 State 4 State 5 相同。所以我们得将其整合起来,相当于 State 2 通过 0 1 符号找到了 State 4 State 5 状态。
2.3 第三次遍历
回头看第二次遍历,可以看出只有 State 6 可以进行状态转移了。
那么就将 State 6 作为第三次遍历的源头,可以看出 . 之后的符号有 L B 0 1 。
State 8 是由 State 6 通过 L 转移到这里的,所以我们找出所有 State 6 在 L 前有 . 的项。
S -> L· .L L -> . LB 有两条式子,往后移发现有非终结符号 B ,所以经过整合可以得到
可以看出 . 的后面还有一个符号,所以这里我们还得再进行一次遍历。
接下来,又是遇到重复的包的情况,可以看出我们由 State 6 通过 B 0 1 得到的闭包分别是 L->B B->0 B->1 ,很明显,这分别对应于 State 3 State 4 State 5 。
第三次遍历也就结束了。
2.4 第四次遍历
回看第三次遍历,可以看出只有 State 8 可以进行状态转移,其 . 之后的符号分别是 B 0 1 。
诶,感觉很熟悉,就是上面几行刚说的情况,也就是说通过这三个符号找到的闭包是我们之前遇到的状态,分别是 State 3 State 4 State 5 。
做到这里,我们发现我们已经全部遍历完毕!
总共有8个状态,通过以上流程做成个图是什么样子的?来看看!
这么一看就很清晰明了了,我们就可以通过这个图做出我们的 LR分析表
其实就是我们之前呈现的表
在状态 I2 和 I8 中,既有 移入 项目,也有 规约 项目,存在 移入 - 规约的冲突 ,所以不是 LR(0) 文法,但是因为 FOLLOW(S) ∩ {0, 1} = ∅,所以可以用 FOLLOW 集解决冲突,所以该文法是 SLR(1) 文法。
上表我们发现还有 r1,r2,r3 等。这个其实就是代表状态停止转移时为 第几条表达式 ,r3代表第三条表达式 L -> LB 。
当我们构建了表之后,我们如何运用起来呢?
下面我们通过一个例子来说明
以上字符串是如何被SLR分析器识别的呢?
E. 编译原理 LR(0) 项目集规范族怎么构建。 书上的实在是看不懂那些I0、I1、I2的步骤。求一个
LR分析法是一种自下而上进行规范归约的语法分析法,L指从左到右扫描输入符号串,R是指构造最右推导的逆过程。对大多数无二义性上下文无关文法描述的语言都可用它进行有效的分析。主要分析器有LR(0),SLR(1),LR(1),LALR(1):
LR(0):在分析的每一步,只需根据当前栈顶状态而不必向前查看输入符号就能确定应采取的分析动作。所能分析的LR(0)文法要求文法的每一个LR(0)项目集中都不含冲突项目。
示例文法:
0 S’ -> S
1 S -> A
2 S -> B
3 A -> aAb
4 A -> c
5 B -> aBb
6 B -> d
F. 编译原理用C语言实现基于LR(1)或SLR(1)语法分析程序代码,最好还有报告,急。。。
这个是精简的语法分析程序,如果符合的话,hi我
给你实验报告
#include <stdio.h>
#include<dos.h>
#include<stdlib.h>
#include<string.h>
char a[50] ,b[50];
char ch;
int n1,i1=0,n=5;
int E();int T();int E1();int T1();int F();
void main() /*递归分析*/
{
int f,j=0;
printf("请输入字符串(长度<50,以#号结束)\n");
do{
scanf("%c",&ch);
a[j]=ch;
j++;
}while(ch!='#');
n1=j;
ch=b[0]=a[0];
f=E();
if (f==0) return;
if (ch=='#') printf("accept\n");
else printf("error\n");
}
int E() // E→TE'
{ int f,t;
f=T();
if (f==0) return(0);
t=E1();
if (t==0) return(0);
else return(1);
}
int T() // T→FT'
{ int f,t;
f=F();
if (f==0) return(0);
t=T1();
if (t==0) return(0);
else return(1);
}
int E1()/*E’*/ // E'→+TE'
{ int f;
if(ch=='+') {
b[i1]=ch;
ch=a[++i1];
f=T();
if (f==0) return(0);
E1();
return(1);
}
return(1);
}
int T1()/*T’*/ // T'→*FT'
{
int f,t;
if(ch=='*') {
b[i1]=ch;
ch=a[++i1];
f=F();
if (f==0) return(0);
t=T1();
if (t==0) return(0);
else return(1);}
a[i1]=ch;
return(1);
}
int F() // F→(E)
{ int f;
if(ch=='(') {
b[i1]=ch;
ch=a[++i1];
f=E();
if (f==0) return(0);
if(ch==')') {
b[i1]=ch;
ch=a[++i1];
}
else {
printf("error\n");
return(0);
}
}
else if(ch=='i') {
b[i1]=ch;
ch=a[++i1];
}
else {printf("error\n");return(0);}
return(1);
}
G. 编译原理中LR(0)分析表中的r1、r2等等 是怎么规则填写的s1、s2…我明白了,但r规则看不懂
r表示规约 r5表示的就是用第五条产生式进行规约的 至于r填在哪里吗 我就举个例子吧 比如I8 进行规约 就会在H的所有fellow集合上填上r5 希望你能看懂。。。。
H. 编译原理LR分析法中的SLR(1)分析表和LR分析过程、语法树怎么求
第二题和第三题拿去,刚做的:
由B->cAa|c就可知该文法不是LR(0)文法了
I. 编译原理LR分析题
{1}. (1)E →E+T →(2) T+T →(4) F+T →(6) 8+T →(3)8+T*F →(4)8+F*F→(6)8+5*F
→(4)8+5*2
{2}.不知道为什么,是不是我忘了,这个怎么能出来 ‘ — ’的?