ANTLR3 NoViableAltException

ANTLR3 NoViableAltException,antlr,antlr3,antlrworks,Antlr,Antlr3,Antlrworks,这是我语法中出错的部分: expr : func_name '(' constant (',' constant)* ')' ; constant : '"' (~'"')* '"'; WS : (' '|'\t')+ {skip();} ; 错误是关于文本的这一部分: "w9ygS99Qp_", "vuPfq6YcbX" ANTLRWorks的解释器为我提供了下一个叶子,其中有一个节点常量作为父节点: " w9ygS99Qp_", " 那么这是一个新

这是我语法中出错的部分:

expr : func_name '(' constant (',' constant)* ')' ;

constant
    :    '"' (~'"')* '"';

WS      :      (' '|'\t')+ {skip();} ;
错误是关于文本的这一部分:

"w9ygS99Qp_", "vuPfq6YcbX"
ANTLRWorks的解释器为我提供了下一个叶子,其中有一个节点常量作为父节点:

"
w9ygS99Qp_",
"
那么这是一个新的异常错误

通常情况下,它应具有以下特征:

"
w9ygS99Qp_
"

显然,问题是“之前的”,因为我试图抑制“之前的”,但是当解析器遇到下一个时,会出现相同的错误。您的
常量应该是lexer规则,而不是解析器规则。在解析器规则中,
~'“
匹配除双引号标记以外的任何标记。它不匹配除双引号字符以外的任何字符

改为这样做:

expr : func_name '(' Constant (',' Constant)* ')' ;

Constant
    :    '"' (~'"')* '"';

好的,因此我必须用Java编译语法,然后用Java测试它,如果我理解得好的话

是的,或者改用ANTLRWorks的调试器。调试器工作起来就像一个符咒

要在纯Java中进行测试,请执行以下操作:

import org.antlr.runtime.*;

public class Main {
  public static void main(String[] args) throws Exception {
    TLexer lexer = new TLexer(new ANTLRStringStream("name(\"w9ygS99Qp_\", \"vuPfq6YcbX\")"));
    TParser parser = new TParser(new CommonTokenStream(lexer));
    parser.expr();
  }
}

也许我应该使用ANTLR4,以便能够正确使用ANTLRWorks


如果您可以选择使用ANTLR3或ANTLR4,那么选择ANTLR4。注意,有一个新的(重写的)ANTLR4语法的版本:

AtLrWorks.x解释器是不可靠的,它不会产生与ANTLR 3相同语法的结果,所以你不应该考虑它的输出对于成功或错误的用例都有用。那么,我必须编译java中的语法,然后如果我理解得好,java就可以测试它吗?也许SH我可以使用ANTLR4吗,才能正确使用ANTLRWorks吗?你的建议很有效,但问题是我想要三个叶子,两个包含“,”和一个带有注释本身,一个单一的lexer规则不允许得到这个结果。你不可能合理地做到这一点,而不去你的lexer内部的大量混乱。最好的方法是按照我的建议去做,并通过执行
''(~'''''''')*''setText(getText().substring(1,getText().length()-1));
,或者在以后(遍历AST时)这样做,从标记中去掉引号
似乎生成了与前面相同的内容,“仍然在左边。@Pico,您可能仍在使用解释器:不要。是的,您是对的,抱歉。使用调试器,它可以工作。非常感谢您的帮助。