Java 如何使用ANTLR创建一个简单的输入验证器?
我用ANTLRWorks编写语法,它运行得很好,然后我生成了lexer和parser 代码执行了,没有错误 但即使输入错误,也会让我发疯,一切都很好。我的意思是Java 如何使用ANTLR创建一个简单的输入验证器?,java,antlr,validation,antlr3,Java,Antlr,Validation,Antlr3,我用ANTLRWorks编写语法,它运行得很好,然后我生成了lexer和parser 代码执行了,没有错误 但即使输入错误,也会让我发疯,一切都很好。我的意思是parser.prog()执行得很好。那么,作为结果,我应该得到的信息在哪里呢?我只想检查输入,弄清楚它是否是一个命题逻辑语句 我使用下面的代码生成代码,但它有一些错误,比如找不到主类 java antlr.jar org.antlr.Tool PropLogic.g 但这一准则起了作用: java -cp antlr.jar org.
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();
}
}
给定以下测试类别:
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"
不会产生任何错误,因为您的解析器和词法分析器是输入的“内容”。lexer将输入标记为以下3个标记a
、b
和c
(空格被忽略)。和解析器规则:
prog
: formula
;
匹配单个公式
,该公式依次匹配符号
标记。请注意,尽管您将其命名为符号
(复数),但它只匹配一个小写字母或波浪号(~
):
因此,简而言之,从输入源“abc”
,解析器只解析a
。您可能希望解析器使用整个令牌流,这可以通过在语法入口点之后添加EOF
(文件结尾)令牌来实现:
prog
: formula EOF
;
如果再次运行测试类并提供“ab 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; } ;
该类包括AntlStringStream
:
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'
“你的语法一定有问题。”杰里米·海勒,可能恰恰相反@Amirh,如果在解析您的输入后,控制台上没有打印任何内容,这意味着您的解析器在所述输入中没有发现任何错误。如果希望解析器实际执行某些操作(返回一个
布尔值或向STDOUT显示一条日志消息),则必须指示它这样做。也许你想发布你的语法,你正在解析的输入,以及你的期望,或者希望得到回报。@Jeremy Heiler,嗯,antlrworks说语法是可以的。我生成了lexer和parser,没有任何错误@Bart Kiers和任何输入解析器都不会向控制台生成任何输出。@Amirh:“无错误”是什么意思?你确保你的语法正确吗?另外,正如@Bart所说,当输入不正确时,您是否指示解析器输出任何内容?@jeremyheiler。不,但它似乎对输入没有任何影响。顺便说一句,我编辑了问题,你可以看到语法。非常感谢你,我还没有测试它,但是你已经添加了我的知识。@Amirh,不客气。如果有什么不清楚的地方,或者没有达到你的预期效果(当然,也可以提出一个新问题!),请随时发回。祝你好运事实上,我测试了“abc”,控制台里什么也并没有。顺便说一句我只需要一个字符串变量作为AntlStringStream的输入。在这种情况下我不使用命令行。@Bart Kiers,谢谢你的时间,但我遇到了一些困难:(@Amirh,嗯,我解释了为什么“abc”
不会产生错误。或者你是说即使包含EOF标记,你也不会出现任何错误?我觉得很难相信……在后一种情况下,请编辑你的原始问题并发布1)你使用的确切语法,2)您用来测试解析器的Java类,3)告诉我您使用的ANTLR的版本。
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'