使用JAVA的ANTLR NoViableAltException

时间:2011-10-09 07:27:23

标签: java exception-handling antlr

在我使用antlrworks的语法中,对于像if这样的规则,我可以得到noviablealtexception,而需要相应的右括号和左括号。但是,在java中,我无法获得noviablealtexception。

loop_statement: (WHILE LPAREN expr RPAREN statement)
        | (DO statement WHILE LPAREN expr RPAREN);

condition_statement 
      : IF LPAREN expr RPAREN statement (options {greedy=true;}: ELSE statement)?

在声明规则中,我有一个阻止规则,

statement_blocks
  :   (LBRACE statement* RBRACE) 
  ;

声明规则如下,

statement
  :  var_dec
    | statement_blocks 
    | condition_statement  
    | loop_statement
    | expr_statement 
;

在发布之前我已经检查了一些例子。我想我需要在每条规则的末尾添加EOF。当我为这些规则添加EOF时,我会得到不同的错误。例如,

loop_statement: ((WHILE LPAREN expr RPAREN statement)
    | (DO statement WHILE LPAREN expr RPAREN)) EOF;

condition_statement 
  : (
     (IF LPAREN expr RPAREN statement (options {greedy=true;}: ELSE statement)?
    )EOF

这些是我得到的以下输入;

if(s==d){
d=s;
if(a=n){
s=h;
}
a=g;
}

第6:0行'a'时缺少EOF 当我从第一个“if”

中删除第一个左括号时
if(s==d)
    d=s;
    if(a=n){
    s=h;
    }
    a=g;
    } 

测试用例/新文件行3:0在'if'处丢失EOF,
测试用例/新文件行6:0在'a'

时缺少EOF
 while(s==d){
    d=s;
    while(a=n){
    s=h;
    }
    a=g;
    }

第6:0行'a'时缺少EOF 当我从第一个“while”

中删除第一个左括号时
 while(s==d)
    d=s;
    while(a=n){
    s=h;
    }
    a=g;
    }

测试用例/新文件行3:0在'while'时缺少EOF 测试用例/新文件行6:0在'a'

时缺少EOF

1 个答案:

答案 0 :(得分:2)

不,您需要将EOF放在“主”解析器规则的末尾,而不是在多个语句之后。通过这样做,解析器期望在这样的语句之后文件结束(当然这是不正确的)。

我的猜测是你的入口点不包含EOF导致解析器过早停止而不是在无效输入时偶然发出错误/异常。

以下是演示(请注意EOF规则后的parse):

T.G

grammar T;

parse
  :  statement+ EOF
  ;

statement
  :  var_dec
  |  statement_blocks
  |  c=condition_statement {System.out.println("parsed :: " + $c.text);}
  ;

var_dec
  :  ID '=' ID ';'
  ;

statement_blocks
  :  LBRACE statement* RBRACE
  ;

condition_statement 
  :  IF LPAREN expr RPAREN statement (options {greedy=true;}: ELSE statement)?
  ;

expr
  :  ID '==' ID
  ;

IF     : 'if';
ELSE   : 'else';
ID     : 'a'..'z'+;
LBRACE : '{';
RBRACE : '}';
LPAREN : '(';
RPAREN : ')';
SPACE  : (' ' | '\t' | '\r' | '\n')+ {skip();};

可以在课堂上进行测试:

Main.java

import org.antlr.runtime.*;

public class Main {
  public static void main(String[] args) throws Exception {
    TLexer lexer = new TLexer(new ANTLRFileStream("in.txt"));
    TParser parser = new TParser(new CommonTokenStream(lexer));
    parser.parse();
  }
}

全部测试

如果您现在解析输入文件(in.txt):

if(s==d) {
  d=s;
  if(a==n){
    s=h;
  }
  a=g;
}

没有问题,你可以看到:

java -cp antlr-3.3.jar org.antlr.Tool T.g
javac -cp antlr-3.3.jar *.java
java -cp .:antlr-3.3.jar Main

parsed :: if(a==n){s=h;}
parsed :: if(s==d){d=s;if(a==n){s=h;}a=g;}

如果您从文件(中删除)in.txt,则会收到以下(类似)错误:

in.txt line 1:8 missing RPAREN at '{'