我可以更改标记与先前 "more" 命令匹配的方式吗?

Can I change the way a token matches from a previous "more" command?

我的语法有点复杂,我不得不使用词法模式。要退出我的一种模式,我需要匹配一个在下一个模式中具有语义意义的标记。但是,more 命令的行为似乎并不像我预期的那样。这里有一个简化的语法来说明:

FooLexer.g4

lexer grammar FooLexer;

IGNORE: [\r\n]+ -> skip;

FOO: 'foo' -> pushMode(FINDBAR);
BARFOO: 'barfoo';

mode FINDBAR;

EXIT: 'bar' -> more,popMode;
OOPS: [\r\n]+;

test.input

foobarfoo

来自grun FooLexer tokens -encoding utf-8 -tokens test.input的输出:

[@0,0:2='foo',<'foo'>,1:0]
[@1,3:8='barfoo',<'foo'>,1:3]
[@2,9:9='\n',<OOPS>,1:9]
[@3,10:9='<EOF>',<EOF>,2:0]

我想在重新进入默认模式时匹配 BARFOO 而不是 FOO。目前,我匹配 FOO 与内容 "barfoo".

给定,

I need to match a token which is semantically significant in the next mode.

试试这个 --

FOO: 'foo' -> pushMode(FINDBAR);
BARFOO: 'barfoo';

mode FINDBAR;
  EXIT: 'barfoo' -> type(BARFOO),popMode;
  OOPS: [\r\n]+;

在退出时发出所需的 BARFOO 令牌。


使用 more 无法实现任何等效,因为 more 属性无法改变任何规则匹配的内容。它只会累积匹配(和消耗)的文本,以包含到实际发出的任何下一个标记(下一个 un-more'd 标记)中。

因此,EXIT 规则不会产生令牌。 EXIT 匹配的文本累积到 FOO 标记的文本中 [@1,3:8='barfoo',<'foo'>,1:3]