【问题标题】:Lexer command 'more' in antlr doesn't match the expected valueantlr 中的 Lexer 命令“更多”与预期值不匹配
【发布时间】:2020-05-19 06:45:34
【问题描述】:

我一直在 antlr 中使用不同的词法分析器模式,我在词法分析器中遇到了“更多”命令的问题,因为它与相应令牌中的所有内容都不匹配。为了让事情更清楚,我的代码大致如下所示:

//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 的第一个字母与 Token 不匹配。我必须输入类似

的内容

SMTH gCLASS

为了匹配关键字CLASS。如果我理解正确,“更多”命令将匹配不是数字的所有内容并将其带回默认模式,因此它可以是另一个令牌的一部分。有人可以告诉我我的错误在哪里吗?谢谢。

【问题讨论】:

    标签: command antlr lexer


    【解决方案1】:

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

    1. 令牌KEYWORD_SMTH是为文本文本"SMTH"创建的
    2. 模式从DEFAULT_MODE更改为NUMBER_MODE
    3. 为文本 "C" (NO_NUMBER...) 创建标记的开头
    4. 模式从NUMBER_MODE变为DEFAULT_MODE
    5. DEFAULT_MODE 中,之前匹配的"C" 被粘在"LASS" 被标记为的任何内容上(注意这与KEYWORD_CLASS 不匹配!)

    因此,假设 "LASS" 被标记为 IDENTIFIER 标记或类似标记,您最终将得到 2 个标记:

    1. KEYWORD_SMTH(文字"SMTH"
    2. IDENTIFIER(文字"C" + "LASS"

    【讨论】:

    • 感谢您的帮助!那么有没有办法从DEFAULT_MODE获取NO_NUMBER的内容来匹配一个关键字呢?
    • 不,词法分析器不会将"C" 放回字符流中,以便可以在DEFAULT_MODE 中创建KEYWORD_CLASS。在这种情况下,您必须将KEYWORD_CLASS: C L A S S; 移动到NUMBER_MODE
    • 你真的应该摆脱 ~[0-9] -> more,这是 IMO 广泛使用的方式。考虑编辑您的问题(或创建一个新问题),在其中解释更大的图景:从您发布的 2 个问题中,我会说您使用词法分析器模式过于矫枉过正,并且让您的生活变得比没有它应该更复杂他们。
    • 感谢您的反馈。我需要为 JCL 编写一个解析器,因为我通常不允许使用语义谓词或 Java 代码,所以我觉得词法分析器模式是我必须避免歧义的唯一可用选项。这就是为什么我基本上对必须解析的 JCL 语句的每个参数都使用词法分析器模式的原因。我将尝试在另一个问题中解释更大的图景。
    • 快速浏览了 JCL,是的,如果您不想要语义谓词,那么我认为需要词汇模式(或者更好:模式优于谓词)。
    猜你喜欢
    • 1970-01-01
    • 2018-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多