package org.openflexo.antar.expr.parser;
import java.util.ArrayList;
import java.util.List;
import org.openflexo.antar.expr.BindingValueAsExpression;
import org.openflexo.antar.expr.Expression;
import org.openflexo.antar.expr.parser.node.AAdditionalArg;
import org.openflexo.antar.expr.parser.node.ABindingTerm;
import org.openflexo.antar.expr.parser.node.ACall;
import org.openflexo.antar.expr.parser.node.ACallBinding;
import org.openflexo.antar.expr.parser.node.AIdentifierBinding;
import org.openflexo.antar.expr.parser.node.ANonEmptyListArgList;
import org.openflexo.antar.expr.parser.node.ATail1Binding;
import org.openflexo.antar.expr.parser.node.ATail2Binding;
import org.openflexo.antar.expr.parser.node.PAdditionalArg;
import org.openflexo.antar.expr.parser.node.PArgList;
import org.openflexo.antar.expr.parser.node.TIdentifier;
/**
* This class implements the semantics analyzer for a parsed AnTAR binding.<br>
* Its main purpose is to structurally build a binding from a parsed AST.<br>
* No semantics nor type checking is performed at this stage
*
* @author sylvain
*
*/
class BindingSemanticsAnalyzer extends ExpressionSemanticsAnalyzer {
private ArrayList<BindingValueAsExpression.AbstractBindingPathElement> path;
/**
* This flag is used to escape binding processing that may happen in call args handling
*/
private boolean weAreDealingWithTheRightBinding = true;
public BindingSemanticsAnalyzer() {
path = new ArrayList<BindingValueAsExpression.AbstractBindingPathElement>();
}
public List<BindingValueAsExpression.AbstractBindingPathElement> getPath() {
return path;
};
/* call =
identifier arg_list ;
arg_list =
l_par expr [additional_args]:additional_arg* r_par;
additional_arg =
comma expr;
binding =
{identifier} identifier |
{call} call |
{tail} identifier dot binding;*/
protected BindingValueAsExpression.NormalBindingPathElement makeNormalBindingPathElement(TIdentifier identifier) {
BindingValueAsExpression.NormalBindingPathElement returned = new BindingValueAsExpression.NormalBindingPathElement(
identifier.getText());
path.add(0, returned);
return returned;
}
public BindingValueAsExpression.MethodCallBindingPathElement makeMethodCallBindingPathElement(ACall node) {
PArgList argList = node.getArgList();
ArrayList<Expression> args = new ArrayList<Expression>();
if (argList instanceof ANonEmptyListArgList) {
args.add(getExpression(((ANonEmptyListArgList) argList).getExpr()));
for (PAdditionalArg aa : ((ANonEmptyListArgList) argList).getAdditionalArgs()) {
AAdditionalArg additionalArg = (AAdditionalArg) aa;
args.add(getExpression(additionalArg.getExpr()));
}
}
BindingValueAsExpression.MethodCallBindingPathElement returned = new BindingValueAsExpression.MethodCallBindingPathElement(node
.getIdentifier().getText(), args);
path.add(0, returned);
return returned;
}
@Override
public void outAIdentifierBinding(AIdentifierBinding node) {
super.outAIdentifierBinding(node);
if (weAreDealingWithTheRightBinding) {
makeNormalBindingPathElement(node.getIdentifier());
}
}
@Override
public void outACallBinding(ACallBinding node) {
super.outACallBinding(node);
if (weAreDealingWithTheRightBinding) {
makeMethodCallBindingPathElement((ACall) node.getCall());
}
}
@Override
public void outATail1Binding(ATail1Binding node) {
super.outATail1Binding(node);
if (weAreDealingWithTheRightBinding) {
makeNormalBindingPathElement(node.getIdentifier());
}
}
@Override
public void outATail2Binding(ATail2Binding node) {
super.outATail2Binding(node);
if (weAreDealingWithTheRightBinding) {
makeMethodCallBindingPathElement((ACall) node.getCall());
}
}
@Override
public void inABindingTerm(ABindingTerm node) {
super.inABindingTerm(node);
// System.out.println("IN binding " + node);
weAreDealingWithTheRightBinding = false;
}
@Override
public void outABindingTerm(ABindingTerm node) {
super.outABindingTerm(node);
// System.out.println("OUT binding " + node);
weAreDealingWithTheRightBinding = true;
}
}