LALR(1)和SLR(1)解析器

时间:2019-05-17 14:39:28

标签: parsing context-free-grammar lookahead

我从我们的老师那里得到了一个假设,他希望我们从中进行搜索和验证。我们有SLR(1)和LALR(1)解析器。假设是:

  

假设我们有一个名为X的语言结构。如果我们不能为此结构提供LALR(1)语法,那么我们也不能提供SLR(1),也许LR(1)语法可以解决问题。 。但是,如果我们可以为此结构提供LALR(1)语法,那么我们也可以提供SLR(1)。

如果您在Internet上搜索,则会发现很多网站,这些网站说的不是SLR(1),而是LALR(1):

S -> R
S -> L = R
L -> * R
L -> id
R -> L

(“ id”,“ *”和“ =”是终端,其他是非终端)
如果尝试查找SLR(1)项,则会看到移位/减少冲突。没错,但我的假设说了别的话。在我们的假设中,我们谈论的是语法而不是语法本身所描述的语言!我们可以删除“ R”并将语法转换为LL(1),它也是SLR(1)和LALR(1):

S -> LM
M -> epsilon
M -> = L
L -> * L
L -> id

您可以尝试该语法,并且可以看到该语法将相同语言描述为最后一个语法,并且具有SLR(1)和LALR(1)语法!

所以我的问题不是找到语法是LALR(1)而不是SLR(1)。互联网上有很多。我想知道是否有任何具有LALR(1)语法但没有SLR(1)语法的语言?如果我们的假设是正确的,那么就不需要LALR(1)并且SLR(1)可以为我们做任何事情,但是LALR(1)更易于使用,将来可能会成为语言拒绝这个假设。

对不起,英语不好。
谢谢。

2 个答案:

答案 0 :(得分:1)

每种LR( k )语言都有SLR(1)语法。

this paper from 1976中有一个证明,如果您具有LR( k )语法并且知道其值,则该证明提供了一种构造SLR(1)语法的算法。的 k 。不幸的是,没有算法可以明确告诉您CFG是否为LR( k ),更不用说提供 k 的值了。 (如果您以某种方式知道语法是LR( k ),则可以尝试 k 的连续值,直到找到可行的值为止。但是,如果语法不是LR( k )。)

以上内容来自this reference question上的Computing Science StackExchange site,对于此类问题更合适。

答案 1 :(得分:0)

LR(1)> LALR(1)> SLR(1)

LR(1)功能最强大,LALR(1)功能更差,SLR(1)功能最差。 这是事实,因为超前集合的计算方式。 (1)表示一个令牌的先行。这是LR(1)而不是LALR(1)绝对不是SLR(1)的语法:

   G : S... <eof>
     ;
   S : c A1 t ';'
     | c A2 n ';'                       
     | r A2 t ';'
     | r A1 n ';'
     ;
  A1 : a 
     ;
  A2 : a 
     ;

不能将此语法制成LALR(1)或SLR(1)。或者确定您可以删除A1和A2以及 用a代替它们,但是您会有不同的语法。问题是 动作可以附加到规则A1:a上,而另一个动作可以附加到规则A1:a上。例如:

  A1 : a    => X()
     ;
  A2 : a    => Y()
     ;

SLR(1)解析器生成器将在语法中报告不是真正冲突的冲突。我说的是使用大语法(例如C11.grm)的现实世界。

SLR(1)超前计算是简单的,从语法中获得超前,而不是由LALR(1)解析器生成器创建的LR(0)状态机。

这就是为什么弗兰克·德雷默(Frank DeRemer)在1969年发表的关于LALR(1)的论文如此重要的原因。

通过查看语法,A1可以跟在t或n后面,因此这是一个冲突 由SLR(1)报告,但存在一个LR(1)状态机,其中A1之后没有冲突。