【问题标题】:Debugging Python ANTLR4 Grammar调试 Python ANTLR4 语法
【发布时间】:2016-05-03 17:54:58
【问题描述】:

我的 ANTLR4 语法出现问题,无法正确解析字符串。我对学习如何解决我的问题比解决我的具体问题更感兴趣。如何生成任何类型的调试信息?我想知道解析器在解析字符串时“在想”什么。

语法可以在这里找到:https://github.com/Metrink/metrink-fe/blob/master/metrink.g4

我正在使用简单的测试字符串:-1d metric('blah', 'blah', 'blah')

我收到以下错误:1:2 missing TIME_INDICATOR at 'd'

语法将TIME_INDICATOR 定义为[shmd],所以我不确定它是如何在字符d 处缺少TIME_INDICATOR,而这是可能的标记之一。我在这里错过了什么?

我正在使用从 ANTLR4 生成的 Python3。

【问题讨论】:

  • 链接已损坏!正确的是Metrink.g4(大写的M)

标签: python parsing python-3.x grammar antlr4


【解决方案1】:

我通常做的是首先转储令牌,看看是否创建了解析器期望的实际令牌。

您可以使用这样的小型测试类来做到这一点(很容易移植到 Python):

public class Main {

    static void test(String input) {

        metrinkLexer lexer = new metrinkLexer(new ANTLRInputStream(input));
        CommonTokenStream tokenStream = new CommonTokenStream(lexer);
        tokenStream.fill();

        System.out.printf("input: `%s`\n", input);

        for (Token token : tokenStream.getTokens()) {
            if (token.getType() != TLexer.EOF) {
                System.out.printf("  %-20s %s\n", metrinkLexer.VOCABULARY.getSymbolicName(token.getType()), token.getText());
            }
        }

        System.out.println();
    }

    public static void main(String[] args) throws Exception {
        test("-1d metric('blah', 'blah', 'blah')");
    }
}

如果您运行上面的代码,以下内容将打印到您的控制台:

input: `-1d metric('blah', 'blah', 'blah')`
  MINUS                -
  INTEGER_LITERAL      1
  IDENTIFIER           d
  METRIC               metric
  LPAREN               (
  STRING_LITERAL       'blah'
  COMMA                ,
  STRING_LITERAL       'blah'
  COMMA                ,
  STRING_LITERAL       'blah'
  RPAREN               )

如您所见,d 被标记为IDENTIFIER,而不是TIME_INDICATOR。这是因为IDENTIFIER 规则是在TIME_INDICATOR 规则之前定义的。词法分析器不会“监听”解析器可能需要的内容,它只是匹配尽可能多的字符,如果两个或多个规则匹配相同数量的字符,则首先定义的规则“获胜”。

因此,d 可以标记为 TIME_INDICATORIDENTIFIER。如果这取决于上下文,我建议您将其标记为 IDENTIFIER(并删除 TIME_INDICATOR)并创建如下解析器规则:

relative_time_literal:
    MINUS? INTEGER_LITERAL time_indicator;

time_indicator:
    {_input.LT(1)getText().matches("[shmd]")}? IDENTIFIER;

{ ... }? 称为谓词:Semantic predicates in ANTLR4?

另外,FALSETRUE 需要放在 IDENTIFIER 规则之前。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2014-09-08
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 2022-01-09
  • 2014-10-24
  • 1970-01-01
  • 2015-09-08
相关资源
最近更新 更多