Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.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 if-then-else条件求值_Java_Antlr_Antlr3 - Fatal编程技术网

Java if-then-else条件求值

Java if-then-else条件求值,java,antlr,antlr3,Java,Antlr,Antlr3,我有一种语言,基本上是为了将列映射到数组中的新结构。该语言旨在让产品经理定义映射,而不必知道很多编程细节。我相信这里还有很多需要改进的地方,但这就是我所拥有的 大多数情况下,这种语言是有效的。我的问题是条件语句 我的解析器具有以下规则: conditionalexpr : IF^ LPAREN! (statement) RPAREN! THEN! LCURLY! statement RCURLY! (ELSE! LCURLY! statement RCURLY!)?; 它可以生成一个包含三个

我有一种语言,基本上是为了将列映射到数组中的新结构。该语言旨在让产品经理定义映射,而不必知道很多编程细节。我相信这里还有很多需要改进的地方,但这就是我所拥有的

大多数情况下,这种语言是有效的。我的问题是条件语句

我的解析器具有以下规则:

conditionalexpr :  IF^ LPAREN! (statement) RPAREN! THEN! LCURLY! statement RCURLY! (ELSE! LCURLY! statement RCURLY!)?;
它可以生成一个包含三个子树的树

我的问题是避免在条件不允许的情况下对语句求值

我很天真地做到了:

conditionalexpr returns[Object o]: 
  ^(IF a=statement b=statement (c=statement)?)
  {
    $o = (Boolean)$a.o ? $b.o : $c.o != null ? $c.o : "";
  }
  ;
显然,这是行不通的

我一直在玩弄语法谓词,但我不能让它们正常工作

语句返回当前的对象。该语言主要处理字符串,但我还需要支持布尔和数字(整数和十进制)

如果我添加类似{$a.o}的内容?=>我在生成的代码中得到$a

我已经看过了antlr的兴趣列表,但是这个问题在那里没有得到很好的回答,很可能是因为对他们来说这似乎是显而易见的


我愿意发布完整的语法,但为了保持简短,我省略了它。

如果您不想计算某些子树,则需要让树规则返回节点,而不是实际值。您可以扩展
CommonTree
并提供自定义
TreeAdaptor
来帮助构建您自己的节点,但就个人而言,我发现创建自定义节点类(或多个类)并使用它们最简单。演示说明:

T.g
语法T;
选择权{
输出=AST;
}
代币{
分配
}
作语法分析
:语句+EOF->语句+
;
陈述
:ifStatement
|分配
;
国际单项体育联合会声明
:如果a=表达式,则b=表达式(否则c=表达式)?->^(如果$a$b$c?)
;
分配
:ID'='表达式->^(分配ID表达式)
;
表达
:orExpression
;
表达
:andExpression(或^andExpression)*
;
andExpression
:equalityExpression(和^equalityExpression)*
;
等式表达式
:relationalExpression((“==”|“!=”)^relationalExpression)*
;
关系表达
:原子((“”)^原子)*
;
原子
:布尔值
|数
|身份证
|“(“表达式”)”->表达式
;
如果:‘如果’;
然后:"然后",;
ELSE:‘ELSE’;
或:‘或’;
和:'和';
布尔值:“真”|“假”;
ID:('a'..'z'|'a'..'z')+;
编号:'0'..'9'+('0'..'9'+)?;
空格:(“”|’\t’|’\r’|’\n’{skip();};
主类 我创建了一个
节点
接口,该接口有一个
eval():Object
方法,还创建了一个抽象类
BinaryNode
,它实现了
节点
,并且将始终有两个子类。正如您在这些Java类后面的树语法中所看到的,所有规则现在都返回一个
节点

import org.antlr.runtime.*;
导入org.antlr.runtime.tree.*;
公共班机{
公共静态void main(字符串[]args)引发异常{
String source=“a=3 b=4如果b>a,则b==b,否则c==c”;
TLexer lexer=新的TLexer(新的AntlStringStream(源));
TParser parser=newtparser(newcommontokenstream(lexer));
TWalker-walker=newtwalker(newcommontreenodestream(parser.parse().getTree());
节点根=walker.walk();
System.out.println(root.eval());
}
}
接口节点{
对象eval();
}
抽象类BinaryNode实现节点{
左保护节点;
受保护的节点权限;
公共二进制节点(节点l、节点r){
左=l;
右=r;
}
}
类AtomNode实现节点{
私人客体价值;
公共原子节点(对象v){
值=v;
}
@凌驾
公共对象eval(){
返回值;
}
}
类OrNode扩展了BinaryNode{
公共OrNode(节点左,节点右){super(左,右);}
@凌驾
公共对象eval(){
返回(布尔)super.left.eval()| |(布尔)super.right.eval();
}
}
类和节点扩展了BinaryNode{
公共AndNode(节点左,节点右){super(左,右);}
@凌驾
公共对象eval(){
返回(布尔)super.left.eval()&(布尔)super.right.eval();
}
}
类LTNode扩展了BinaryNode{
公共LTNode(节点左,节点右){super(左,右);}
@凌驾
公共对象eval(){
返回(双精度)super.left.eval()<(双精度)super.right.eval();
}
}
类LTEqNode扩展了BinaryNode{
公共LTEqNode(节点左,节点右){super(左,右);}
@凌驾
公共对象eval(){
返回(双精度)super.left.eval()(双精度)super.right.eval();
}
}
类GTEqNode扩展了BinaryNode{
公共GTEqNode(节点左,节点右){super(左,右);}
@凌驾
公共对象eval(){
返回(双精度)super.left.eval()>=(双精度)super.right.eval();
}
}
类EqNode扩展了BinaryNode{
公共EqNode(节点左,节点右){super(左,右);}
@凌驾
公共对象eval(){
返回super.left.eval().equals(super.right.eval());
}
}
类NEqNode扩展了BinaryNode{
公共NEqNode(节点左,节点右){super(左,右);}
@凌驾
公共对象eval(){
return!super.left.eval().equals(super.right.eval());
}
}
类VarNode实现节点{
私有java.util.Map内存;
私有字符串变量;
VarNode(java.util.Map m,字符串v){
内存=m;
var=v;
}
@凌驾
公共对象eval(){
对象值=memory.get(var);
如果(值==null){
抛出新的RuntimeException(“未知变量:”+var);
}
返回值;
}
}
类IfNode实现节点{
专用节点测试;
私有节点ifTrue;
私有节点ifFalse;
公共IfNode(节点a、节点b、节点c){
试验=a;
ifTrue=b;
ifFalse=c;
}
@凌驾
公共对象eval(){
返回(布尔)test.eval()?ifTrue.eval():ifFalse.eval();
}
}
吐尔克
树语法吐温;
选择权{
b=T;
ASTLabelType=CommonTree;
}
@成员{
私有java.util.Map内存=n
a = 3   
b = 4   
if b > a then 
  b==b 
else 
  c==c