Search code examples
dslxtext

Range Specification in Xtext


I am new to XText and want to define a language element for specifying ranges of values. Examples: [1-2] or ]0.1-0.3[

I have the following rule for this purpose:

Range returns Expression:
Atomic (leftBracket=('[' | ']') left=Atomic '-'  right=Atomic rightBracket=('[' | ']'))*;

Atomic here refers basically to the primitive float and int types. I have two problems:

  1. I get the warning "The assigned value of feature 'leftBracket' will possibly override itself because it is used inside of a loop" and the same for rightBracket. What does this mean in this context?
  2. The expression works only in standalone manner (in one row), but not in connection with the rest of the language elements. E.g. in connection with the element right before:

    Comparison returns Expression:
    Range ({Comparison.left=current} op=(">="|"<="|">"|"<"|"=>"|" <=>"|"xor"|"=") right=Range)*;
    

    This means, if such an operation is before the Range element in my input of the second Eclipse window, I get the error "No viable alternative at input".

Any ideas? Thanks for any hints and advices!

Some more information: I took this example and changed it: https://github.com/LorenzoBettini/packtpub-xtext-book-examples/blob/master/org.example.expressions/src/org/example/expressions/Expressions.xtext

Full code:

grammar org.example.expressions.Expressions with org.eclipse.xtext.common.Terminals

generate expressions "http://www.example.org/expressions/Expressions"

ExpressionsModel:
    expressions+=Expression*;

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:
    Range ({Comparison.left=current} op=(">="|"<="|">"|"<"|"=>"|"<=>"|"xor"|"=") right=Range)*
;

Range returns Expression:
    Primary (leftBracket=('[' | ']') left=Primary '-'  right=Primary rightBracket=('[' | ']'))*
;

Primary returns Expression:
    '(' Expression ')' |
    {Not} "!" expression=Primary |
    Atomic
;

Atomic returns Expression:
    {IntConstant} value=INT |
    {StringConstant} value=STRING |
    {BoolConstant} value=('true'|'false')
;

Example where it fails: (1 = [1-2]) however [1-2] in a row works fine.


Solution

  • i cannot really follow you but your grammar looks strange to me

    Model:
        (expressions+=Comparison ";")*;
    Comparison returns Expression:
        Range ({Comparison.left=current} op=(">=" | "<=" | ">" | "<" | "=>" | "<=>" | "xor" | "=") right=Range)*;
    Range:
        (leftBracket=('[' | ']') left=Atomic '-' right=Atomic rightBracket=('[' | ']'))
        |
        Atomic;
    Atomic:
        value=INT;
    

    works fine with

    [1-2];
    ]3-5[;
    [1-4[ < ]1-6];
    6;
    1 < 2;
    

    so can you give some more context