Как я могу создать простой валидатор ввода с помощью ANTLR?

Я написал свою грамматику в ANTLRWorks, и она работала довольно хорошо, а затем я сгенерировал лексер и парсер.

Ну, код выполняется, и нет ошибки.

Но это сводит меня с ума даже при неправильном вводе все нормально. Я имею в виду, что parser.prog() выполняется просто отлично. Так где же информация, которую я должен получить в результате? Я просто хочу проверить вход, чтобы понять, что это логическое утверждение или нет?

Я использовал приведенный ниже код для генерации кода, но в нем были некоторые ошибки, например, он не может найти основной класс!

java antlr.jar org.antlr.Tool PropLogic.g

Но этот код работал:

java -cp antlr.jar org.antlr.Tool PropLogic.g

Вот грамматика:

    grammar PropLogic;

    NOT : '!' ;
    OR  : '+' ;
    AND : '.' ;
    IMPLIES : '->' ;
    SYMBOLS : ('a'..'z') | '~' ;
    OP : '(' ;
    CP : ')' ;

prog    : formula ;


formula : NOT formula
    | OP formula( AND formula CP | OR formula CP | IMPLIES formula CP)
    | SYMBOLS ;


WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+    { $channel = HIDDEN; } ;

Вот мой код:

import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CommonTokenStream;

public class Tableaux {

    public static void main(String[] args) throws Exception {

    ANTLRStringStream in = new ANTLRStringStream("a b c");
        PropLogicLexer lexer = new PropLogicLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        PropLogicParser parser = new PropLogicParser(tokens);
        parser.prog();
    }

}

1 ответ

Решение

Дан следующий тестовый класс:

import org.antlr.runtime.*;

public class Main {
  public static void main(String[] args) throws Exception {
    ANTLRStringStream in = new ANTLRStringStream(args[0]);
    PropLogicLexer lexer = new PropLogicLexer(in);
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    PropLogicParser parser = new PropLogicParser(tokens);
    parser.prog();
  }
}

который может быть вызван в *nix/MacOS следующим образом:

java -cp .:antlr-3.2.jar Main "a b c"

или на винде

java -cp .;antlr-3.2.jar Main "a b c"

не выдает никаких ошибок, потому что ваш парсер и лексер являются "контентом" с вводом. Лексер токенизирует вход в следующие 3 токена a, b а также c (пробелы игнорируются). И правило парсера:

prog
  :  formula 
  ;

соответствует одному formula что в свою очередь соответствует SYMBOLS маркер. Обратите внимание, что хотя вы назвали это SYMBOLS (множественное число), оно соответствует только одной строчной букве или тильде (~):

SYMBOLS : ('a'..'z') | '~' ;

Итак, короче говоря, из источника ввода "a b c", только a анализируется вашим парсером Вы, вероятно, хотите, чтобы ваш парсер использовал весь поток токенов, что можно сделать, добавив EOF (конец файла) токен после точки входа вашей грамматики:

prog
  :  formula EOF
  ;

Если вы снова запустите тестовый класс и предоставите "a b c" в качестве входных данных выдается следующая ошибка:

line 1:2 missing EOF at 'b'

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

Я проверил вашу грамматику, включая EOF маркер:

grammar PropLogic;

prog
  :  formula EOF
  ;

formula 
  :  NOT formula
  |  OP formula (AND formula CP | OR formula CP | IMPLIES formula CP)
  |  SYMBOLS
  ;

NOT : '!' ;
OR  : '+' ;
AND : '.' ;
IMPLIES : '->' ;
SYMBOLS : ('a'..'z') | '~' ;
OP : '(' ;
CP : ')' ;
WHITESPACE : ('\t' | ' ' | '\r' | '\n'| '\u000C')+ { $channel = HIDDEN; } ;

с классом, включая ANTLRStringStream:

import org.antlr.runtime.*;

public class Main {
  public static void main(String[] args) throws Exception {
    ANTLRStringStream in = new ANTLRStringStream("a b c");
    PropLogicLexer lexer = new PropLogicLexer(in);
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    PropLogicParser parser = new PropLogicParser(tokens);
    parser.prog();
  }
}

как с ANTLR 3.2, так и с ANTLR 3.3:

java -cp antlr-3.2.jar org.antlr.Tool PropLogic.g 
javac -cp antlr-3.2.jar *.java
java -cp.: antlr-3.2.jar Главная
в строке 1:2 отсутствует EOF на "b"

java -cp antlr-3.3.jar org.antlr.Tool PropLogic.g 
javac -cp antlr-3.3.jar *.java
java -cp .:antlr-3.3.jar Главная
в строке 1:2 отсутствует EOF на "b"

И, как вы можете видеть, оба выдают сообщение об ошибке:

line 1:2 missing EOF at 'b'
Другие вопросы по тегам