(编译原理)求LL1语法分析中的FIRST集、FOLLOW集和SELECT集

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/destiny1507/article/details/86758588
编译原理的语法分析分为两大类:自顶向下和自底向上

语法分析
对于LL1分析:
LL1分析
感觉LL1分析的重点在于构造预测分析表(废话,每个文法分析的重点都是预测分析表的构造QAQ)

那么,为了成功构造出预测分析表,我们需要计算出FIRST集、FOLLOW集以及SELECT集;这三个集合的定义这里不再粘贴(书上有十分专(nan)业(dong)的定义),只写一下如何计算以及我的理解(刚刚了解编译原理,如有不对还请指正。

FIRST集
个人理解:

对于一个非终结符,它的FIRST集,就是把它一步步展开,每个展开式的第一个字符,如果这个字符是终结符,就把这个终结符放入FIRST集;如果是非终结符,就把这个非终结符继续展开。当然,如果第一个字符可以是空串,那么第二个字符,此时也就成了第一个字符,以此类推。

例子(如何计算):
给定文法如下:
(图片来源:https://blog.csdn.net/zuzhiang/article/details/79047743
在这里插入图片描述
首先看E的FIRST集:

  • 展开E,右部第一个字符是一个非终结符T;
  • 那么继续展开T:右部第一个字符是一个非终结符F;
  • 继续展开F:右部第一个字符是终结符( 和 i
  • 因此FIRST(E) = { ‘(’, ‘i’ }

其它同理;

FOLLOW集
个人理解

对于一个非终结符,当前字符匹配上之后,下一个字符可以取哪些值

计算方法

根据定义我们也知道,FOLLOW集是从产生式右部找;对于FOLLOW(A),如果有一个产生式右部存在A,大致分四种情况:

  • A后面没有其他符号,那么FOLLOW(A) = FOLLOW(产生式右部符号);
  • A后面是一个终结符,那么就把这个终结符加入FOLLOW(A)集合中去;
  • A后面是一个非终结符且这个非终结符的FIRST集中不含空串,那么就把这个非终结符的FIRST集加入到FOLLOW(A)中;
  • A后面是一个非终结符且这个非终结符的FIRST集中含有空串,那么把这个非终结符的FIRST集减去空串后,加入FOLLOW(A),并且,产生式右部的FOLLOW集也加入到FOLLOW(A)中;

例子
还是上面那个文法,

  • 计算FOLLOW(E):
    因为E是开始符号,所以它的FOLLOW集中肯定有文法结束符号$,然后我们来找那个产生式右部有E:F—>(E),E的后面是一个终结符),所以FOLLOW(E) = { ‘)’, ‘$’ };
  • 再算FOLLOW(F):
    可以发现:E—>TE`,E`—>+TE`,T的后面是非终结符E`,且FIRST(E`)中含有空串,所以FOLLOW(T)=FIRST(E`) - {ε} + FOLLOW(E) + FOLLOW(E`)
    所以FOLLOW(F) = { ‘*’, ‘+’, ‘)’, ‘$’ }

SELECT集
个人理解

这个个人感觉几乎是预测分析表的表达式形式了:对于一个产生式,如果分析中这一步你想选择这个产生式,你当前输入的符号可以是哪些

计算方法
对于一个产生式A—>B

  • 如果FIRST(B)中不含ε,那么把FIRST(B)加入到SELECT(A)中;
  • 如果FIRST(B)中含有ε,那么把FIRST(B) - ε + FOLLOW(A)加入到SELECT(A)中;
    (例子不想写了,想吃饭……可以自己推导一下,用上面那个例子,给出答案:
    (来源:https://blog.csdn.net/zuzhiang/article/details/79047743
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/destiny1507/article/details/86758588