Java 复合规则的ANTLR求值
以下是我一直在研究的ANTLR语法的一个片段:Java 复合规则的ANTLR求值,java,antlr,Java,Antlr,以下是我一直在研究的ANTLR语法的一个片段: compoundEvaluation returns [boolean evalResult] : singleEvaluation (('AND'|'OR') singleEvaluation)* ; //overall rule to evaluate a single expression singleEvaluation returns [boolean evalResult] : simpleStringEvaluation {
compoundEvaluation returns [boolean evalResult]
: singleEvaluation (('AND'|'OR') singleEvaluation)*
;
//overall rule to evaluate a single expression
singleEvaluation returns [boolean evalResult]
: simpleStringEvaluation {$evalResult = $simpleStringEvaluation.evalResult;}
| stringEvaluation {$evalResult = $stringEvaluation.evalResult;}
| simpleDateEvaluation {$evalResult = $simpleDateEvaluation.evalResult;}
| dateEvaluatorWithModifier1 {$evalResult = $dateEvaluatorWithModifier1.evalResult;}
| dateEvaluatorWithoutModifier1 {$evalResult = $dateEvaluatorWithoutModifier1.evalResult;}
| simpleIntegerEvaluator {$evalResult = $simpleIntegerEvaluator.evalResult;}
| integerEvaluator {$evalResult = $integerEvaluator.evalResult;}
| integerEvaluatorWithModifier {$evalResult = $integerEvaluatorWithModifier.evalResult;}
;
下面是其中一个评估规则的示例:
simpleStringEvaluation returns [boolean evalResult]
: op1=STR_FIELD_IDENTIFIER operator=(EQ|NE) '"'? op2=(SINGLE_VALUE|INTEGER) '"'?
{
// I don't want these to be equal by default
String op1Value = op1.getText();
String op2Value = op2.getText();
try {
// get the values of the bean property specified by the value of op1 and op2
op1Value = BeanUtils.getProperty(policy,op1.getText());
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
String strOperator = operator.getText();
if (strOperator.equals("=")) {
evalResult = op1Value.equals(op2Value);
}
if (strOperator.equals("<>")) {
evalResult = !op1Value.equals(op2Value);
}
}
;
simpleStringEvaluation返回[boolean evalResult]
:op1=STR_字段|标识符运算符=(EQ | NE)“”?op2=(单值|整数)“?”?
{
//我不希望这些默认值相等
字符串op1Value=op1.getText();
字符串op2Value=op2.getText();
试一试{
//获取由op1和op2的值指定的bean属性的值
op1Value=BeanUtils.getProperty(策略,op1.getText());
}捕获(无此方法例外){
e、 printStackTrace();
}捕获(调用TargetException e){
e、 printStackTrace();
}捕获(非法访问例外e){
e、 printStackTrace();
}
字符串strOperator=operator.getText();
if(strOperator.equals(“=”){
evalResult=op1Value.equals(op2Value);
}
if(strOperator.equals(“”){
evalResult=!op1Value.equals(op2Value);
}
}
;
显然,我是一个新手,因为我没有构建树,但是代码是有效的,所以我对它相当满意。但是,下一步是对多个单计算语句执行逻辑计算。由于我将代码嵌入到语法中,所以我希望有人能为我指出正确的方向,以找出如何计算0个或更多结果。以下是我的做法。我创建了一个集合作为成员,然后在每个语句的@init中重新初始化集合。在对语句求值时,它填充了集合。因为集合的唯一合法值是true或false,所以我最终得到了一个包含0、1或两个成员的集合 OR评估如下所示:
compoundOrEvaluation returns [boolean evalResult]
@init {evaluationResults = new HashSet<Boolean>();}
: a=singleEvaluation {evaluationResults.add($a.evalResult);} (('OR') b=singleEvaluation {evaluationResults.add($b.evalResult);})+
{
if (evaluationResults.size()==1) {
evalResult = evaluationResults.contains(true);
} else {
evalResult = true;
}
}
;
compoundOrEvaluation returns [boolean evalResult]
: a=singleEvaluation { $evalResult = $a.evalResult; }
( ('OR') b=singleEvaluation { $evalResult ||= $b.evalResult; } )*
;
compoundOrEvaluation返回[boolean evalResult]
@init{evaluationResults=new HashSet();}
:a=singleEvaluation{evaluationResults.add($a.evalResult);}(('OR')b=singleEvaluation{evaluationResults.add($b.evalResult);})+
{
if(evaluationResults.size()==1){
evalResult=evaluationResults.contains(true);
}否则{
evalResult=true;
}
}
;
AND求值仅在else语句中不同,其中evalResult将设置为false。到目前为止,它通过了我可以进行的单元测试
最终,我可能会使用一个树和一个visitor类,但代码目前可以正常工作。下面是我如何做到的。我创建了一个集合作为成员,然后在每个语句的@init中重新初始化集合。在对语句求值时,它填充了集合。因为集合的唯一合法值是true或false,所以我最终得到了一个包含0、1或两个成员的集合 OR评估如下所示:
compoundOrEvaluation returns [boolean evalResult]
@init {evaluationResults = new HashSet<Boolean>();}
: a=singleEvaluation {evaluationResults.add($a.evalResult);} (('OR') b=singleEvaluation {evaluationResults.add($b.evalResult);})+
{
if (evaluationResults.size()==1) {
evalResult = evaluationResults.contains(true);
} else {
evalResult = true;
}
}
;
compoundOrEvaluation returns [boolean evalResult]
: a=singleEvaluation { $evalResult = $a.evalResult; }
( ('OR') b=singleEvaluation { $evalResult ||= $b.evalResult; } )*
;
compoundOrEvaluation返回[boolean evalResult]
@init{evaluationResults=new HashSet();}
:a=singleEvaluation{evaluationResults.add($a.evalResult);}(('OR')b=singleEvaluation{evaluationResults.add($b.evalResult);})+
{
if(evaluationResults.size()==1){
evalResult=evaluationResults.contains(true);
}否则{
evalResult=true;
}
}
;
AND求值仅在else语句中不同,其中evalResult将设置为false。到目前为止,它通过了我可以进行的单元测试
最终我可能会使用一个树和一个visitor类,但代码目前可以工作。不需要将值存储在一个集合中 为什么不干脆这样做:
compoundOrEvaluation returns [boolean evalResult]
@init {evaluationResults = new HashSet<Boolean>();}
: a=singleEvaluation {evaluationResults.add($a.evalResult);} (('OR') b=singleEvaluation {evaluationResults.add($b.evalResult);})+
{
if (evaluationResults.size()==1) {
evalResult = evaluationResults.contains(true);
} else {
evalResult = true;
}
}
;
compoundOrEvaluation returns [boolean evalResult]
: a=singleEvaluation { $evalResult = $a.evalResult; }
( ('OR') b=singleEvaluation { $evalResult ||= $b.evalResult; } )*
;
?无需将值存储在一个集合中 为什么不干脆这样做:
compoundOrEvaluation returns [boolean evalResult]
@init {evaluationResults = new HashSet<Boolean>();}
: a=singleEvaluation {evaluationResults.add($a.evalResult);} (('OR') b=singleEvaluation {evaluationResults.add($b.evalResult);})+
{
if (evaluationResults.size()==1) {
evalResult = evaluationResults.contains(true);
} else {
evalResult = true;
}
}
;
compoundOrEvaluation returns [boolean evalResult]
: a=singleEvaluation { $evalResult = $a.evalResult; }
( ('OR') b=singleEvaluation { $evalResult ||= $b.evalResult; } )*
;
?@Jason,很酷。只要意识到,如果你的语法相对简单,就不需要构建一个单独的AST:只需像现在这样动态地评估它。当您开始向语法中添加谓词(导致解析器从决策中回溯)时,可能是时候将解析与求值分开了。祝你好运。@Jason,酷。只要意识到,如果你的语法相对简单,就不需要构建一个单独的AST:只需像现在这样动态地评估它。当您开始向语法中添加谓词(导致解析器从决策中回溯)时,可能是时候将解析与求值分开了。祝你好运