java Main < входной файл не работает (Main — это класс Java для проверки грамматики ANTLR)

#java #error-handling #io #redirect #antlr3

#java #обработка ошибок #io #перенаправление #antlr3

Вопрос:

Я пытаюсь протестировать грамматику ANTLR с помощью такой стандартной тестовой установки

 import org.antlr.runtime.*;

 class Main {
  public static void main(String[] args) throws Exception {
    SampleLexer lexer = new SampleLexer(new ANTLRStringStream(args[0]));
    SampleParser parser = new SampleParser(new CommonTokenStream(lexer));
    parser.program();
  }
}
  

У меня есть тестовый файл с именем mytest00. Теперь я хочу использовать этот файл в качестве входных данных. Я полагаю, что здесь я делаю перенаправление ввода-вывода stardard.

    bash-3.2$ java Main < mytest00
  

Но это выдает мне такое сообщение об ошибке. В чем проблема, пожалуйста? Спасибо.

 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
    at Main.main(SampleTest.java:5)
  

Ответ №1:

Вы пытаетесь использовать args[0] , но на самом деле вы не передали никаких аргументов командной строки — вы просто перенаправили файл в стандартный ввод процесса. Итак, в массиве нет элементов, и вы получаете исключение, потому что пытаетесь получить первый элемент этого пустого массива.

На самом деле не совсем ясно, что вы на самом деле хотите ANTLRStringStream . Я подозреваю, что вы хотите ANTLRInputStream переносить System.in , если args.length == 0 и ANTLRFileStream(args[0]) в противном случае.

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

1. Извините, не могли бы вы, пожалуйста, быть более точным? Я действительно не могу это уловить. Что бы вы предложили сделать? Я думаю, что моя программа ожидает ввода через свой параметр arg [0], а стандартный ввод — это фактическое значение, которое примет arg [0]. Разве это не должно так работать?? Спасибо.

2. @zell: Нет, это не должно так работать. Существует большая разница между стандартным вводом программы и аргументами, используемыми для ее вызова. Что бы вы ожидали от него, если бы вы написали java Main foo bar < mytest00 ? В этом случае args было бы { "foo", "bar" } .

3. Спасибо, Джон. Но какой был бы аккуратный способ обработать мой входной файл как входные данные тестовой установки ANTLR? Спасибо. Для информации я использовал gunit для этой цели, но проблема gunit для меня в том, что он не предоставляет полезного сообщения об ошибке. Поэтому было бы неплохо иметь файл в качестве прямого ввода JAVA Main.

4. @zell: Как я уже сказал в своем ответе, я подозреваю, что вам нужен, ANTLRFileStream который позволяет вам передавать имя файла — или вы можете использовать ANTLRInputStream перенос System.in , если вы все еще хотите перенаправление stdin.

5. @zell, под «интерпретаторами ANTLR» вы, вероятно, имеете в виду интерпретатор в ANTLRWorks (это всего лишь один). Однако отладчик из ANTLRWorks работает идеально.

Ответ №2:

когда вы используете < в качестве параметра , ОС обрабатывает его как перенаправление ввода . поэтому он проверит это и не передаст аргумент java main()

Ответ №3:

Что означает исключение и как обычно обращаться с исключениями

 at Main.main(SampleTest.java:5)
  

Проблема появляется в 5 строке вашего кода, которая:

 SampleLexer lexer = new SampleLexer(new ANTLRStringStream(args[0]));
  

и исключением является:

 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
  

это означает, что вы пытаетесь извлечь 0-элемент из своего массива args , к массиву был получен доступ с недопустимым индексом, потому что массив пуст (размер = 0)


Пример решения

Вы хотите использовать этот конструктор:

 public ANTLRStringStream(String str)
  

Для этого вы можете:

  1. прочитайте стандартный ввод в некоторую строку
  2. передайте эту строку в ANTLRStringStream конструктор