如何评估在运行时输入的“VERB1 OR(VERB2 AND VERB3)OR(VERB4)”等逻辑表达式。 VERB *是占位符来评估某些条件。例如,VERB1可能意味着检查数据库中是否存在记录。
在表达式“VERB1 OR(VERB2 AND VERB3)OR(VERB4)”中,如果VERB1为真,则不应执行其他动词
编辑:http://www.alittlemadness.com/2006/06/05/antlr-by-example-part-1-the-language/中描述的示例与我正在尝试的内容非常相似。但是,优化步骤(如果VERB1为真,则不应执行其他动词)似乎不存在。
答案 0 :(得分:1)
如果您可以使用||
和&&
代替AND
和OR
,则可以使用groovy缺少的属性方法和the GroovyShell base class setting,如下所示:
import org.codehaus.groovy.control.CompilerConfiguration
// The command to be executes
def command = "VERB1 || (VERB2 && VERB3) || (VERB4)"
// Set a base class for the GroovyShell
new CompilerConfiguration().with { compiler ->
compiler.scriptBaseClass = 'VerbHandlingBaseClass'
new GroovyShell( this.class.classLoader, new Binding(), compiler ).with { shell ->
// and evaluate the command
shell.evaluate( command )
}
}
abstract class VerbHandlingBaseClass extends Script {
boolean VERB1() {
System.out.println( 'CHECK THE DATABASE, RETURN FALSE' )
false
}
boolean VERB2() {
System.out.println( 'WRITE A LOG ENTRY RETURN TRUE' )
true
}
boolean VERB3() {
System.out.println( 'VALIDATE SOMETHING, RETURN TRUE' )
true
}
boolean VERB4() {
System.out.println( 'THIS WONT BE REACHED, AS VERB2 && VERB3 == true' )
true
}
def propertyMissing( String name ) {
"$name"()
}
}
那应该打印:
CHECK THE DATABASE, RETURN FALSE
WRITE A LOG ENTRY RETURN TRUE
VALIDATE SOMETHING, RETURN TRUE
答案 1 :(得分:0)
你在你的标签中提到过ANTLR:你有这个去过吗?你可以在ANTLR中创建一个完整的布尔语法,但是当你达到评估动词的水平时,它会变得更加困难。
如果有一小组固定的动词可以查询,你可以轻松地在动词和函数之间创建一个映射。
如果有更大的动词列表,您可以使用反射来调用特定方法来评估它们。
如果你的动词可以包含数学比较,那么当你创建一个数学词法分析器和解析器时,这一切都会变得更加困难。
如果没有更具体的问题和你在ANTLR中尝试过的知识,我不确定我能给你更多的建议。
编辑:根据您的评论,我会再添加一些内容。 您可以在语法中添加解析规则:
boolean_or returns [boolean b]
: b1=boolean_and {$b = $b1.b;}
(OR b2=boolean_and {$b = $b || $b2.b;})*
;
boolean_atom returns [boolean b]
:
((numeric_comparison)=> b1=numeric_comparison {$b = $b1.b;}
| TRUE {$b = true;} | FALSE {$b = false;}
| s1=VERB {$b = evalVerb($s1.s);}
| LPAREN b1=boolean_expr RPAREN {$b = $b1.b;}
)
;
这是我正在使用的布尔解析器的一小部分。你可以填空。
然后使用
之类的东西调用解析器ANTLRStringStream in = new ANTLRStringStream(booleanString);
ActionLexer lexer = new ActionLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
BooleanParser parser = new BooleanParser(tokens);
try {
return parser.eval();
} catch (Exception e) {
}
这并不能解释您提前返回的要求,但我相信您可以弄清楚如何做到这一点。
这可能不是最好的做事方式,但它是我过去为我工作的方式。希望这会有所帮助。