2015-08-13 53 views
0

我的语言具有可参数小于或带有参数的命令,并在“如果”的文章:Antlr4词法采取错误的规则

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字符串(让我们暂时忽略注释...)

这些是我的语法规则: 语法TestFlow;作为if其次if cmd3,而不是由cmd3因为我需要:

// 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

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

回答

0

您的示例中似乎没有解析器规则来定义语法。意思是没有规则表示寻找'如果'和一个命令。

什么是你的话发生的事情:

但我的词法分析器识别3号线为CMD:如果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 : ~([\n\r\u2028\u2029])*; 
NEWLINE  : ('\r')?'\n'; 

同样,我必须说,如果你读的书(我做了),这可能会给你预期的响应从你的解析器(而不是词法分析器)。 ifStat是可选的(根据您的测试用例,可能不存在),总是会有一个cmd,并且可能有或者可能没有后面的行注释。尝试一下,看看它是否有帮助。祝你好运!

+0

我最初排除了解析器规则,因为在我看来,这是一个词法分析器问题。无论如何,如果有帮助,我更新了我的问题以包含解析器规则。第二件事:'IF'规则出现在'CMD'之前,所以我认为它优先。 – Tar

+0

如果你提到的是“The Definitive ANTLR4 Reference”这本书,那么我就是这样写的,但这不是一本很好的“入门”教程。 – Tar

+0

'root:((ifStat)?cmd(lineComment)?)* EOF;'也不起作用。问题是'如果cmd3'出现在'commonTokenStream.getTokens()'所得的单个令牌中。所以如果它是一个单一的标记,这就是解析器从词法分析器得到的东西,它不能将它们分开。这就是为什么我认为这是一个词法分析器问题,而不是解析器 – Tar