我的语言包含的参数可以是无参数或带参数的命令,以及" 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行标识为CMD
:if cmd3
,而不是if
,后跟cmd3
,因为我需要。
我的错误是什么?如何解决?
答案 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;
...
为了找到这个小细节,浪费了太多时间......: - (
(很少)其他人不知道发生了什么事,只是为了最终达到这个解决方案: