ANTLR NoViableAltException с JAVA - PullRequest
       4

ANTLR NoViableAltException с JAVA

4 голосов
/ 09 октября 2011

В моей грамматике с antlrworks я могу получить исключение noviablealtexception для правил вроде if, для которых нужны соответствующие правая и левая скобки. Тем не менее, в 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 отсутствует EOF при 'a'
Когда я удаляю первую левую скобку из первого «если»

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

testcases / строка нового файла 3: 0 отсутствует EOF при 'if',
testcases / новая строка файла 6: 0 отсутствует EOF при 'a'

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

в строке 6: 0 отсутствует EOF при 'a'
Когда я убираю первую левую скобку с первого «пока»

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

testcases / новая строка файла 3: 0 отсутствует EOF при 'while'
testcases / new file line 6: 0 отсутствует EOF при 'a'

1 Ответ

2 голосов
/ 09 октября 2011

Нет, вам нужно ставить EOF в конце вашего "основного" правила синтаксического анализатора, а не после нескольких операторов.Таким образом, синтаксический анализатор ожидает конца файла после таких операторов (что, конечно, не правильно).

Я предполагаю, что ваша точка входа не содержит EOF, что заставляет синтаксический анализатор преждевременно останавливаться, вместо того, чтобы выдавать ошибку / исключение, когда он сталкивается с неверным вводом.EOF после правила parse):

Tg

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