ANTLR - недетерминированное поведение во время запуска / отладки - PullRequest
1 голос
/ 27 января 2012

Я пытаюсь использовать ANTLR (пробовал 3.3 и 3.4). Странная вещь случается, когда я пытаюсь запустить свой тестовый код. Пожалуйста, сначала посмотрите мой очень простой код, потом я объясню свою проблему.

Тестовая грамматика:

lexer grammar CSVLexer;
Comma 
  :  ','
  ;
LineBreak
  :  '\r'? '\n'
  |  '\r'
  ;
SimpleValue
  :  ~(',' | '\r' | '\n' | '"')+
  ;
QuotedValue
  :  '"' ('""' | ~'"')* '"'
  ;

Тестовый код:

import org.antlr.runtime.*;
public class JMain {
    public static void main(String[] args) throws Exception {
        String source = "val1,val2,val3";
        CSVLexer lexer = new CSVLexer(new ANTLRStringStream(source));
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        int n = 1;
        for (Object o : tokens.getTokens()) {
            CommonToken token = (CommonToken) o;
            System.out.println("token(" + n + ") = " + token.getText().replace("\n", "\\n"));
            n++;
        }
    }
}

Compiation:

$ export CLASSPATH=antlr3.jar
$ java org.antlr.Tool CSVLexer.g
$ javac *.java
$ java JMain

Первая проблема в том, что он ничего не печатает :). Я работаю в Intellij IDEA (10), и я безуспешно пытался запустить код отсюда (с ANTLR в CLASSPATH). ОДНАКО, если я установлю точку останова на int i = 1, отладлю и подожду, скажем 1-3 секунды, прежде чем продолжить, это работает! Если я запускаю его в режиме отладки без точки останова, это не так. Может кто-нибудь объяснить мне, в чем может быть проблема? Спасибо.

РЕДАКТИРОВАТЬ:

Итак, я попробовал ту поставить:

tokens.fill()

сразу после

CommonTokenStream tokens = new CommonTokenStream(lexer);

и это сработало. Однако затем я начал отлаживать конструктор CommonTokenStream (несколько минут), и когда я включил tokens.fill(), я получил IndexOutOfBoundException. Так что что-то в фоновом режиме что-то сделало, но я не вижу других потоков в IDEA.

EDIT2:

Проблема решена. Похоже, что сначала нужно вызвать fill() и что BufferedTokenStream, вероятно, не предназначено для такого использования. Я следовал этому уроку http://bkiers.blogspot.com/2011/03/2-introduction-to-antlr.html, где он, вероятно, как-то работал на автора (интересно почему). Отладчик IntelliJ IDEA вызывал toString() для локальных объектов, а он в свою очередь вызывал fill(), поэтому он работал, когда я устанавливал точку останова. toString() Модифицирующее состояние - зло!

...