《自己手动写一个编译器、连接器》一(4)

这一篇是补昨天的。 前天发了一个关于求FIRST,FOLLOW集的方法的特辑,但是还有一种没有提到,就是求SELECT集由于SELECT其实就是对前两个的运用,所以没有提到前面去说,这里先补充以下:求SELECT(A->a)就是相当于求FIRST(a)然后如果FIRST(a)中没有空字符串那么SELECT(A->a)=FIRST(a),如果有,那么SELECT(A->a)=FIRST(a)和FOLLOW(A)的并集。下面是一个语法定义举例和分析程序的关系:(我推测出来的,对于不准确的地方后期学习过程中会重新编辑改正)

<program>::=<statement>{statement}"#"

这里我们就知道开头是用了program这个函数,然后program这个函数里面至少有一个statement以"#"作为结尾,中间有0~n个statement

<statement>::=<expression>"\n"

然后statement这个函数里面有一个以"\n"作为结尾的expression

<expression>::=<multiplicative_expression>{"+"<multiplicative_expression>|"-"<multiplicative_expression>}然后这里我们的expression里面有一个以一个multiplicative_expression为开头,0~n个以"+"或"-"加multiplicative_expression为结尾的式子。。。

类似分析所以得出来的递归程序大概就是:

<program>::=<statement>{statement}"#"

while(token!='#')

statement();

<statement>::=<expression>"\n"

if(token!='\n')

expression();

<expression>::=<multiplicative_expression>{"+"<multiplicative_expression>|"-"<multiplicative_expression>}

multiplicative_expression();

while(token=='+'||token=='-')

{

get_token(); //取符号

multiplicative_expression();

}

后面的就不推下去了,其实大同小异。

最后来说一下特殊情况:

如果一个文法中有左递归:A->Ab(这个就是左递归),其中A->a,a,b中有ε、a中没有那么这个时候直接改为:A->bA1,A1->aA1|ε

左公共因子:A->ab|ac这个时候其实等价于A->a(b|c)那么再转换以下就有:A->aA1A1->b|c

为什么要转换?

因为我们写的都是自定向下的分析法,这个方法要求文法必须为LL(1)此时如果出现上面的情况则不是LL(1)文法,所以要进行转换



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值