Parsing 如何将此语法转换为LR(1)?

Parsing 如何将此语法转换为LR(1)?,parsing,lr,Parsing,Lr,我的语法与LR(1)冲突无法解决;然而,语法应该是明确的。我将首先用五个标记在简化语法上演示这个问题:(,),{},,和id EBNF如下所示: args = ( id ',' )* expression = id | '(' expression ')' | '(' args ')' '{}' 语法是明确的,最多需要两个前瞻标记。当(移位时,只有五种可能: (→ 复发 )→ 减少为”('args')” id)不是{}→ 减少为”(“表

我的语法与LR(1)冲突无法解决;然而,语法应该是明确的。我将首先用五个标记在简化语法上演示这个问题:
{}
id

EBNF如下所示:

      args = ( id ',' )*

expression = id
           | '(' expression ')'
           | '(' args ')' '{}'
语法是明确的,最多需要两个前瞻标记。当
移位时,只有五种可能:

  • → 复发
  • → 减少为
    ”('args')”
  • id
    不是
    {}
    → 减少为
    ”(“表达式”)”
  • id
    {}
    → 减少为
    '('args')'{}'
  • id
    → 减少为
    ('args')'{}'
    (最终)
  • 简单的翻译会产生以下结果(和):

    因此,语法最多需要三个前瞻标记来决定。我知道一个LR(3)语法到LR(1)语法


    然而,我不太明白在这种特殊情况下如何进行转换。请注意,上面的简化语法是从;特别是,是否可以在不触碰
    expr
    和上面的所有内容的情况下转换
    。基本思想是将
    (id)
    案例与其他两种可能性(
    (expr\u not\u id)
    (列出至少两个id)
    )分开。然后,关于如何减少
    (id)
    的决定可以推迟到前瞻令牌可用为止(在您的情况下,
    {
    ,假设这足够了)

    不幸的是,虽然将
    expr
    转换为
    expr\u not\u id
    非常简单,几乎是机械的,但它确实涉及到很多作品。而且,它有点难看。因此它无法解决您在最后一句中提出的问题。我实际上不认为有可能转换
    主要内容
    没有触摸
    expr
    ,但我以前很惊讶


    (另一个显而易见的解决方案,因为语法事实上是明确的,就是使用GLR解析器生成器,但我不相信您正在使用的解析器生成器具有该功能。)

    事实上,我刚刚得出了与您相同的结论。然而,我的解析器生成器(menhir)有更高阶的规则,所以我可以让它为我做繁重的工作。我可能会自己回答这个问题(如果它对我有效的话),很抱歉不接受!最有趣的是,我知道你链接的问题的作者。我刚完成了你的转换,它工作了,尽管需要对语法进行一系列奇怪的转换。太棒了。
       formal_arg: Ident
                   {}
    
      formal_args: formal_arg Comma formal_args
                 | formal_arg
                 | /* nothing */
                   {}
    
          primary: Ident
                 | LParen formal_args Curly
                 | LParen primary RParen
                   {}