Parsing LL(1)、LR(1)、LR(0)、LALR(1)语法的示例?

Parsing LL(1)、LR(1)、LR(0)、LALR(1)语法的示例?,parsing,grammar,lalr,lr,ll,Parsing,Grammar,Lalr,Lr,Ll,是否有一个很好的在线资源,包含一些主要解析算法(LL(1)、LR(1)、LR(0)、LALR(1))的语法集合?我发现了许多属于这些家族的独立语法,但我知道没有一个好的资源,有人编写了大量的示例语法 有人知道这样的资源吗?我不指望你会发现大量语法集是故意这样组织的。组织者会得到什么回报 您可能有机会找到对应于每个族的解析器生成器(例如,LL(1)),并查找该解析器生成器的输入实例,根据定义,所有这些实例都将是LL(1)。例如,ANTLR的语法都是LL(k)的不同版本,这取决于您选择的ANTLR版

是否有一个很好的在线资源,包含一些主要解析算法(LL(1)、LR(1)、LR(0)、LALR(1))的语法集合?我发现了许多属于这些家族的独立语法,但我知道没有一个好的资源,有人编写了大量的示例语法


有人知道这样的资源吗?

我不指望你会发现大量语法集是故意这样组织的。组织者会得到什么回报

您可能有机会找到对应于每个族的解析器生成器(例如,LL(1)),并查找该解析器生成器的输入实例,根据定义,所有这些实例都将是LL(1)。例如,ANTLR的语法都是LL(k)的不同版本,这取决于您选择的ANTLR版本(ANTLR版本的描述将说明它接受的k);Bison语法都是LALR(1)[忽略最近的GLR选项]。如果你去我的网站(见bio),你会看到一个语法列表,这些语法几乎都与上下文无关(也就是说,在你描述的任何类中都没有)


编辑:请注意@Bart Kier的澄清,ANTLR可以显式地将特定k的语法标记为LL(k)。

来自维基百科的示例

语法

S -> F
S -> ( S + F )
F -> a
(1) E → E * B
(2) E → E + B
(3) E → B
(4) B → 0
(5) B → 1 
S’ -> S S 
S  -> C C 
C  -> c C | d
A -> C x A | ε
B -> x C y | x C
C -> x B x | z
输入

( a + a )
1 + 1
cd
xxzxx
解析步骤

S -> "(" S "+" F ")"
  -> ( "F" + F ) 
  -> ( "a" + F ) 
  -> ( a + "a" )       
need to build a parser table and traverse through states.
large table
traverse large parser table
语法

S -> F
S -> ( S + F )
F -> a
(1) E → E * B
(2) E → E + B
(3) E → B
(4) B → 0
(5) B → 1 
S’ -> S S 
S  -> C C 
C  -> c C | d
A -> C x A | ε
B -> x C y | x C
C -> x B x | z
输入

( a + a )
1 + 1
cd
xxzxx
解析步骤

S -> "(" S "+" F ")"
  -> ( "F" + F ) 
  -> ( "a" + F ) 
  -> ( a + "a" )       
need to build a parser table and traverse through states.
large table
traverse large parser table
语法

S -> F
S -> ( S + F )
F -> a
(1) E → E * B
(2) E → E + B
(3) E → B
(4) B → 0
(5) B → 1 
S’ -> S S 
S  -> C C 
C  -> c C | d
A -> C x A | ε
B -> x C y | x C
C -> x B x | z
输入

( a + a )
1 + 1
cd
xxzxx
解析步骤

S -> "(" S "+" F ")"
  -> ( "F" + F ) 
  -> ( "a" + F ) 
  -> ( a + "a" )       
need to build a parser table and traverse through states.
large table
traverse large parser table
语法

S -> F
S -> ( S + F )
F -> a
(1) E → E * B
(2) E → E + B
(3) E → B
(4) B → 0
(5) B → 1 
S’ -> S S 
S  -> C C 
C  -> c C | d
A -> C x A | ε
B -> x C y | x C
C -> x B x | z
输入

( a + a )
1 + 1
cd
xxzxx
解析步骤

S -> "(" S "+" F ")"
  -> ( "F" + F ) 
  -> ( "a" + F ) 
  -> ( a + "a" )       
need to build a parser table and traverse through states.
large table
traverse large parser table
你可能还想看看

  • -
    • 几乎每种语法类型都有几个例子(即每种类型大概有六个左右)。你可以购买第二版的书,尽管第一版是在作者的PDF格式(接近链接底部)上免费提供的

      作者还有一些测试语法,这些语法与第二版的代码示例捆绑在一起,可以找到


      注:所有这些语法都很小(不到几十条规则),因为这显然是一本出版的书。

      大多数yacc及其克隆或替代品(如btyacc、hyacc、bison)的安装都有测试套件。这些测试套件中的语法一起构成了一个示例列表。我假设LL解析器生成器也是如此;但我对他们了解不多。既然提到了ANTLR,那么我还可以指出,快速搜索将显示ANTLR下的以下大型示例库,因此,我想这也算是一个答案。

      这些是解析算法,而不是语法。你指的是需要一种或另一种解析器的语法示例吗?我认为从技术上讲,LL(1)等实际上是语法家族。以它们命名的解析算法可以解析语言家族中的任何语法。我建议你看看ANTLR网站。它有一些很好的语言语法;)@Ira Baxter——我目前正在教授一门编译器课程,当我想展示各种解析算法时,我不得不从其他来源窃取示例语法。在这些类别中创建非平凡语法是很棘手的(但可行的),而且要创建LR(1)而不是LALR(1)或LALR(1)而不是SLR(1)的语法是极其困难的。我希望找到与这些描述相匹配的真实语法示例,这样我就可以专注于展示材料而不是调整语法。下面包含4个LL(1)语法,一个LR(0)语法不是LL(1),一个SLR(1)语法不是LR(0),还有一个LR(1)语法不是SLR(1)。所有示例都可以通过在任何类似*.nix的操作系统的终端中简单地编写“make”来编译和运行。建议尝试使用解析器生成器。使用ANTLR,您可以像这样手动设置前瞻:
      options{k=1;}
      用于LL(1),或者,默认的
      options{k=*;}
      用于LL(k)。@Bart Kiers:我的印象是旧版本的ANTLR不能以不同的方式执行k>1和k=*。所有版本都接受显式声明吗?不过,我还是很想知道。我认为最新的ANTLR使用特定于Grammar规则的lookahead来自动计算出前瞻性是什么。但我不是ANTLR专家,我相信在ANTLR v3中添加了未绑定的前瞻功能,
      k=*
      。ANTLR v2.x始终有一个固定的
      k
      。这是我脑子里想不出来的,我以后会看一看我的ANTLR参考副本,如果我弄错了,我会改正的。但我很确定它是正确的。你能告诉我如何证明一个语法是LR(0)或SLR(1)?@katia-你可能想看看斯坦福大学的编译器课程,它有一大堆课堂幻灯片和讲义,详细说明了你是如何做到这一点的。第二个习题集和期中考试(及其解决方案)对此进行了详细介绍。我不相信给出的语法是LR(0)。在[S->E.]状态中,[E->E.+B]我们有一个移位/减少冲突。我们需要使用前瞻标记来确定是否减少,S->E。在$lookahead上,或继续转换。使用S的通用跟随集解决了冲突,使语法SLR不是LR(0)。我同意@ChrisSmowton@ChrisSmowton,语法确实是LR(0)。要创建项目DFA,通常需要添加规则S->E#(其中#是输入的结尾),因此所提到的状态包含[S->E.#]、[E->E.+B],并且没有冲突,但有两个不同的移位(一个是接受操作)。