ANTLR NoViableAltException with JAVA

北慕城南 提交于 2019-12-23 12:43:08

问题


In my grammar with antlrworks, I can get noviablealtexception for rules like if, while which need corresponding right and left brackets. However, in java, i cannot get 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)?

In statement rule I have a block rule which is,

statement_blocks
  :   (LBRACE statement* RBRACE) 
  ;

And statement rule is below,

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

Before posting this I've checked some examples. I think i need to add EOF at the end of each rule. When I add EOF for those rules, I get different errors. For example,

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

These are what I get for the following inputs;

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

line 6:0 missing EOF at 'a'
When I remove the first left bracket from the first "if"

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

testcases/new file line 3:0 missing EOF at 'if',
testcases/new file line 6:0 missing EOF at 'a'

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

line 6:0 missing EOF at 'a'
When I remove the first left bracket from the first "while"

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

testcases/new file line 3:0 missing EOF at 'while'
testcases/new file line 6:0 missing EOF at 'a'


回答1:


No, you need to place EOF at the end of your "main" parser rule, not after more than one statement. By doing so, the parser expects the end of the file after such statements (which is not correct, of course).

My guess is that your entry point does not contain EOF causing the parser to stop prematurely instead of throwing an error/exception when it stumbles upon invalid input.

Here's a demo (note the EOF after the parse rule):

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();};

which can be tested with the class:

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();
  }
}

Testing it all

If you now parse the input file (in.txt):

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

there's no problem, as you can see:

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;}

And if you remove a ( or ) from the file in.txt, you will get the following (similar) error:

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


来源:https://stackoverflow.com/questions/7702048/antlr-noviablealtexception-with-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!