Parsing 形式语法权力的实际后果?

Parsing 形式语法权力的实际后果?,parsing,theory,Parsing,Theory,每一门本科编译器入门课程都会回顾上下文无关语法的常用子集:LL(k)、SLR(k)、LALR(k)、LR(k)。我们还被教导,对于任何给定的k,这些语法中的每一个都是下一个语法的子集 我从来没有看到过一个解释,说明什么样的编程语言语法特性可能需要迁移到不同的语言类。对于GLR解析器来说,有一个明显的实用动机,即在解析C++时避免解析器和符号表的不一致。但是,LL和LR这两个“标准”类之间的区别是什么呢 两个问题: 什么(一般)句法结构可以用LR(k)而不是LL(k')解析 如果有的话,这些结构以

每一门本科编译器入门课程都会回顾上下文无关语法的常用子集:LL(k)、SLR(k)、LALR(k)、LR(k)。我们还被教导,对于任何给定的k,这些语法中的每一个都是下一个语法的子集

我从来没有看到过一个解释,说明什么样的编程语言语法特性可能需要迁移到不同的语言类。对于GLR解析器来说,有一个明显的实用动机,即在解析C++时避免解析器和符号表的不一致。但是,LL和LR这两个“标准”类之间的区别是什么呢

两个问题:

  • 什么(一般)句法结构可以用LR(k)而不是LL(k')解析
  • 如果有的话,这些结构以什么方式表现为理想的语言结构
  • 有一个看似合理的论点是通过尽可能地减小k来降低语言能力,因为一种需要大量前瞻标记的语言对于人类来说更难解析,对于机器来说也更难解析。问题(2)隐式地问,同样的推理是否在类之间以及类内部都成立


    编辑:这里有一个例子来说明我正在寻找的答案的种类,但是对于常规语言,而不是上下文无关的:

    在描述常规语言时,通常会得到三个运算符:
    +
    *
    。现在,您可以删除
    +
    ,而不降低语言的能力;不是写
    x+
    ,而是写
    xx*
    ,效果相同。但是,如果
    x
    是一个大而多毛的表达式,那么由于人类的健忘,这两个
    x
    很可能会随着时间的推移而发生分歧,从而产生一个语法正确的正则表达式,与原作者的意图不符。因此,尽管添加
    +
    并不能严格地增加功能,但它确实使符号不那么容易出错


    在从LR切换到LL时,是否存在必须“删除”的具有类似实际(人类?)效果的结构?

    语言的能力不受其语法和语法的限制


    用LL(k)语法定义任何语言功能都是可能的,只是人类可能不太容易理解。

    首先,左递归定义在LL(k)语法中是不可能的(据我所知),不知道其他语法。这并不意味着不可能定义其他事情,否则会带来巨大的痛苦。例如,用左递归语言(伪代码)组合表达式可能很容易:

    就可以用左递归实现的语法有用的东西而言,简单的语法在语法上有用吗?

    解析(我声称)有点像排序:在CS早期,这个问题是很多人思考的焦点,导致了一组理解良好的解决方案和一些很好的理论结果

    我的观点是,在某种程度上,我们在编译器课程中得到的(或给出的,对于我们这些教书的人来说)图片是对错误问题的美丽回答

    为了更直接地回答您的问题,LL(1)语法不能解析您可能想要解析的所有类型的东西;例如,带有可选“else”的“if”的“natural”表达式

    但是等等!难道我不能将我的语法重新格式化为LL(1)语法,然后通过遍历源代码树来修补它吗?当然可以!在某种程度上,这就是为什么解析器使用哪种语法的问题在很大程度上是没有意义的

    而且,当我还是一名大学生时(1990-94),对空格敏感的语法显然是魔鬼的杰作;现在,Python和Haskell的设计将空白敏感性重新引入人们的视野。此外,Packrat语法分析说“为了检验你理论上的纯洁性:我只是将语法分析器定义为一组规则,我不在乎我的语法属于哪一类。”


    总之,我同意你暗示的建议:在2009年,对LL(k)类和LR(k)类之间的差异有一个清晰的理解它本身没有制定和调试语法的能力那么重要,语法的制定和调试使解析器生成器满意。

    LL和LR之间的区别主要在于前瞻机制。人们通常说LR解析器承载更多的“上下文”。为了实际地看到这一点,考虑以S作为起始符号的递归语法定义:

    A -> Ax | x 
    B -> Ay
    C -> Az
    S -> B | C
    
    当k是一个小的固定值时,解析像xxxxxx y这样的字符串更适合LR解析器。然而,现在流行的LL解析器(如ANTLR)并没有将k限制为如此小的值,大多数人不再关心

    我希望这或多或少符合你的问题。当然,Knuth指出,任何明确的上下文无关语言都可以被某些LR(1)语法识别。然而,在实践中,我们也关注翻译

    顺便说一句:你可能也喜欢阅读

    这一点并没有得到证实,但我一直质疑类似LR的解析是否真的与阅读某些符号时大脑的工作方式相似。例如,当我们阅读一个英语句子时,很明显我们是从左到右阅读的。但是,请考虑下面的模式:

    我更希望像这样的短模式,人们不会从左到右逐字读“点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点。换句话说,我不认为我们必须以从左到右的方式读取所有模式,并使用LL/LR解析器使用的那种线性前瞻

    此外,如果我们可以使用LR(1)语法描述任何上下文无关的语言,那么很明显,简单地识别字符串并不等于“理解”它。

    当然,LL(1)对于
    A -> Ax | x 
    B -> Ay
    C -> Az
    S -> B | C