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

时间:2021-07-19 12:18:35

标签: antlr4

我正在尝试用 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(不正确的词法规则优先级与“非”规则)

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

1 个答案:

答案 0 :(得分:1)

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;
相关问题