Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 复合规则的ANTLR求值_Java_Antlr - Fatal编程技术网

Java 复合规则的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 {

以下是我一直在研究的ANTLR语法的一个片段:

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:只需像现在这样动态地评估它。当您开始向语法中添加谓词(导致解析器从决策中回溯)时,可能是时候将解析与求值分开了。祝你好运