【问题标题】:How do I tell ANTLR to prefer one alternative over the other?我如何告诉 ANTLR 更喜欢一种选择而不是另一种?
【发布时间】:2017-11-15 19:45:04
【问题描述】:

我有以下作品:

expression
    :   primary # stubLabel
    |   expression '.' Identifier # stubLabel
    |   expression '.' 'this' # stubLabel
    |   expression '.' 'new' nonWildcardTypeArguments? innerCreator # stubLabel
    |   expression '.' 'super' superSuffix # stubLabel
    |   expression '.' explicitGenericInvocation # stubLabel
    |   expression '[' expression ']' # stubLabel
    |   Identifier arguments # namedMethodInvocation
    |   expression '.' Identifier arguments # namedMethodInvocation
    |   expression arguments # unnamedMethodInvocation
    |   // Lots of other patterns...
    ;

我希望让解析器在尝试unnamedMethodInvocation 之前先尝试namedMethodInvocation 模式。这不会自动发生,因为 ANTLR 会尝试选择具有最长匹配的替代方案,而不是使用第一个匹配策略。我怎样才能强制它这样做?

编辑:对不起,我忽略了上面的语法文件的链接。 Here 是。

【问题讨论】:

  • 请发布primary生产规则。
  • @saka1029 很抱歉,我忽略了在我的帖子中链接到完整的语法文件!语法文件可以在here找到。 primary 生产规则是 here
  • 在解析器规则中,alts 被一个一个地测试,从上到下的顺序(如语法中所写),第一个匹配的获胜。 Alts 排序本身就是一个问题,因为它决定了很多事情(例如优先级)。

标签: java parsing antlr grammar antlr4


【解决方案1】:

尝试像这样将namedMethodInvocation 移动到primary 生产规则(在Identifier 之前)。

primary
    :   '(' expression ')'
    |   'this'
    |   'super'
    |   literal
    |   Identifier arguments // namedMethodInvocation
    |   Identifier
    |   typeType '.' 'class'
    |   'void' '.' 'class'
    |   nonWildcardTypeArguments (explicitGenericInvocationSuffix | 'this' arguments)
    ;

或者将primary移动到expression中的最后一个。

expression
    : expression '.' Identifier
    .....
    | Identifier arguments  // namedMethodInvocation
    | expression arguments  // unnamedMethodInvocation
    .....
    | primary
    ;

或插入新规则primaryOrNamedMethodInvocation

expression
    : primaryOrNamedMethodInvocation
    | expression '.' Identifier
    .....
    ;

primaryOrNamedMethodInvocation
    : Identifier arguments  // namedMethodInvocation
    | primary
    ;

【讨论】:

  • saka1029,我不想这样做,因为 namedMethodInvocation 成为主要成员是没有意义的。 namedMethodInvocation 应该匹配像 foo.bar() 这样的表达式,因为它太复杂而不能作为主要表达式。
  • 添加了另一个解决方案。
  • saka1029,我认为这不会影响结果,因为 ANTLR 会根据时间长度而不是生产顺序来选择替代方案。
  • 添加了另一个解决方案。
  • saka1029,更近一点,谢谢你的帮助。但是,我还需要为namedMethodInvocation 处理expression '.' Identifier arguments(我在原始问题中发布了这个)。将其移入新规则将不起作用,因为它将使用间接左递归。
猜你喜欢
  • 2016-09-13
  • 2020-11-04
  • 1970-01-01
  • 2014-08-16
  • 1970-01-01
  • 1970-01-01
  • 2011-04-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多