Antlr grun 错误 - 没有可行的替代输入

Antlr grun error - no viable alternative input at

我正在尝试为 Prolog 解释器编写语法。当我从命令行 运行 g运行 输入“父亲(约翰,玛丽)”时,我收到一条消息说“'father(john,' 没有可行的输入”,但我没有知道为什么。我在我的语法中尝试了 rear运行ging 规则,使用了不同的入口点等,但仍然得到同样的错误。我什至不确定它是由我的语法还是其他类似 antlr 本身引起的。谁能指出我的语法有什么问题,或者想想如果不是语法问题可能是什么原因?

我运行的命令是:

antlr4 -no-listener -visitor Expr.g4

javac *.java

grun antlr.Expr start tests/test.txt -gui

这是生成的解析树:

这是我的语法:

grammar Expr;

@header{
    package antlr;
}

//start rule
start       : (program | query) EOF
            ;
            
program     : (rule_ '.')*
            ;

query       : conjunction '?'
            ;

rule_       : compound
            | compound ':-' conjunction
            ;

conjunction : compound
            | compound ',' conjunction
            ;
            
compound    : Atom '(' elements ')'         
            | '.(' elements ')'             
            ;

list        : '[]'
            | '[' element ']'           
            | '[' elements ']'          
            ;
            
element     : Term
            | list
            | compound
            ;           

elements    : element
            | element ',' elements
            ;
            
WS          : [ \t\r\n]+ -> skip ;

Atom        : [a-z]([a-z]|[A-Z]|[0-9]|'_')*
            | '0' 
            ;

Var         : [A-Z]([a-z]|[A-Z]|[0-9]|'_')*
            ;

Term        : Atom
            | Var
            ;

词法分析器将始终为任何输入生成相同的标记。词法分析器不会“监听”解析器试图匹配的内容。词法分析器应用的规则非常简单:

  1. 尝试匹配尽可能多的字符
  2. 当 2 个或多个词法分析器规则匹配相同数量的字符时,让规则首先定义为“win”

因为第二条规则,规则Term永远不会被匹配。将 Term 规则移动到 VarAtom 之上将导致后面的规则永远不会匹配。解决方案:将 Term 规则“提升”为解析器规则:

start       : (program | query) EOF
            ;

program     : (rule_ '.')*
            ;

query       : conjunction '?'
            ;

rule_       : compound (':-' conjunction)?
            ;

conjunction : compound (',' conjunction)?
            ;

compound    : Atom '(' elements ')'
            | '.' '(' elements ')'
            ;

list        : '[' elements? ']'
            ;

element     : term
            | list
            | compound
            ;

elements    : element (',' element)*
            ;

term        : Atom
            | Var
            ;

WS          : [ \t\r\n]+ -> skip ;

Atom        : [a-z] [a-zA-Z0-9_]*
            | '0'
            ;

Var         : [A-Z] [a-zA-Z0-9_]*
            ;