package org.openflexo.antar.expr.parser; import java.util.Hashtable; import org.openflexo.antar.expr.ArithmeticBinaryOperator; import org.openflexo.antar.expr.ArithmeticUnaryOperator; import org.openflexo.antar.expr.BinaryOperatorExpression; import org.openflexo.antar.expr.BindingValueAsExpression; import org.openflexo.antar.expr.BooleanBinaryOperator; import org.openflexo.antar.expr.BooleanUnaryOperator; import org.openflexo.antar.expr.ConditionalExpression; import org.openflexo.antar.expr.Constant.BooleanConstant; import org.openflexo.antar.expr.Constant.FloatConstant; import org.openflexo.antar.expr.Constant.FloatSymbolicConstant; import org.openflexo.antar.expr.Constant.IntegerConstant; import org.openflexo.antar.expr.Constant.ObjectSymbolicConstant; import org.openflexo.antar.expr.Constant.StringConstant; import org.openflexo.antar.expr.Expression; import org.openflexo.antar.expr.UnaryOperatorExpression; import org.openflexo.antar.expr.parser.analysis.DepthFirstAdapter; import org.openflexo.antar.expr.parser.node.AAcosFuncFunction; import org.openflexo.antar.expr.parser.node.AAddExprExpr2; import org.openflexo.antar.expr.parser.node.AAnd2ExprExpr3; import org.openflexo.antar.expr.parser.node.AAndExprExpr3; import org.openflexo.antar.expr.parser.node.AAsinFuncFunction; import org.openflexo.antar.expr.parser.node.AAtanFuncFunction; import org.openflexo.antar.expr.parser.node.ABindingTerm; import org.openflexo.antar.expr.parser.node.ACharsValueTerm; import org.openflexo.antar.expr.parser.node.ACondExprExpr; import org.openflexo.antar.expr.parser.node.AConstantNumber; import org.openflexo.antar.expr.parser.node.ACosFuncFunction; import org.openflexo.antar.expr.parser.node.ADecimalNumberNumber; import org.openflexo.antar.expr.parser.node.ADivExprExpr3; import org.openflexo.antar.expr.parser.node.AEq2ExprExpr; import org.openflexo.antar.expr.parser.node.AEqExprExpr; import org.openflexo.antar.expr.parser.node.AExpFuncFunction; import org.openflexo.antar.expr.parser.node.AExpr2Expr; import org.openflexo.antar.expr.parser.node.AExpr3Expr2; import org.openflexo.antar.expr.parser.node.AExprTerm; import org.openflexo.antar.expr.parser.node.AFalseConstant; import org.openflexo.antar.expr.parser.node.AFunctionTerm; import org.openflexo.antar.expr.parser.node.AGtExprExpr; import org.openflexo.antar.expr.parser.node.AGteExprExpr; import org.openflexo.antar.expr.parser.node.ALogFuncFunction; import org.openflexo.antar.expr.parser.node.ALtExprExpr; import org.openflexo.antar.expr.parser.node.ALteExprExpr; import org.openflexo.antar.expr.parser.node.AModExprExpr3; import org.openflexo.antar.expr.parser.node.AMultExprExpr3; import org.openflexo.antar.expr.parser.node.ANegativeTerm; import org.openflexo.antar.expr.parser.node.ANeqExprExpr; import org.openflexo.antar.expr.parser.node.ANotExprExpr3; import org.openflexo.antar.expr.parser.node.ANullConstant; import org.openflexo.antar.expr.parser.node.ANumberTerm; import org.openflexo.antar.expr.parser.node.AOr2ExprExpr2; import org.openflexo.antar.expr.parser.node.AOrExprExpr2; import org.openflexo.antar.expr.parser.node.APiConstant; import org.openflexo.antar.expr.parser.node.APowerExprExpr3; import org.openflexo.antar.expr.parser.node.APreciseNumberNumber; import org.openflexo.antar.expr.parser.node.AScientificNotationNumberNumber; import org.openflexo.antar.expr.parser.node.ASinFuncFunction; import org.openflexo.antar.expr.parser.node.ASqrtFuncFunction; import org.openflexo.antar.expr.parser.node.AStringValueTerm; import org.openflexo.antar.expr.parser.node.ASubExprExpr2; import org.openflexo.antar.expr.parser.node.ATanFuncFunction; import org.openflexo.antar.expr.parser.node.ATermExpr3; import org.openflexo.antar.expr.parser.node.ATrueConstant; import org.openflexo.antar.expr.parser.node.Node; import org.openflexo.antar.expr.parser.node.PBinding; import org.openflexo.antar.expr.parser.node.TCharsValue; import org.openflexo.antar.expr.parser.node.TDecimalNumber; import org.openflexo.antar.expr.parser.node.TPreciseNumber; import org.openflexo.antar.expr.parser.node.TScientificNotationNumber; import org.openflexo.antar.expr.parser.node.TStringValue; /** * This class implements the semantics analyzer for a parsed AnTAR expression.<br> * Its main purpose is to build a syntax tree with AnTAR expression model from a parsed AST. * * @author sylvain * */ class ExpressionSemanticsAnalyzer extends DepthFirstAdapter { private Hashtable<Node, Expression> expressionNodes; private Node topLevel = null; public ExpressionSemanticsAnalyzer() { expressionNodes = new Hashtable<Node, Expression>(); } public Expression getExpression() { if (topLevel != null) { return expressionNodes.get(topLevel); } return null; } private void registerExpressionNode(Node n, Expression e) { // System.out.println("REGISTER " + e + " for node " + n + " as " + n.getClass()); expressionNodes.put(n, e); topLevel = n; } protected Expression getExpression(Node n) { if (n != null) { Expression returned = expressionNodes.get(n); if (returned == null) { System.out.println("No expression registered for " + n + " of " + n.getClass()); } return returned; } return null; } private BindingValueAsExpression makeBinding(PBinding node) { // System.out.println("Make binding with " + node); // Apply the translation. BindingSemanticsAnalyzer bsa = new BindingSemanticsAnalyzer(); node.apply(bsa); BindingValueAsExpression returned = new BindingValueAsExpression(bsa.getPath()); // System.out.println("Made binding as " + bsa.getPath()); registerExpressionNode(node, returned); return returned; } private IntegerConstant makeDecimalNumber(TDecimalNumber node) { // System.out.println("Make decimal number with " + node + " as " + Long.parseLong(node.getText())); IntegerConstant returned = new IntegerConstant(Long.parseLong(node.getText())); registerExpressionNode(node, returned); return returned; } private FloatConstant makePreciseNumber(TPreciseNumber node) { // System.out.println("Make precise number with " + node + " as " + Double.parseDouble(node.getText())); FloatConstant returned = new FloatConstant(Double.parseDouble(node.getText())); registerExpressionNode(node, returned); return returned; } private FloatConstant makeScientificNotationNumber(TScientificNotationNumber node) { // System.out.println("Make scientific notation number with " + node + " as " + Double.parseDouble(node.getText())); FloatConstant returned = new FloatConstant(Double.parseDouble(node.getText())); registerExpressionNode(node, returned); return returned; } private StringConstant makeStringValue(TStringValue node) { // System.out.println("Make string value with " + node); StringConstant returned = new StringConstant(node.getText().substring(1, node.getText().length() - 1)); registerExpressionNode(node, returned); return returned; } private StringConstant makeCharsValue(TCharsValue node) { // System.out.println("Make chars value with " + node); StringConstant returned = new StringConstant(node.getText().substring(1, node.getText().length() - 1)); registerExpressionNode(node, returned); return returned; } // Following methods manage following grammar fragment /*expr = {expr2} expr2 | {cond_expr} [condition]:expr if_token [then]:expr2 else_token [else]:expr2 | {eq_expr} [left]:expr eq [right]:expr2 | {eq2_expr} [left]:expr eq2 [right]:expr2 | {neq_expr} [left]:expr neq [right]:expr2 | {lt_expr} [left]:expr lt [right]:expr2 | {gt_expr} [left]:expr gt [right]:expr2 | {lte_expr} [left]:expr lte [right]:expr2 | {gte_expr} [left]:expr gte [right]:expr2 ;*/ @Override public void outAExpr2Expr(AExpr2Expr node) { super.outAExpr2Expr(node); registerExpressionNode(node, getExpression(node.getExpr2())); } @Override public void outACondExprExpr(ACondExprExpr node) { super.outACondExprExpr(node); // System.out.println("On chope une conditionnelle avec cond:" + node.getCondition() + " then:" + node.getThen() + " else:"+ // node.getElse()); registerExpressionNode(node, new ConditionalExpression(getExpression(node.getCondition()), getExpression(node.getThen()), getExpression(node.getElse()))); } @Override public void outAEqExprExpr(AEqExprExpr node) { super.outAEqExprExpr(node); registerExpressionNode(node, new BinaryOperatorExpression(BooleanBinaryOperator.EQUALS, getExpression(node.getLeft()), getExpression(node.getRight()))); } @Override public void outAEq2ExprExpr(AEq2ExprExpr node) { super.outAEq2ExprExpr(node); registerExpressionNode(node, new BinaryOperatorExpression(BooleanBinaryOperator.EQUALS, getExpression(node.getLeft()), getExpression(node.getRight()))); } @Override public void outANeqExprExpr(ANeqExprExpr node) { super.outANeqExprExpr(node); registerExpressionNode(node, new BinaryOperatorExpression(BooleanBinaryOperator.NOT_EQUALS, getExpression(node.getLeft()), getExpression(node.getRight()))); } @Override public void outALtExprExpr(ALtExprExpr node) { super.outALtExprExpr(node); registerExpressionNode(node, new BinaryOperatorExpression(BooleanBinaryOperator.LESS_THAN, getExpression(node.getLeft()), getExpression(node.getRight()))); } @Override public void outALteExprExpr(ALteExprExpr node) { super.outALteExprExpr(node); registerExpressionNode(node, new BinaryOperatorExpression(BooleanBinaryOperator.LESS_THAN_OR_EQUALS, getExpression(node.getLeft()), getExpression(node.getRight()))); } @Override public void outAGtExprExpr(AGtExprExpr node) { super.outAGtExprExpr(node); registerExpressionNode(node, new BinaryOperatorExpression(BooleanBinaryOperator.GREATER_THAN, getExpression(node.getLeft()), getExpression(node.getRight()))); } @Override public void outAGteExprExpr(AGteExprExpr node) { super.outAGteExprExpr(node); registerExpressionNode(node, new BinaryOperatorExpression(BooleanBinaryOperator.GREATER_THAN_OR_EQUALS, getExpression(node.getLeft()), getExpression(node.getRight()))); } // Following methods manage following grammar fragment /* expr2 = {expr3} expr3 | {or_expr} [left]:expr2 or [right]:expr3 | {or2_expr} [left]:expr2 or2 [right]:expr3 | {add_expr} [left]:expr2 plus [right]:expr3 | {sub_expr} [left]:expr2 minus [right]:expr3; */ @Override public void outAExpr3Expr2(AExpr3Expr2 node) { // System.out.println("OUT Expr3-Expr2 with " + node); super.outAExpr3Expr2(node); registerExpressionNode(node, getExpression(node.getExpr3())); // System.out.println("***** AExpr3Expr2 " + node + "expression=" + getExpression(node.getExpr3())); } @Override public void outAOrExprExpr2(AOrExprExpr2 node) { super.outAOrExprExpr2(node); registerExpressionNode(node, new BinaryOperatorExpression(BooleanBinaryOperator.OR, getExpression(node.getLeft()), getExpression(node.getRight()))); } @Override public void outAOr2ExprExpr2(AOr2ExprExpr2 node) { super.outAOr2ExprExpr2(node); registerExpressionNode(node, new BinaryOperatorExpression(BooleanBinaryOperator.OR, getExpression(node.getLeft()), getExpression(node.getRight()))); } @Override public void outAAddExprExpr2(AAddExprExpr2 node) { super.outAAddExprExpr2(node); // System.out.println("OUT add with " + node); registerExpressionNode(node, new BinaryOperatorExpression(ArithmeticBinaryOperator.ADDITION, getExpression(node.getLeft()), getExpression(node.getRight()))); } @Override public void outASubExprExpr2(ASubExprExpr2 node) { super.outASubExprExpr2(node); registerExpressionNode(node, new BinaryOperatorExpression(ArithmeticBinaryOperator.SUBSTRACTION, getExpression(node.getLeft()), getExpression(node.getRight()))); } // Following methods manage following grammar fragment /* expr3 = {term} term | {and_expr} [left]:expr3 and [right]:term | {and2_expr} [left]:expr3 and2 [right]:term | {mult_expr} [left]:expr3 mult [right]:term | {div_expr} [left]:expr3 div [right]:term | {mod_expr} [left]:expr3 mod [right]:term | {power_expr} [left]:expr3 power [right]:term | {not_expr} not term; */ @Override public void outATermExpr3(ATermExpr3 node) { // System.out.println("OUT Term-Expr3 with " + node + " term=" + node.getTerm() + " of " + node.getTerm().getClass()); super.outATermExpr3(node); registerExpressionNode(node, getExpression(node.getTerm())); // System.out.println("***** ATermExpr3 " + node + "expression=" + getExpression(node.getTerm())); } @Override public void outAAndExprExpr3(AAndExprExpr3 node) { super.outAAndExprExpr3(node); registerExpressionNode(node, new BinaryOperatorExpression(BooleanBinaryOperator.AND, getExpression(node.getLeft()), getExpression(node.getRight()))); } @Override public void outAAnd2ExprExpr3(AAnd2ExprExpr3 node) { super.outAAnd2ExprExpr3(node); registerExpressionNode(node, new BinaryOperatorExpression(BooleanBinaryOperator.AND, getExpression(node.getLeft()), getExpression(node.getRight()))); } @Override public void outAMultExprExpr3(AMultExprExpr3 node) { super.outAMultExprExpr3(node); // System.out.println("OUT mult with " + node); registerExpressionNode(node, new BinaryOperatorExpression(ArithmeticBinaryOperator.MULTIPLICATION, getExpression(node.getLeft()), getExpression(node.getRight()))); } @Override public void outADivExprExpr3(ADivExprExpr3 node) { super.outADivExprExpr3(node); registerExpressionNode(node, new BinaryOperatorExpression(ArithmeticBinaryOperator.DIVISION, getExpression(node.getLeft()), getExpression(node.getRight()))); } @Override public void outAModExprExpr3(AModExprExpr3 node) { super.outAModExprExpr3(node); registerExpressionNode(node, new BinaryOperatorExpression(ArithmeticBinaryOperator.MOD, getExpression(node.getLeft()), getExpression(node.getRight()))); } @Override public void outAPowerExprExpr3(APowerExprExpr3 node) { super.outAPowerExprExpr3(node); registerExpressionNode(node, new BinaryOperatorExpression(ArithmeticBinaryOperator.POWER, getExpression(node.getLeft()), getExpression(node.getRight()))); } @Override public void outANotExprExpr3(ANotExprExpr3 node) { super.outANotExprExpr3(node); registerExpressionNode(node, new UnaryOperatorExpression(BooleanUnaryOperator.NOT, getExpression(node.getTerm()))); } // Following methods manage following grammar fragment /* function = {cos_func} cos l_par expr2 r_par | {acos_func} acos l_par expr2 r_par | {sin_func} sin l_par expr2 r_par | {asin_func} asin l_par expr2 r_par | {tan_func} tan l_par expr2 r_par | {atan_func} atan l_par expr2 r_par | {exp_func} exp l_par expr2 r_par | {log_func} log l_par expr2 r_par | {sqrt_func} sqrt l_par expr2 r_par; */ @Override public void outACosFuncFunction(ACosFuncFunction node) { super.outACosFuncFunction(node); registerExpressionNode(node, new UnaryOperatorExpression(ArithmeticUnaryOperator.COS, getExpression(node.getExpr2()))); } @Override public void outAAcosFuncFunction(AAcosFuncFunction node) { super.outAAcosFuncFunction(node); registerExpressionNode(node, new UnaryOperatorExpression(ArithmeticUnaryOperator.ACOS, getExpression(node.getExpr2()))); } @Override public void outASinFuncFunction(ASinFuncFunction node) { super.outASinFuncFunction(node); registerExpressionNode(node, new UnaryOperatorExpression(ArithmeticUnaryOperator.SIN, getExpression(node.getExpr2()))); } @Override public void outAAsinFuncFunction(AAsinFuncFunction node) { super.outAAsinFuncFunction(node); registerExpressionNode(node, new UnaryOperatorExpression(ArithmeticUnaryOperator.ASIN, getExpression(node.getExpr2()))); } @Override public void outATanFuncFunction(ATanFuncFunction node) { super.outATanFuncFunction(node); registerExpressionNode(node, new UnaryOperatorExpression(ArithmeticUnaryOperator.TAN, getExpression(node.getExpr2()))); } @Override public void outAAtanFuncFunction(AAtanFuncFunction node) { super.outAAtanFuncFunction(node); registerExpressionNode(node, new UnaryOperatorExpression(ArithmeticUnaryOperator.ATAN, getExpression(node.getExpr2()))); } @Override public void outAExpFuncFunction(AExpFuncFunction node) { super.outAExpFuncFunction(node); registerExpressionNode(node, new UnaryOperatorExpression(ArithmeticUnaryOperator.EXP, getExpression(node.getExpr2()))); } @Override public void outALogFuncFunction(ALogFuncFunction node) { super.outALogFuncFunction(node); registerExpressionNode(node, new UnaryOperatorExpression(ArithmeticUnaryOperator.LOG, getExpression(node.getExpr2()))); } @Override public void outASqrtFuncFunction(ASqrtFuncFunction node) { super.outASqrtFuncFunction(node); registerExpressionNode(node, new UnaryOperatorExpression(ArithmeticUnaryOperator.SQRT, getExpression(node.getExpr2()))); } // Following methods manage following grammar fragment /* constant = {true} true | {false} false | {null} null | {this} this | {pi} pi;*/ @Override public void outATrueConstant(ATrueConstant node) { super.outATrueConstant(node); registerExpressionNode(node, BooleanConstant.TRUE); } @Override public void outAFalseConstant(AFalseConstant node) { super.outAFalseConstant(node); registerExpressionNode(node, BooleanConstant.FALSE); } @Override public void outAPiConstant(APiConstant node) { super.outAPiConstant(node); registerExpressionNode(node, FloatSymbolicConstant.PI); } @Override public void outANullConstant(ANullConstant node) { super.outANullConstant(node); registerExpressionNode(node, ObjectSymbolicConstant.NULL); } // Following methods manage following grammar fragment /* number = {decimal_number} decimal_number | {precise_number} precise_number | {scientific_notation_number} scientific_notation_number | {constant} constant; */ @Override public void outADecimalNumberNumber(ADecimalNumberNumber node) { super.outADecimalNumberNumber(node); registerExpressionNode(node, makeDecimalNumber(node.getDecimalNumber())); } @Override public void outAPreciseNumberNumber(APreciseNumberNumber node) { super.outAPreciseNumberNumber(node); registerExpressionNode(node, makePreciseNumber(node.getPreciseNumber())); } @Override public void outAScientificNotationNumberNumber(AScientificNotationNumberNumber node) { super.outAScientificNotationNumberNumber(node); registerExpressionNode(node, makeScientificNotationNumber(node.getScientificNotationNumber())); } @Override public void outAConstantNumber(AConstantNumber node) { super.outAConstantNumber(node); registerExpressionNode(node, getExpression(node.getConstant())); } // Following methods manage following grammar fragment /* term = {negative} minus term | {number} number | {string_value} string_value | {chars_value} chars_value | {function} function | {binding} binding | {expr} l_par expr r_par;*/ @Override public void outANegativeTerm(ANegativeTerm node) { super.outANegativeTerm(node); registerExpressionNode(node, new UnaryOperatorExpression(ArithmeticUnaryOperator.UNARY_MINUS, getExpression(node.getTerm()))); } @Override public void outANumberTerm(ANumberTerm node) { super.outANumberTerm(node); registerExpressionNode(node, getExpression(node.getNumber())); } @Override public void outAStringValueTerm(AStringValueTerm node) { super.outAStringValueTerm(node); registerExpressionNode(node, makeStringValue(node.getStringValue())); } @Override public void outACharsValueTerm(ACharsValueTerm node) { super.outACharsValueTerm(node); registerExpressionNode(node, makeCharsValue(node.getCharsValue())); } @Override public void outAFunctionTerm(AFunctionTerm node) { super.outAFunctionTerm(node); registerExpressionNode(node, getExpression(node.getFunction())); } @Override public void outABindingTerm(ABindingTerm node) { super.outABindingTerm(node); registerExpressionNode(node, makeBinding(node.getBinding())); } @Override public void outAExprTerm(AExprTerm node) { super.outAExprTerm(node); registerExpressionNode(node, getExpression(node.getExpr())); } }