ANTLR : no viable alternative error

标签 antlr parser-generator

我有一个任务是编写简单的解析器生成器,所以我编写了类似 ANTLR 的语法并尝试解析像“foo:bar;”这样的简单文件,但得到了以下输出:

[@0,0:2='foo',<1>,1:0]
[@1,3:3=':',<16>,1:3]
[@2,4:6='bar',<1>,1:4]
[@3,7:7=';',<18>,1:7]
[@4,8:7='<EOF>',<-1>,1:8]
line 1:0 no viable alternative at input 'foo'
(rule foo : bar ;)

我的语法看起来像

grammar parsGen;

gram : rule SEMICOLON (NEWLINE+ rule SEMICOLON)* ;

rule : lRule | pRule ;

lRule : LRULEID COLON lRule1 ;
lRule1 : (((LRULEID | STRING | SET) | LBRACE lRule1 PIPE lRule1 RBRACE) modificator? SPACE+)+ ;

pRule : PRULEID COLON pRule1 ;
pRule1 : (((LRULEID | PRULEID) | LBRACE lRule1 PIPE lRule1 RBRACE) modificator? SPACE+)+ ;

modificator : PLUS | ASTERISK | QUESTION ;

ID : LRULEID | PRULEID ;

LRULEID : UPPERLETTER (UPPERLETTER | LOWERLETTER | DIGIT)* ;
PRULEID : LOWERLETTER (UPPERLETTER | LOWERLETTER | DIGIT)* ;

STRING : ('\''.*?'\'') ;
SET : '\''.*?'\'..\''.*?'\'' ;

UPPERLETTER : [A-Z] ;
LOWERLETTER : [a-z] ;
DIGIT : [0-9] ;

NEWLINE : '\r\n'|'\n'|'\r' ;

PLUS : '+' ;
ASTERISK : '*' ;
QUESTION : '?' ;

LBRACE : '(' ;
RBRACE : ')' ;

SPACE : ' ' ;

COLON : ':' ;

PIPE : '|' ;

SEMICOLON : ';' ;

那么我哪里可能会出错呢?我尝试到处搜索(谷歌,SO等)错误“没有可行的替代方案”,但这并没有真正帮助我。

最佳答案

ANTLR 词法分析器在使用解析器之前完全分配明确的标记类型。当多个标记类型可以匹配一个标记时,语法中出现的第一个标记就是使用的标记类型。对于您的语法,标记不能具有类型 ID和类型 LRULEID同时。自输入foo匹配这两个词法分析器规则,使用语法中第一个出现的规则,因此您的标记为:ID , COLON , ID , SEMICOLON , <EOF> .

ID解析器中从未实际引用 token,我建议进行以下更改之一。 这些选项中的任何一个都可以解决您所描述的问题,因此选择完全取决于您对最终语法外观的偏好。

前言

您需要更改 SPACE+ 的空间引用至SPACE* ,或者规则将要求 bar 之间至少有一个空格字符和; .

选项 1

删除ID词法分析器完全规则。

选项 2

  1. 更改 ID解析器规则,因此它不会尝试分配 token 类型 ID您的所有标识符。

    id : LRULEID | PRULEID;
    
  2. 更新pRule1通过引用 id 进行规则.

    pRule1 : ((id | LBRACE lRule1 PIPE lRule1 RBRACE) modificator? SPACE+)+ ;
    

不相关的旁注

如果删除最外面的 +,您的语法可能会更容易阅读lRule内的封闭和pRule1规则,而是将它们添加到规则引用本身中,如下所示。请注意,我更改了 SPACE引用文献如前言中所述。

lRule : LRULEID COLON lRule1+ ;
lRule1 : ((LRULEID | STRING | SET) | LBRACE lRule1 PIPE lRule1 RBRACE) modificator? SPACE* ;

pRule : PRULEID COLON pRule1+ ;
pRule1 : ((LRULEID | PRULEID) | LBRACE lRule1 PIPE lRule1 RBRACE) modificator? SPACE* ;

关于ANTLR : no viable alternative error,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16856963/

相关文章:

parser-generator - 基于 BNF 语法的 CMIS 查询解析器

java - 我如何解析代码以在 Java 中构建编译器?

java - 使用 BNF 的 Compiler 编译器

c# - C#/Python/Ruby 的表达式计算器

java - ANTLR:通过stringtemplate将修改后的AST翻译成java源码

algorithm - 如何使用解析树求解表达式?

java - ANTLR 4 中 while 循环的访问者/监听器代码

antlr - 安装 Antlr v4.4 的问题