2013-08-27 4 views
2

Когда я обновился с Antlr 3 до Antlr 4, я удалил все синтаксические предикаты в грамматике. Но когда я изменил его, я получаю сообщение об ошибке, как упоминалось в названии.Ошибка - действие в правиле lexer «xxxx» должно быть последним элементом одного внешнего внешнего.

Это измененный код

NUMBER 
    :(
     '0'..'9' ('.' '0'..'9'+)? 
    | '.' '0'..'9'+ 
    ) 
    (
     E 
     (
       M  { $type = EMS;   } 
      | X  { $type = EXS;   } 
     ) 
    | P 
     (
       X  
      | T 
      | C 
     ) 
        { $type = LENGTH;  } 
    | C M   { $type = LENGTH;  } 
    | M 
     (
       M  { $type = LENGTH;  } 

      | S  { $type = TIME;   } 
     ) 
    | I N   { $type = LENGTH;  } 

    | D E G  { $type = ANGLE;  } 
    | R A D  { $type = ANGLE;  } 

    | S   { $type = TIME;   } 

    | K? H Z { $type = FREQ;   } 

    | IDENT   { $type = DIMENSION; } 

    | '%'   { $type = PERCENTAGE; } 

    | // Just a number 
    ) 
; 

Это ошибка я получаю. enter image description here

Я увидел ответ на этот вопрос here. Но я не мог понять, что это значит. Пожалуйста, дайте мне несколько советов.

EDIT: появляется

же здесь ошибка в грамматике.

fragment INVALID :; 
    STRING   : '\'' (~('\n'|'\r'|'\f'|'\''))* 
        (

          '\'' 
          | { $type = INVALID; } 
        ) 

       | '"' (~('\n'|'\r'|'\f'|'"'))* 
        (
         '"' 
         | { $type = INVALID; } 
        ) 
       ; 

Мне не удалось изменить это на ANTLR 4. Что нового в этом коде? Пожалуйста, дайте мне быстрое решение для этого.

ответ

1

Ваше правило NUMBER было тяжело вручную левым. На самом деле это одно правило лексера, которое создает 9 различных типов токенов. Вероятно, левый факторинг выполнялся из-за того, как ANTLR 3 lexers используют предсказание с помощью рекурсивного анализатора спуска. ANTLR 4 использует полностью различный алгоритм лексера, основанный на DFA. Ошибка, которую вы видите, является результатом этого изменения - поскольку лексеры ANTLR 4 больше не рекурсивно-спускающие синтаксические анализаторы, у них больше нет возможности выполнять код действия в произвольных точках.

Наиболее эффективным способом написания вышеуказанного правила в ANTLR 4 является использование «неэффективного» синтаксиса ANTLR 3. В ANTLR 4 он не будет медленным.

EMS 
    : NUMBER E M 
    ; 
EXS 
    : NUMBER E X 
    ; 
LENGTH 
    : NUMBER P X 
    | NUMBER P T 
    | NUMBER P C 
    | NUMBER C M 
    | NUMBER M M 
    | NUMBER I N 
    ; 
TIME 
    : NUMBER M S 
    | NUMBER S 
    ; 
ANGLE 
    : NUMBER D E G 
    | NUMBER R A D 
    ; 
FREQ 
    : NUMBER K? H Z 
    ; 
DIMENSION 
    : NUMBER IDENT 
    ; 
PERCENTAGE 
    : NUMBER '%' 
    ; 
NUMBER 
    : [0-9] ('.' [0-9]+)? 
    | '.' [0-9]+ 
    ; 
+0

Еще раз спасибо за большую помощь. Я снова поражен той же ошибкой, но с той же ошибкой. Как я могу разрешить это с помощью нового синтаксиса. –