ANTLR NoViableAltException与JAVA [英] ANTLR NoViableAltException with JAVA

查看:186
本文介绍了ANTLR NoViableAltException与JAVA的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用antlrworks的语法中,对于诸如if的规则,我需要noviablealtexception,而规则需要相应的左右括号.但是,在Java中,我无法获得noviablealtexception.

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

下面是语句规则,

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

在发布此内容之前,我已经检查了一些示例.我认为我需要在每条规则的末尾添加EOF.当我为这些规则添加EOF时,会出现不同的错误.例如,

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

第6:0行在'a'处缺少EOF
当我从第一个"if"中删除第一个左括号时

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

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

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

第6:0行在'a'处缺少EOF
当我从第一个"while"中删除第一个左括号时

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

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

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

推荐答案

否,您需要将EOF放在主"解析器规则的末尾,而不是在多个语句之后.通过这样做,解析器期望在此类语句之后出现文件的结尾(当然这是不正确的).

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).

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

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.

这是一个演示(请注意parse规则后的EOF):

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

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:

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中删除(),则会出现以下(类似)错误:

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 '{'

这篇关于ANTLR NoViableAltException与JAVA的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆