2015-11-06 6 views
0

Я получаю ошибкуЯ получаю ошибку левой рекурсии в моем Antlr синтаксического анализа грамматике

[fatal] rule statement has non-LL(*) decision due to recursive rule invocations reachable from alts 6,7. Resolve by left-factoring or using syntactic predicates or using backtrack=true option. 

Я не знаю точно, какая часть моей грамматики бросает эту ошибку. и 1 других же ошибка для альта 3,4

parser grammar syn1; 

    options { 
     tokenVocab = lex1; 
     buildAST=true; 
    } 


    program : 
     statements 
     ; 

    statements : 
      statement (SEMICOLON^ statement)* 
     ; 

    statement : 
      variable ASSIGN^ exp 
     | SKIP 
     | IF^ boolexp THEN statement ELSE statement 
     | WHILE^ boolexp DO statement 
     | READ^ OPENPAREN! variable CLOSEPAREN! 
     | WRITE^ OPENPAREN! exp CLOSEPAREN! 
     | WRITE^ OPENPAREN! boolexp CLOSEPAREN! 
     | WRITE^ OPENPAREN! STRING CLOSEPAREN! 
     | WRITELN 
     | OPENPAREN! statements CLOSEPAREN! 
     ; 

    boolexp : 
      boolterm (AND^ boolterm)* 
     ; 

    boolterm : 
      NOT^ bool 
     | bool 
     ; 

    bool : 
      TRUE 
     | FALSE 
     | exp EQUALS^ exp 
     | exp LESSEQUALS^ exp 
     | OPENPAREN! boolexp CLOSEPAREN! 
     ; 

    exp : 
      term ((ADD | SUBTRACT)^ term)* 
     ; 

    term : 
      factor (MULTIPLY^ factor) * 
     ; 

    factor : 
      variable 
     | INTNUM 
     | OPENPAREN exp CLOSEPAREN 
     ; 

    variable : 
      IDENTIFIERS 
     ; 

Я не знаю, какая часть потребности переставляя, чтобы удалить левую рекурсию и был бы признателен, если кто-то может указать на это.

ответ

0

Проблема, как представляется, эти две альтернативы:

| WRITE^ OPENPAREN! exp CLOSEPAREN! 
    | WRITE^ OPENPAREN! boolexp CLOSEPAREN! 

Пример входы, которые вызывают рекурсию (то есть я могу повторить последнюю часть столько раз, сколько я хочу, и это по-прежнему действует префикс из этих двух правил):

  • WRITE (((((((((((...
  • WRITE (myVar + myVar + ...

В обоих случаях вы не можете знать, какую альтернативу выбрать, пока вы не увидите +, -, *, AND, NOT или )