antlr4 - 如何摆脱词汇模式
问题描述
我一直在尝试使用模式来解析这样的消息:
-MSGTXT (DO NOT TOKENIZE (THERE CAN BE PARENS HERE) THIS PART)
-END END OF MESSAGE
-TEST 123
MSGTXT 的内容可以是任何字符,因此我将我的词法分析器语法设置如下:
lexer grammar ADEXPLexer;
// Fields
MSGTYP: 'MSGTYP';
ADEP: 'ADEP';
TITLE: 'TITLE';
FILTIM: 'FILTIM';
ORIGINDT: 'ORIGINDT';
IFPLID: 'IFPLID';
MSGTXT: 'MSGTXT' -> pushMode(MSG);
COMMENT: 'COMMENT';
// Message types.
ACK: 'ACK';
IFPL: 'IFPL';
// Lexical rules.
SEP: HYPHEN;
WS: [ \t\n\r] + -> skip;
KEYWORD: (ALPHA|DIGIT)+;
mode MSG;
TEXT: CLOSE_MSG | (ALPHA|DIGIT|SPECIAL|WS|HYPHEN)+;
CLOSE_MSG: ')' -> popMode;
fragment HYPHEN: '-';
fragment ALPHA: [A-Z];
fragment DIGIT: [0-9];
fragment SPECIAL
: '('
| '?'
| ':'
| '.'
| ','
| '\''
| '='
| '+'
| '/'
| ')'
;
然而,现在的问题是,最后一个关闭的 ')' 永远不会用于重新进入默认模式,因此它会继续进入消息的其他部分。解析器规则本身如下所示:
msgtxt: SEP MSGTXT TEXT;
我正在寻找一种不涉及 TokenStreamRewriter 的方法来解决这个问题,因为 JavaScript 运行时中没有这样的东西。
任何帮助表示赞赏!
解决方案
不确定你到底需要什么,但如果你不需要检查内容是否TEXT
是其中之一,请(ALPHA|DIGIT|SPECIAL|WS|HYPHEN)
使用:
mode MSG;
TEXT: ~[)]+;
CLOSE_MSG: ')' -> popMode;
如果你这样做,只需')'
排除fragment SPECIAL
推荐阅读
- javascript - javascript循环的分层响应
- asp.net-core - How to use AbpSession?
- laravel - 如何更新日期列并增加计数器?
- java - 按钮没有响应
- javascript - 如何遍历对象数组并在页面上显示每个对象?(香草JS)
- graph-databases - Graph/Gremlin query for social media use case
- mongodb - Mongo:错误的 Auth 身份验证失败。
- java - Multidimensional array in Java with for function - Schildt
- ruby-on-rails - Rails:在检查现有记录(并使用现有记录)后创建实例和关联
- javascript - 用 Jest 模拟测试