Как я могу создать простой валидатор ввода с помощью 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'