Command Lexer命令';更多';在antlr中没有';与期望值不匹配

Command Lexer命令';更多';在antlr中没有';与期望值不匹配,command,antlr,lexer,Command,Antlr,Lexer,我在antlr中使用了不同的lexer模式,并且在lexer中遇到了“more”命令的问题,因为它不匹配相应令牌中的所有内容。为了让事情更清楚,我的代码大致如下: //DEFAULT_MODE fragment A: ('A'); //same done for A-Z KEYWORD_CLASS: C L A S S; NUM: [0-9]; KEYWORD_SMTH: S M T H->mode(NUMBER_MODE); mode NUMBER_MODE; NUMBER: NU

我在antlr中使用了不同的lexer模式,并且在lexer中遇到了“more”命令的问题,因为它不匹配相应令牌中的所有内容。为了让事情更清楚,我的代码大致如下:

//DEFAULT_MODE
fragment A: ('A'); //same done for A-Z
KEYWORD_CLASS: C L A S S;
NUM: [0-9];
KEYWORD_SMTH: S M T H->mode(NUMBER_MODE);


mode NUMBER_MODE;

NUMBER: NUM+ ->mode(ANOTHER_MODE);
NO_NUMBER: ~[0-9]->more, mode(DEFAULT_MODE);
现在,当我尝试测试解析器规则时

rule: KEYWORD_SMTH NUMBER? CLASS;
然后我希望匹配以下短语:

SMTH类

但由于某些原因,C的第一个字母与标记不匹配。我得打一些类似的字

SMTH gCLASS


以匹配关键字类。如果我理解正确,“more”命令将匹配所有不是数字的内容,并将其恢复到默认模式,因此它可以是另一个令牌的一部分。有人能告诉我我的错在哪里吗?谢谢。

假设您忽略了跳过/隐藏空格的规则,这就是标记SMTH类时发生的情况:

  • 为文本“SMTH”
  • 模式从
    DEFAULT\u模式
    更改为
    NUMBER\u模式
  • 标记的开头是为文本
    “C”
    无编号…
    )创建的
  • 模式从
    NUMBER\u模式
    更改为
    DEFAULT\u模式
  • 默认\u模式
    中,先前匹配的
    “C”
    被粘贴到标记为的
    “LASS”
    上(注意这将不匹配
    关键字\u类
    !)
  • 因此,假设
    “LASS”
    被标记为
    标识符
    标记或类似标记,您将得到两个标记:

  • 关键字\u SMTH
    (文本
    “SMTH”
  • 标识符
    (text
    “C”
    +
    “LASS”

  • 谢谢你的帮助!因此,无法从默认模式中获取与关键字匹配的no_NUMBER的内容?不,lexer不会将
    “C”
    放回字符流中,以便可以在
    默认模式下创建
    关键字类
    。您必须移动
    关键字\u类:clas~[0-9]->更多的
    ,这是IMO要推广的方法。考虑编辑你的问题(或者创建一个新的问题),在这里你解释了更大的画面:从你发布的2个问题中,我认为你使用LeXER模式是多余的,并且让你的生活比没有它们更复杂。谢谢你的反馈。我需要为JCL编写一个解析器,因为我一般不允许使用语义谓词或Java代码,所以我觉得lexer模式是唯一可以避免歧义的选项。这就是为什么我基本上对我必须解析的JCL语句的每个参数都使用lexer模式。我将尝试用另一个问题来解释更大的图景。快速看一下JCL,是的,如果你不想要语义谓词,那么我认为需要词汇模式(或者更好:模式比谓词更好)。