Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Trying to implement simple expressions in XTEXT(Trying to implement simple expressions XTEXT)
Trying to implement simple expressions in XTEXT [message #722902] Wed, 07 September 2011 06:42 Go to next message
Jack Matthews is currently offline Jack MatthewsFriend
Messages: 9
Registered: August 2009
Junior Member
I have been trying all day to do this and hit hurdle after hurdle.

I need to implement a simple language.

Two types

A String expression might look like this, @STREET,@CITY @STATE mean previously defined variables

STREET := "mystreet";
CITY := "my city";
STATE := "my state";
ADDRESS := @STREET + ", " + @CITY + ", " + @STATE;


An numeric one might look like this.

COST:=123;
nV2:=23.345;
RealCost:= @COST/@nV2*10;



I can't get the rule to work that will allow me to enter either of the expressions above.

Can someone suggest the grammar I could use that would allow me to reference variables via @VAR_NAME as well as normal strings/numbers


Re: Trying to implement simple expressions in XTEXT [message #722905 is a reply to message #722902] Wed, 07 September 2011 06:50 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
Hi,

what about

Literal: IntLiteral | StringLiteral | VarReference;
IntLiteral: value=INT;
StringLiteral: value=STRING;
VarReference: '@' ref=[Variable]


~Christian
~Christian


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Trying to implement simple expressions in XTEXT [message #722910 is a reply to message #722905] Wed, 07 September 2011 07:23 Go to previous messageGo to next message
Jack Matthews is currently offline Jack MatthewsFriend
Messages: 9
Registered: August 2009
Junior Member
I tried this but it still does not work, The "Variable" name does not show, in fact I can use any variable name and it says it is correct.

@SOMENAME should only work if it has been SOMENAME was declared previously


Variable: name=ID;

Literal: NumericLiteral | StringLiteral | VarReference;
IntLiteral: value=INT;
DoubleLiteral: value=INT'.'INT;
NumericLiteral: IntLiteral | DoubleLiteral;
StringLiteral: value=STRING;
VarReference: '@' ref=[Variable];

VariableDeclaration:
Variable ':=' value+=Literal ('+' value+=Literal)* ';'
;
Re: Trying to implement simple expressions in XTEXT [message #722911 is a reply to message #722910] Wed, 07 September 2011 07:26 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
Hi,

shouldnt that be

VariableDeclaration:
var=Variable ':=' value+=Literal ('+' value+=Literal)* ';'
;


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Trying to implement simple expressions in XTEXT [message #722939 is a reply to message #722911] Wed, 07 September 2011 09:07 Go to previous messageGo to next message
Jack Matthews is currently offline Jack MatthewsFriend
Messages: 9
Registered: August 2009
Junior Member
Probably, I don't really understand it properly.

For Example, can you tell me the difference between

Something:ID;


and

Something:name=ID;


In what circumstances would I use each of these? In the tutorials they seem to use each but don't explain it properly.
Re: Trying to implement simple expressions in XTEXT [message #722942 is a reply to message #722939] Wed, 07 September 2011 09:20 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
Hi,

can you please share a reproducable example. that may help to solve your problem.
and of course: @SOMENAME should only work if it has been SOMENAME was declared previously is a scoping thing thats your task.


~Christian


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de

[Updated on: Wed, 07 September 2011 09:33]

Report message to a moderator

Re: Trying to implement simple expressions in XTEXT [message #722949 is a reply to message #722939] Wed, 07 September 2011 09:44 Go to previous messageGo to next message
Alexander Nittka is currently offline Alexander NittkaFriend
Messages: 1193
Registered: July 2009
Senior Member
Hi,

the documentation has explanations of the grammar concepts.

Rule: ID;

is a datatype rule. The parser creates a simple type (usually a string).

Rule: name=ID;

is an "EObject-rule". The parser creates an actual object that has a feature with name "name".

Alex
Re: Trying to implement simple expressions in XTEXT [message #723181 is a reply to message #722911] Wed, 07 September 2011 23:27 Go to previous messageGo to next message
Jack Matthews is currently offline Jack MatthewsFriend
Messages: 9
Registered: August 2009
Junior Member
Still didn't work, my code so far looks like this


/*******************
* VARIABLE SECTION
*******************/
Variable: name=ID;

Literal: NumericLiteral | StringLiteral | VarReference;
IntLiteral: value=INT;
DoubleLiteral: value=INT'.'INT;
NumericLiteral: IntLiteral | DoubleLiteral;
StringLiteral: value=STRING;
VarReference: '@' ref=[Variable];

VariableDeclaration:
var=Variable ':=' value+=Literal ('+' value+=Literal)* ';'
;



I tried things like this,

hello:="String";
hello2:="hello2";
hello3:=@


however, hello3 does not pop up with "@hello" or "@hello2"
Re: Trying to implement simple expressions in XTEXT [message #723226 is a reply to message #723181] Thu, 08 September 2011 05:45 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
Hi,

still don't get your problem:

Model:decls+=VariableDeclaration*;
Variable: name=ID;
Literal: NumericLiteral | StringLiteral | VarReference;
IntLiteral: value=INT;
DoubleLiteral: value=INT'.'INT;
NumericLiteral: IntLiteral | DoubleLiteral;
StringLiteral: value=STRING;
VarReference: '@' ref=[Variable];
	
VariableDeclaration:
	var=Variable ':=' value+=Literal ('+' value+=Literal)* ';'
;


pasted in a newly create xtext project works like a charm to me


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Trying to implement simple expressions in XTEXT [message #723248 is a reply to message #723226] Thu, 08 September 2011 07:21 Go to previous message
Daniel Missing name is currently offline Daniel Missing nameFriend
Messages: 101
Registered: July 2011
Senior Member
Hi.

If you want to have a real expression tree like each programming language (and xbase) has, you would create a ruleset like this:


VariableDefinition:
    name=ID ':=' value=Expression ';'
;

Expression returns IExpression:
    MultiplicativeExpression
;

MultOp: '*' | '/' | '%';
MultiplicativeExpression returns IExpression:
    AdditiveExpression ({BinaryExpression.current=this} operator=MultOp right=AdditiveExpression)*
;

AdditiveOp: '+' | '-';
AdditiveExpression returns IExpression:
    PrimaryExpression ({BinaryExpression.current=this} operator=AdditiveOp right=PrimaryExpression)*
;

PrimaryExpression returns IExpression:
    ILiteral
    | ReferenceExpression
    | ParenthesizedExpression
;

ParenthesizedExpression returns IExpression:
    {ParenthesizedExpression}
    '(' expression=Expression ')'
;

ReferenceExpression return IExpression:
    {ReferenceExpression}
    '@' variable=[VariableDefinition]
;

ILiteral returns IExpression:
    StringLiteral
    | NumberLiteral
;

StringLiteral returns IExpression:
    {StringLiteral}
    value=STRING
;

NumberLiteral returns IExpression:
    {NumberLiteral}
    value=Number
;

Number: 
    {IntegerNumber} value=INT
    | {DoubleNumber} value=DOUBLE
;

terminal DOUBLE ecore::EDouble:
    INT '.' INT
;


This will allow you to create a small interpreter using the polymorphic dispatcher (a very quick&dirty notepad version):
	
public class TypeEvaluationInterpreter {

	private PolymorphicDispatcher<EvaluationResult> evalDispatcher = 
            PolymorphicDispatcher.createForSingleTarget("eval", this); 

    
    public EvaluationResult start(IExpression expression) throws EvaluationException {
        // TODO: caching and cycle detection
        this.evalDispatcher.invoke(expression);
    }
    
    protected EvaluationResult eval(BinaryExpression expression) throws EvaluationException {
        
        EvaluationResult leftHandSide = this.evalDispatcher.invoke(reference.getLeft());
        EvaluationResult rightHandSide = this.evalDispatcher.invoke(reference.getRight());
        
        Type result = getResultType(Operation.getOperation(expression.getOperator()),
                                    leftHandSide.getType(),
                                    rightHandSide.getType());
                                    
        return new EvaluationResult(result);
    }   
    
    protected Type getResultType(Operation op, Type left, Type right) {
        switch(op) {
            case ADDITION:
                // addition works for all types, higher priority type will be result
                getHigherPriority(left, right); 
            break;
            case SUBTRACTION:
            case DIVISION:
            case MODULO:
            case MULTIPLICATION:
                if(left == Type.STRING || right == Type.STRING) {
                    throw new EvaluationException("Operation '" + op.getOpString() + "' is undefined for types " + left + " and " + right);
                }
                getHigherPriority(left, right);      
            break;
        }
    }
    
    protected Type getHigherPriority(Type left, Type right) {
        if(left.getPriority() > right.getPriority()) {
            return left;
        }
        else {
            return right;
        } 
    }
    
    protected EvaluationResult eval(ParenthesizedExpression expression) {
        return this.evalDispatcher.invoke(reference.getExpression());
    }
   
    protected EvaluationResult eval(ReferenceExpression expression) {
        VariableDefinition reference = expression.getVariable();
        return this.evalDispatcher.invoke(reference.getValue());
    }   
    
    protected EvaluationResult eval(StringLiteral expression) {
        return new EvaluationResult(Type.STRING);
    }    
    
    protected EvaluationResult eval(NumberLiteral expression) {
        return this.evalDispatcher.invoke(expression.getValue());
    }    
    
    protected EvaluationResult eval(IntegerNumber expression) {
        return new EvaluationResult(Type.INTEGER);
    }   
    
    protected EvaluationResult eval(DoubleNumber expression) {
        return new EvaluationResult(Type.DOUBLE);
    }
    
    public static class EvaluationResult {
        private Type type;
        public Type getType() { return this.type; }
        public EvaluationResult(Type type) { this.type = type; }
    }
    
    public static enum Type {
        INTEGER(0),
        DOUBLE(1),
        STRING(2);
        
        private int priority;
        
        public int getPriority() { return this.priority; }
        
        public Type(int priority) { this.priority = priority; }
    }
    
    public static enum Operation {
        ADDITION("+"),
        SUBTRACTION("-"),
        DIVISION("/"), 
        MODULO("%"),
        MULTIPLICATION("*");
        
        private String opString;
        
        public String getOpString() { return this.opString; }
        public Operation(String opString) { this.opString = opString; }
        public static Operation getOperation(String opString) {
            for(Operation op : values() {
                if(op.getOpString().equals(opString)) {
                    return op;
                }
            }
            return null;
        }
    }
}


In your java validator you simply call this interpreter and catch the exception to show an error.
The code is quite simple so you should understand it Smile

Or: Simply use xbase for your needs Wink xbase ships with exactly such a (more extended) expression tree and interpreter.

Cheers
Daniel
Previous Topic:GMF and Xtext working on same resource - How?
Next Topic:Porting Xpand Code Generation Templates to Xtend 2
Goto Forum:
  


Current Time: Fri Apr 26 05:57:59 GMT 2024

Powered by FUDForum. Page generated in 0.03250 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top