为LL(1)解析器设置的PREDICT帮我修复它

时间:2015-11-09 08:46:46

标签: parsing grammar compiler-construction

我正在尝试为大学项目构建编译器。目前我在创建LL(1)语法的预测集的一部分时遇到问题。这是我的语法的一部分,我遇到了问题:

<DECLS>  ::- id <DECL> <N_DECL>
<N_DECL> ::- op_, <DECLS> | null
<DECL>   ::- <SOMETHING_MORE>

这部分语法的第一组是:

<DECLS>  = id
<N_DECL> = op_ , null

这部分语法的跟随集是:

<DECLS>  = op_; , op_,
<N_DECL> = op_; , op_,

这部分语法的预测集(见矩阵):

                   id                      op_,
<DECLS>    id <DECL> <N_DECL> 
<N_DECL>                               op_, <DECLS> / null      <--- here

正如您所看到的,N_DECLop_的条目有两个条目。据我所知,如果预测集在同一个框中有两个或多个条目,则语法错误。所以我想知道是否有人可以帮助我改变语法来解决这个问题。

1 个答案:

答案 0 :(得分:1)

如果我理解你的符号,那么

  • 第一个( <N_DECL> )= { op_, null } < / em>的
  • 关注( <N_DECL> )= { op_; op_, } < / em>的

我不知道op_,的{​​{1}}中的<N_DECL>来自哪里(也许它来自你语法的不同部分),但是如果它真的存在,由于 FIRST / FOLLOW冲突,你的语法会模棱两可。只要非终端的FIRST集合包含null(即非终端可以产生空字符串),并且该非终端的FIRST和FOLLOW集合重叠,就会发生这些情况。在这种情况下,它们都包含op_,,这会引起您注意到的问题。

从您在op_,的关注集中列出<DECLS>这一事实,我推断实际的歧义来自于您未包含的部分语法。你的问题。如果您正在使用一个标记的前瞻解析<DECLS>,则遇到逗号可能意味着您有另一个op_, id <DECL> <N_DECL>短语,或者该逗号属于逗号为&#的结构34;外侧&#34; <DECLS>

您的语言可能是LL(1),但如果不知道为什么 <DECLS>可以跟op_,,我就不知道如何解决这个冲突。但是,如果事实证明您的语言不是LL(1),因为它现在已被标记化,您应该考虑欺骗令牌器为您做前瞻:

  • 使用替换来<N_DECL> ::- op_, id <DECL> <N_DECL> | null
  • 让词法分析器将op_, id解析为自己的令牌comma_id
  • 纠正制作:<N_DECL> ::- comma_id <DECL> <N_DECL> | null