Antlr4 词法分析器采用了错误的规则

Antlr4 lexer takes wrong rule

我的语言具有可以无参数或带参数的命令,以及一个 "if" 关键字:

cmd1            // parameter-less command
cmd2   a word   // with parameter: "a word" - it starts with first non-WS char
if cmd3         // if, not a command, followed by parameter-less command
cmd4 if text    // command with parameter: "if text"

"if" 仅当它是该行中的第一个非 WS 字符串时才被识别为 if(现在让我们忽略注释...)

这些是我的语法规则: 语法 TestFlow;

// Parser Rules:
root: (lineComment | ifStat | cmd )* EOF;

lineComment : LC;
ifStat  : IF;
cmd : CMD;

// Lexer Rules:
LC  : '//' ~([\n\r\u2028\u2029])* -> channel(HIDDEN); // line comment

IF  : 'if';

CMD : [-_a-zA-Z0-9]+ GAP LINE
    | [-_a-zA-Z0-9]+
    ;

fragment GAP    : [ \t]+;
fragment LINE   : ~([\n\r\u2028\u2029])*;

但是我的词法分析器将第 3 行识别为 CMDif cmd3,而不是我需要的 if 后跟 cmd3

我的错误是什么?如何解决?

您的示例中似乎没有定义语法的解析器规则。这意味着没有规则指示查找 'if' 和命令。

你的话是怎么回事:

But my lexer identifies 3rd line as a CMD: if cmd3, and not as if followed by cmd3 as I need

词法分析器规则 CMD 中的第一个选项查找一个或多个字符 ("if"),然后是 space ' ',然后是 LINE (cmd3)。 因此,输入 "if cmd3" 它匹配整行,这正是您告诉它要做的!

我可以根据个人经验告诉您,即使是一门简单的语言,您也可以通过后退一步并复习一些示例语法来快速学习 很多,这如果我现在是你,我会这样做以避免沮丧。我 高度 推荐 www.pragprog.com 的 Antlr4 参考书以及 antlr 网站。

已更新 我想这可能是您感兴趣的内容:

grammar myGrammar;

root        :   statement NEWLINE
            | comment NEWLINE
            ;

statement   :   ifStat (LC)?
            | cmdStat (LC)?
            ;

ifStat      :   IF cmdStat;
cmdStat     :   cmd (args)*;

cmd     :   CMD;

args        :   LINE;
CMD     :   [-_a-zA-Z0-9]+ GAP LINE
            | [-_a-zA-Z0-9]+
        ;

fragment GAP    :   [ \t]+;
fragment LINE   :   ~([\n\r\u2028\u2029])*;
NEWLINE     :   ('\r')?'\n';

同样,我必须说,如果您读过这本书(我读过),这可能会给您解析器(而不是词法分析器)的预期响应。 ifStat 是可选的(可能存在也可能不存在,具体取决于您的测试用例),总会有一个 cmd,它后面可能有也可能没有行注释。试试这个,看看它是否有帮助。祝你好运!

只是小小的一行,让一切变得完美:在我的 MyParser.g4 中,只需输入:

options { tokenVocab = MyLexer; }

紧接着 parser grammar MYParser;...

为了找到这个小细节浪费了很多时间...:-(


(少数)其他不知道发生了什么的人的帖子,只是为了最终找到这个解决方案:

  • ANTLR: Lexer does not recognize token

  • mismatched Input when lexing and parsing with modes