调试Python ANTLR4语法

调试Python ANTLR4语法,python,parsing,python-3.x,grammar,antlr4,Python,Parsing,Python 3.x,Grammar,Antlr4,我的ANTLR4语法有问题,无法正确解析字符串。我更感兴趣的是学习如何解决我的问题,而不是解决我的具体问题。如何生成任何类型的调试信息?我想知道解析器在解析字符串时在“思考”什么 语法可在此处找到: 我使用的是简单的测试字符串:-1d metric('blah','blah','blah') 我得到以下错误:1:2缺少时间\u指示器位于'd' 语法将TIME\u指示器定义为[shmd],因此我不确定当字符d是一个可能的标记时,它是如何缺少TIME\u指示器的。我错过了什么 我使用的是从ANTLR

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

语法可在此处找到:

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

我得到以下错误:
1:2缺少时间\u指示器位于'd'

语法将
TIME\u指示器
定义为
[shmd]
,因此我不确定当字符
d
是一个可能的标记时,它是如何缺少
TIME\u指示器的。我错过了什么


我使用的是从ANTLR4生成的Python3。

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

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

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

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
被标记为
标识符
,而不是
时间指示器
。这是因为
标识符
规则是在
时间指示器
规则之前定义的。lexer不“监听”解析器可能需要的内容,它只匹配尽可能多的字符,如果两个或多个规则匹配相同数量的字符,则第一个定义的规则“获胜”

因此,
d
可以标记为
TIME\u指示器
标识符
。如果这取决于上下文,我建议您将其标记为
标识符
(并删除
时间指示符
),并创建如下解析器规则:

relative_time_literal:
    MINUS? INTEGER_LITERAL time_indicator;

time_indicator:
    {_input.LT(1)getText().matches("[shmd]")}? IDENTIFIER;
{…}?
称为谓词:


另外,
FALSE
TRUE
需要放在
标识符
规则之前。

我更新了我的代码以包括标记的打印:链接已断开!正确的是
Metrink.g4
(大写为M)
relative_time_literal:
    MINUS? INTEGER_LITERAL time_indicator;

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