㈠ 编译原理follow集怎么求例:s->xSNy|Nx;N->zN|空 答案:follow(S)={y,z,#},follw(N)={x,y}什么时候有#
求某一非终结符的follow集,主要看产生式右端(含有该非终结符的右端)。
因为S是该文法的开始符,所以#在follow(S)中。在产生式S->xSNy的右端,S的后跟符号是first(Ny),即z和y。这样follow(S)={y,z,#}
求follw(N)时,看产生式S->xSNy和S->Nx,在它们的右端都含有N,根据S->xSNy可知,y在follw(N)中;根据S->Nx可知,x在follw(N)中;这样follw(N)={x,y}
虽然产生式N->zN的右端也含有N,但根据follow集合的定义,将follw(N)加入follw(N)中没有意义,所以不用计算。
对于不是开始符的其他非终结符,其follow集合有没有#,要看产生式的结构(产生式右端)。
㈡ 编译原理这个符号表示什么 如图~~~~
剪头上加一个星号:S-*->aPb
表示从S可以推出含有非终结符P的形如aPb的句型。
剪头上加一个加号:S-+->a
表示从S可以推出终结符a。
㈢ 关于编译原理first follow 和select
首先要明白这三个集的作用和用途,知道了他们是用来做什么的之后,理解起来就简单一些
First(A)集的作用是标示在替换非终结符A的时候,替换后的文法的首字母集合,语法分析程序根据这个来判断给定的语言是否是合法的,是符合规则的。
Follow(A)的作用是标示那些可以出现在A之后的字符,语法分析程序根据这个,在A可以被替换为e(空)的时候来进行判断,看当前的文法是否是合法的。
这里简单说明下,比如A->b,A->e(空) 当给定的语言是 bXXXXX的时候,根据第一句文法就可以判定句子合法,但是如果给的语言是cXXXXX的时候,因为A->可以替换为空,这时候就需要一句A的follow集来进行判断,若A的follow集里面含有c 则语言是合法的
Select集的作用是将first集和follow集进行合并,如果两个文法的左端都是A,若他们的select集交集为空,表明他们是两个无关的,不会产生不确定性的文法,反之,则表明文法不是LL(1)文法
计算的公式很繁杂,理解了意思之后,看就能看出来。。。。
㈣ 一个编译原理的问题
First(α) 是符号串α的开始符号集合。
也就是说,用推导的方法对α进行推导,一次次地使用产生式,用产生式右部的符号串替换一个非终结符,所有那些可能出现在第一个符号位置的终结符,就构成了开始符号集。
比如,在C语言中,对于符号串“语句”来说,标识符(赋值语句)、if(条件语句)、printf(输出函数)这些单词(终结符)都是它开始符号集合中的元素,而+(加号)、}(右花括号)不可能出现在“语句”的开头,所以不是它的开始符号集合中的元素。
Follow(A)是非终结符A的后跟符号集合。
它是指在所有可能的句型中,一切可能出现在非终结符A后面的一个终结符。
这里要特别注意是在“句型”中。
你可以自己举例,比如分析一下C语言中“表达式”后面可能跟哪些单词,它们就是非终结符“表达式”后跟符号集合中的元素。
你说的这两个集合的交集问题不存在。
因为它们针对的是不同类型的对象(一个是符号串,另一个是某个非终结符)。
实际上,在选择集合问题中,考虑的不是它们的交集,而是一个产生式右部符号串的First集跟这个产生式左端非终结符的Follow集的并集。
考虑交集的,发生在相同左部的不同产生式的选择集合之间。
㈤ 编译原理的,要详细的
^\d+\.\d+E[-+]?\d+$
㈥ 编译原理 FOLLOW集
因为有:
T→ F T’
T’→ *F T’
所以FIRST(T')是FOLLOW(F)的子集。所以 * 是FOLLOW(F)中的元素。
因为有:
T→ F T’
T’→ε
所以FOLLOW(T)是FOLLOW(F)的子集。
因为有:
E’→ +TE’
所以FIRST(E‘)是FOLLOW(T)中的子集。所以FIRST(E‘)是FOLLOW(F) 中的子集。
因为有:
E’→ +TE’
所以+是FIRST(E’)中的元素,所以+是FOLLOW(F)中的元素。
因为有:
E’→ ε
E → TE’
所以有:
FOLLOW(E)是FOLLOW(T)子集。前面有所以FOLLOW(T)是FOLLOW(F)的子集。所以有
FOLLOW(E)是FOLLOW(F)的子集,
由F → (E)|id
知 ) 是FOLLOW(E)的元素。所以 ) 是FOLLOW (F)的元素。
因为E是开始符号,所以有 $ 是FOLLOW(E)中的元素,所以 $ 是FOLLOW(F)中的元素。
综上所述:
FOLLOW(F)= {*,+,),$}
㈦ 急求!怎么求编译原理的FOLLOW集合在线等~
follow集合是针对非终结符而言的;follow(U)所表达的是句型中非终结符U的所有可能的后随终结符号的集合,特别注意一点:“#”是识别符号的后随附。
直接收取:形如“……Ua”的组合,直接把啊收入到follow(U)中
直接收取:形如“……UP……”的组合,(P是非终态符);把firth(P)除去ε直接收入到follow(U)中。
反复传递:形如“P-……U”的产生式,
follow(P)的全部内容传递到follow(U)中,或者说是P-……UB且first(B)包含ε,则把first(B)除去ε直接收入到follow(U)中,同时吧follow(P)的全部内容传送到follow(U)中...
㈧ 一道《编译原理》求follow集题目,在线等答案
哥们,你这个问题中的一个产生式E’→+TE’| e,应该是E->+TE’ |ε这样吧!否则不可能获得如此结果。
关于求follow集合,龙书中说得很清楚,依据三条规则即可:
1、任何FOLLOW(S)都包含输入终止符号,其中S是开始符号。
适用该条,因此FOLLOW(E’)中包含终止符号#。
2、如果存在产生式,A->αBβ,则将FIRST(β)中除ε以外的符号都放入FOLLOW(B)中。
该条不适用,因为在上述所有产生式中不存在形如E‘->αE’β这样的产生式。
3、如果存在产生式,A->αB,或A->αBβ,其中FIRST(β)中包含ε,则将FOLLOW(A)中的所有符号都放入FOLLOW(B)中。
适用该条,因为存在这样的产生式E->+TE’,使得FOLLOW(E’)=FOLLOW(E)成立。而FOLLOW(E)适用上述第二条,根据产生式F→(E)可求得为FOLLOW(E)={#,)}。
综上,FOLLOW(E’)=FOLLOW(E)={#,)}。
㈨ 编译原理中V*是什么意思
V是一个符号集合,假设V指的是三个符号a, b, c的集合,记为 V = {a, b, c }
V* 读作“V的闭包”,它的数学定义是V自身的任意多次自身连接(乘法)运算的积,也是一个集合。
也就是说,用V中的任意符号进行任意多次(包括0次)连接,得到的符号串,都是V*这个集合中的元素。
0次连接的结果是不含任何符号的空串,记为 ε
1次连接就是只有一个符号的符号串,比如,a,b, c
2次连接是两个符号构成的符号串,比如,aa, ab, ac, ba, bb, bc,等等
……
n次连接是一个长度为n、由a、b、c三个符号构成的符号串,比如abaacbbac……
因此,V*包含一切由a,b,c三个符号连接而成的、任意长度的符号串(以及空串ε)
㈩ 编译原理对符号表进行操作有哪些
//----------------------------符号表---------------------------------------
//预定义
struct snode;
struct stable;
//符号表结点
struct snode
{
string text; //符号名称
string type; //符号类型
union {int ival;double rval;}value; //值------------
int offset; //偏移量
snode *nextn; //指向下一个节点
stable *header; //指向下属符号表的表头
};
//符号表表头
struct stable
{
stable *previous; //指向先前创建的符号表表头
snode *firstnode; //指向第一个结点
stable *ifnoelements;//如果此表为空,则用它指向下一个表头
};
//当前表头
stable *currtab;
//建立新表,返回表头指针
//参数:当前的节点的表头
stable *mktable(stable *previous)
{
stable *newtable =new stable;
newtable->previous=previous;
newtable->ifnoelements=0;
newtable->firstnode=0;
if(previous->firstnode==0)
{
previous->ifnoelements=newtable;
}
else
{
snode* ininode=previous->firstnode;
while(ininode->nextn!=0)
{
ininode=ininode->nextn;
}
ininode->header=newtable;
}
currtab=newtable;
return newtable;
}
//在node指向的符号表中为text建立一个新表项,返回新建立的结点
//参数:node为当前的节点的表头,text名称,type类型,offset偏移
snode *enter(stable *table,string text,string type,int offset,double value)
{
//创建节点
snode *newnode = new snode;
newnode->text=text;
newnode->type=type;
newnode->offset=offset;
newnode->nextn=0;
newnode->header=0;
if(type=="int")
{
newnode->value.ival=value;
}
else if(type=="real")
{
newnode->value.rval=value;
}
//判断此表是否无元素
if(currtab->firstnode==0)
{
currtab->firstnode=newnode;
currtab->ifnoelements=0;
}
else
{
snode* addnode=currtab->firstnode;
while(addnode->nextn!=0)
{
addnode=addnode->nextn;
}
addnode->nextn=newnode;
}
return newnode;
}
//初始化符号表,返回表头节点
void inittab()
{
stable *initable = new stable;
initable->firstnode=0;
initable->previous=0;
initable->ifnoelements=0;
currtab=initable;
}
//查找指针,表示结果
snode *searchresult;
//查找变量,返回指向该变量的指针
//查找变量,返回指向该变量的指针
snode* search(string name)
{
//检查表是否空
bool isempty=true;
stable* checktab=currtab;
if(checktab->firstnode!=0)
{isempty=false;}
while(checktab->previous!=0)
{
if(checktab->firstnode!=0)
{isempty=false;}
checktab=checktab->previous;
}
if(checktab->firstnode!=0)
{isempty=false;}
if(isempty)
{
return 0;
}
snode* lastnode;
if(currtab->firstnode==0)
{
//移到非空的表头
stable* notnullhead=currtab;
while(notnullhead->firstnode==0)
{
notnullhead=notnullhead->previous;
}
snode* tmpnode=notnullhead->firstnode;
//移到最后的元素
while(tmpnode->nextn!=0)
{
tmpnode=tmpnode->nextn;
}
lastnode=tmpnode;
}
else
{
lastnode=currtab->firstnode;
while(lastnode->nextn!=0)
{
lastnode=lastnode->nextn;
}
}
//移到表头
stable* fronttab=currtab;
while(fronttab->previous!=0)
{
fronttab=fronttab->previous;
}
snode* nownode=0;
while(nownode!=lastnode)
{
while(fronttab->ifnoelements!=0)
{
fronttab=fronttab->ifnoelements;
}
nownode=fronttab->firstnode;
while(nownode->nextn!=0)
{
if(nownode->text==name)
{
searchresult=nownode;
return searchresult;
}
nownode=nownode->nextn;
}
if(nownode->text==name)
{
searchresult=nownode;
return searchresult;
}
fronttab=nownode->header;
}
if(nownode->text==name)
{
searchresult=nownode;
return searchresult;
}
return 0;
}
//消毁符号表
void delNode()
{
//more codes here......
}