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值?除此之外,代码完美运行。
解决方案
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;
推荐阅读
- python - Django - 解决生产中 DRF 视图集的线程本地和中间件问题
- datagrid - Material UI Datagrid:全选时调用onRowSelected函数
- javascript - 如果 ul 里面没有 li,则无法隐藏 ul
- c++ - cout 语句中 C++ 中的前置和后置增量
- python - 通过迭代创建字典同时更新值的 Pythonic 方法?
- javascript - 当页面完全加载时,我如何告诉 puppeteer?
- excel - 使用 if 函数从列中提取日期(如果它存在)或另一个(如果它在 excel 中缺失)
- java - 如何制作一种从 x 和 o 中创建模式的方法?
- progressive-web-apps - 网页调用GameClient的setViewForPopups实现自动登录
- reactjs - 下一个 js 应用程序(在 docker 容器内运行)无法加载位于公共目录中的静态文件图像