Antlr4 lexer采取错误的规则

时间:2015-08-13 11:51:31

标签: antlr antlr4

我的语言包含的参数可以是无参数或带参数的命令,以及" 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"

"如果"只有当它是该行中的第一个非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,因为我需要。

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

2 个答案:

答案 0 :(得分:0)

在您的示例中,似乎没有定义语法的解析器规则。意思是没有规则指示寻找' if'和一个命令。

你的话发生了什么:

  

但是我的词法分析器将第3行标识为CMD:如果是cmd3,而不是像我需要的那样跟随cmd3

词法分析器规则CMD中的第一个选项是查找一个或多个字符("如果"),后跟空格' ',然后是LINE(cmd3)。 所以,输入"如果是cmd3"它匹配整条线,这正是你告诉它做的!

我可以从个人经验告诉你,即使是一种简单的语言,你也可以通过后退并回顾一些示例语法来快速学习很多,这就是我的意思如果我现在就是为了避免沮丧,那会怎么做。我高度推荐来自www.pragprog.com以及antlr网站的Antlr4参考书。

<强>已更新 我想这可能是你感兴趣的:

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,并且可能会有或没有跟随它的行注释。试试这个,看看它是否有用。祝你好运!

答案 1 :(得分:0)

只是一点点细线,让一切都变得完美:在MyParser.g4中,只需输入:

options { tokenVocab = MyLexer; }

parser grammar MYParser; ...

之后

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

(很少)其他人不知道发生了什么事,只是为了最终达到这个解决方案: