Токен строкового литерала генерирует исключение MismatchedTokenException с токеном escape-последовательности

#antlr #antlr3

#antlr #antlr3

Вопрос:

В настоящее время я пытаюсь реализовать анализатор Antlr.
Я получаю странное исключение MismatchedTokenException в токене, который идентифицирует строковые литералы, как только я добавляю поддержку escape-последовательности.

Ниже приведен пример анализатора Antlr, который вызывает проблему:

 rule: STRING_LITERAL ;

STRING_LITERAL
  :
  '"' STRING_GUTS '"'
  ;

fragment
STRING_GUTS
  :
  ( ESC | ~('\' | '"') )*
  ;

ESC
  :
  '\'
  ( '\' | '"' )
  ;
  

Вы видели какую-либо проблему в этом коде?

Обратите внимание, что если я удаляю ESC из STRING_GUTS , синтаксический анализ строки работает хорошо…

Ответ №1:

Вам нужно будет опубликовать входные данные, с которыми вы получаете эту ошибку, версию ANTLR, которую вы используете, и способ выполнения ваших тестов, потому что я не вижу проблем с этой грамматикой, как вы можете видеть:

T.g

 grammar T;

rule
  :  STRING_LITERAL {System.out.println("parsed : "   $STRING_LITERAL.text);}
  ;

STRING_LITERAL 
  :  '"' STRING_GUTS '"'
  ;

fragment
STRING_GUTS
  :  (ESC | ~('\' | '"'))*
  ;

// also a fragment rule perhaps?
ESC
  :  '\' ('\' | '"')
  ;
  

Main.java

 import org.antlr.runtime.*;

public class Main {
  public static void main(String[] args) throws Exception {
    String src = ""a\"b\\c"";
    TLexer lexer = new TLexer(new ANTLRStringStream(src));
    TParser parser = new TParser(new CommonTokenStream(lexer));
    System.out.println("src    : "   src);
    parser.rule();
  }
}
  

Если я сгенерирую лексер и синтаксический анализатор из вашей грамматики (1), скомпилируйте все исходные файлы java (2) и запустите основной класс (3):

 java -cp antlr-3.3.jar org.antlr.Tool T.g    # 1
javac -cp antlr-3.3.jar *.java               # 2
java -cp .;antlr-3.3.jar Main                # 3
  

На консоль выводится следующее:

 src    : "a"b\c"
parsed : "a"b\c"
  

Т.е.: входные src данные обрабатываются, как и ожидалось.

Если вы столкнулись с проблемами с интерпретатором ANTLRWorks: не используйте его, он немного глючит. Либо используйте отладчик ANTLRWorks, либо используйте пользовательский класс, как я сделал выше.

Комментарии:

1. Вы были правы, я тестировал с помощью отладчика antlrworks, и он хорошо разбирается. Есть идеи, почему один и тот же код не работает через интерпретаторы подключаемого модуля antlrworks или antlr IDE Eclipse?

2. @greydet, интерпретатор ANTLRWorks просто глючит. А плагин Eclipse использует интерпретатор ANTLRWorks, AFAIK.

3. Есть ли какой-либо другой инструмент «менее глючный», помогающий в создании анализатора antlr? Спасибо за помощь

4. Отладчик ANTLRWorks отлично работает (но я уже упоминал об этом в своем ответе). И пожалуйста.

5. Итак, если мы пойдем путем antlrworks debugger, можно ли использовать его без генерации и компиляции результирующего кода? На самом деле, какова наилучшая практика в дизайне синтаксического анализатора, чтобы он не зависел от пользовательского кода, который обрабатывает результат синтаксического анализа?