我的语言有可以不带参数或带参数的命令,以及一个"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
(现在让我们忽略注释…)
// Parser Rules:
root: (lineComment | ifStat | cmd )* EOF;
lineComment : LC;
ifStat : IF;
cmd : CMD;
// Lexer Rules:
LC : '//' ~([nru2028u2029])* -> channel(HIDDEN); // line comment
IF : 'if';
CMD : [-_a-zA-Z0-9]+ GAP LINE
| [-_a-zA-Z0-9]+
;
fragment GAP : [ t]+;
fragment LINE : ~([nru2028u2029])*;
但是我的词法分析器将第三行标识为CMD
: if cmd3
,而不是我需要的if
和cmd3
。
我错在哪里?如何解决这个问题?
在您的示例中似乎没有定义语法的解析器规则。这意味着没有规则指示查找'if'和命令。
你的话里发生了什么?
但是我的词法分析器将第三行标识为CMD: if cmd3,而不是像我需要的那样后跟cmd3
词法分析器规则CMD中的第一个选项查找一个或多个字符("if"),后面跟着空格' ',后面跟着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 : ~([nru2028u2029])*;
NEWLINE : ('r')?'n';
我必须再说一次,如果你读了这本书(我读了),这可能会给你从解析器(不是词法分析器)得到预期的响应。ifStat是可选的(根据你的测试用例,可能有也可能没有),总是会有一个cmd,它后面可能有也可能没有行注释。尝试一下,看看是否有用。好运! 只是一小行,让一切变得完美:在我的MyParser.g4
中,只需要输入:
options { tokenVocab = MyLexer; }
紧接parser grammar MYParser;
…
(少数)其他不知道发生了什么的人的帖子,只是为了最终达成这个解决方案:
ANTLR: Lexer不识别令牌
使用模式进行词法分析时输入不匹配