如何解析无法转换为解析器规则的长词法分析器规则的标记?

How to parse tokens of long lexer rule that cannot be converted into parser rule?

我正在尝试用 ANTLR4 解析它:

> A Request [AR]
Commments might have many lines here
Line 2
 
- A Response [A]
- The other response [B]
Response can also have lines here.

> Request [A]
- Responce

下面的代码解析的很好:

grammar Response;

prog: (request | response)+ EOF;

request: REQUEST TEXT*;
response: RESPONSE TEXT*;
 
REQUEST: '>' TEXT '[' ID ']';
RESPONSE: '-' TEXT ('[' ID ']')?;
 
ID: [a-zA-Z] [a-zA-Z0-9._]*;
TEXT: ~[\r\n]+;
 
EMPTY: [ \t\r\n]+ -> skip;

这是一个很好的结果。但是我想分别解析 ID 和 TEXT。因为这些是长词法分析器规则中的标记,所以这似乎不受支持。

据我了解,通常在这种情况下,您可以将词法分析器规则 REQUEST 和 RESPONSE 替换为 request_rule 和 response_rule 等解析器规则。

但这在这里不起作用,因为 TEXT 词法分析器规则将匹配每一行。例如,如果我将 REQUEST 和 RESPONSE 替换为 ruleREQUEST 和 ruleRESPONSE:

我正在尝试弄清楚如何继续...似乎唯一的方法是使用大量 popMode 和 pushMode 使代码复杂得多,如下所述:

https://github.com/antlr/antlr4/issues/2229(不正确的词法分析器规则优先级为“not”规则)

有没有什么简单的方法,基于原来的antlr4代码,在C#中获取TEXT和ID值Antlr4.Runtime.Standard?除此之外,代码运行完美。

TEXT 是贪婪的,因此它匹配所有其他词法分析器规则。您将需要通过添加 '?' 使其不贪心。 '+' 后的运算符。

但是,一旦您这样做了,就需要更改解析器规则以允许不同的标记。

这里是一个可能有用的语法。它适用于您的输入,但您可能需要进行进一步的更改。

grammar Response;

prog: (request | response)+ EOF;
request: request_rule text*;
response: response_rule text*;
request_rule: '>' text '[' ID ']';
response_rule: '-' text ('[' ID ']')?;
text: (ID | TEXT)+;
ID: [a-zA-Z] [a-zA-Z0-9._]*;
GT: '>';
LP: '[';
RP: ']';
DS: '-';
TEXT: ~[\r\n]+?;
EMPTY: [ \t\r\n]+ -> skip;