Как я могу создать простой валидатор ввода с помощью ANTLR? - PullRequest
2 голосов
/ 31 марта 2011

Я написал свою грамматику в 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 Ответ

1 голос
/ 01 апреля 2011

Учитывая следующий тестовый класс:

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"

или в Windows

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

не выдает никаких ошибок, потому что ваши парсер и lexer "довольны" вводом. Лексер токенизирует входные данные в следующие 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'

EDIT

Я проверил вашу грамматику, включая 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 Main
line 1:2 missing EOF at '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 Main
line 1:2 missing EOF at 'b'

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

line 1:2 missing EOF at 'b'
...