ANTLR NoViableAltException 与 JAVA [英] ANTLR NoViableAltException with JAVA

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

问题描述

在我使用 antlrworks 的语法中,我可以为 if、while 等需要相应的左右括号的规则获得 noviablealexception.但是,在 Java 中,我无法获得 noviablealexception.

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

 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

推荐答案

不,您需要将 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();};

可以用类进行测试:

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天全站免登陆