Search code examples
javaexpressioninterpreterxtext

Xtext evaluate expressions


i have the following grammar for my expressions , i would like to evaluate my expressions with my interpreter but i dont figure out how to do it.

Declarations:
    Text | Real | CurveCollection | Interval | Boolean;

Text:
    ("String" | "Text") name=ID (value=STRING)?;

Real:
    ("Double" | "Real") name=ID (array=isarray)? (value+=Double*)? ;

Atomic returns Expression:
    {IntConstant} value=Double |
    {StringConstant} value=STRING |
    {BoolConstant} value=('true'|'false') |
    {Declarations}  variable=[Declarations]
;
Expression : Or;

Or returns Expression:
    And({Or.left=current}"||" right=And)*
;
And returns Expression:
    Equality({And.left=current}"&&"right=Equality)*
;
Equality returns Expression:
    Comparison(
        {Equality.left=current} op=("=="|"!=")
        right=Comparison
    )*
;
Comparison returns Expression:
    PlusOrMinus(
        {Comparison.left=current} op=(">="|"<="|">"|"<")
        right=PlusOrMinus
    )*
;

PlusOrMinus returns Expression:
    MulOrDiv(
        ({Plus.left=current} '+' | {Minus.left=current} '-') 
        right=MulOrDiv
    )*
;
MulOrDiv returns Expression:
    Primary(
        ({MulOrDiv.left=current} op=('*'|'/'))
        right=Primary
    )*
;
Primary returns Expression:
    '(' Expression ')' |
    {function} expression=functions |
    {Not} "!" expression=Primary |
    Atomic
;

In my interpreter when I find an "If" which has a Expression to be evaluated (the variable exp doesn't has methods to evaluate the expression):

if(element instanceof If){
    Expression exp = ((If)element).getIfcondition();

but in this point i dont know how to evaluate recursive expressions for example the following :

if (5 < 10)&&(2==max w[2])||(n>2) then

it's only an example of the kind of expressions to be evaluated ( max is a function what return a double value) . Any idea of how to do it ? I 'm doing the interpreter in Java with Xtext and eclipse . Thank so much -> well another problema is when the atomic {Declarations} variable=[Declarations] when i get in my expressionshandler ( my xtend class ) y get a null value and i dont know why .

def dispatch Object interpret(Expression e,Scope scope) {
        switch (e) {
                            IntConstant:
                e.value
            BoolConstant:
                Boolean.parseBoolean(e.value)
            StringConstant:
                e.value
            Declarations:{
                //scope.getRealValueOf(e.name)
                e.toString()

            }

i need the name of the variable but i can see the following output of the toString :

org.xtext.energy.impl.DeclarationsImpl@1f1f1a2f (name: null)

why is the name null? is something wrong in my grammar?


Solution

  • You should have a recursive function that accepts an expression and an evaluation context, e.g. to reflect scoping semantic and store variables, and returns a result of evaluation. The function should apply different logic depending on a type of an expression, so for If it should invoke itself recursively on if.gtIfCondition().

    See how it is done for Xbase: https://github.com/eclipse/xtext-extras/blob/master/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/interpreter/impl/XbaseInterpreter.java#L187

    Implementing interpreters and compilers with Java is tedious, use Xtend for it. It is designed for such tasks and has neat features like dispatch methods and powerful switch expressions.