Home » Modeling » TMF (Xtext) » SetExpressions: Lists and Ranges
SetExpressions: Lists and Ranges [message #810585] |
Thu, 01 March 2012 09:38 |
Alex G Messages: 96 Registered: January 2012 |
Member |
|
|
Hi folks!
I want to have expressions for sets of items like
list: {1, 2, 3} or even {1}
range: {1..3}
I found so far two possibilites with XText. The first doesn't creaste the correct Ecore-Model, the second doesn't work with syntactic predicates as expected (I don't know understand why):
1.
SetDescription returns SetDescription:
"{" ArithExpr (
({SetList.elements+=current} ("," elements += ArithExpr)+ |
({SetRange.left=current} ".." right=ArithExpr)?
) "}";
ArithExpr: ...;
Problem here is: In the ecore model the type ArithExpr is a subtype of SetDescription, which shall not be the case. Ok, so work with syntactic predicates, since it will be not left-factored:
2.
SetDescription returns SetDescription:
'{' (
=>({SetList} elements+=ArithExpr (',' elements+=ArithExpr)*) |
({SetRange} left=ArithExpr '..' right=ArithExpr)
)'}';
In this case, the second "range"-alternative can never be taken, that means, I can not write expressions like {1..2}. I thought that syntactic predicates work like backtracking, meaning, that if the parser see ".." he tracks back and doesn't take the default alternative described by the syntactic predicate (here the list of items).
What I want is an (abstract) type SetDescription with (concrete) subtypes SetListDescription (with elements attribute) and SetRangeDescription (with left and right attributes). ArithExpr shall not be a subtype of SetDescription (in this case, if the description looks like {1}, it shall be a SetListDescription. What I don't want is:
* attributes in SetDescription like "firstItem"
* describe the range syntactically in another way, like [1..3] instead of {1..3}
* turn on backtrack option.
Does anyone has an idea how to solve this problem with XText (if possible)?
|
|
| | |
Re: SetExpressions: Lists and Ranges [message #811412 is a reply to message #810585] |
Fri, 02 March 2012 10:09 |
Jan Koehnlein Messages: 760 Registered: July 2009 Location: Hamburg |
Senior Member |
|
|
Would unassigned rulecalls work?
SetDescription :
'{' SetList | SetRange '}'
SetList:
elements+=ArithExpr (',' elements+=ArithExpr)*;
SetRange
left=ArithExpr '..' right=ArithExpr;
Am 01.03.12 10:38, schrieb Alex G:
> Hi folks!
>
> I want to have expressions for sets of items like
>
> list: {1, 2, 3} or even {1}
> range: {1..3}
>
>
> I found so far two possibilites with XText. The first doesn't creaste
> the correct Ecore-Model, the second doesn't work with syntactic
> predicates as expected (I don't know understand why):
> 1.
>
> SetDescription returns SetDescription:
> "{" ArithExpr (
> ({SetList.elements+=current} ("," elements += ArithExpr)+ |
> ({SetRange.left=current} ".." right=ArithExpr)?
> ) "}";
> ArithExpr: ...;
>
> Problem here is: In the ecore model the type ArithExpr is a subtype of
> SetDescription, which shall not be the case. Ok, so work with syntactic
> predicates, since it will be not left-factored:
> 2.
>
> SetDescription returns SetDescription:
> '{' (
> =>({SetList} elements+=ArithExpr (',' elements+=ArithExpr)*) |
> ({SetRange} left=ArithExpr '..' right=ArithExpr)
> )'}';
>
> In this case, the second "range"-alternative can never be taken, that
> means, I can not write expressions like {1..2}. I thought that syntactic
> predicates work like backtracking, meaning, that if the parser see ".."
> he tracks back and doesn't take the default alternative described by the
> syntactic predicate (here the list of items).
>
> What I want is an (abstract) type SetDescription with (concrete)
> subtypes SetListDescription (with elements attribute) and
> SetRangeDescription (with left and right attributes). ArithExpr shall
> not be a subtype of SetDescription (in this case, if the description
> looks like {1}, it shall be a SetListDescription. What I don't want is:
> * attributes in SetDescription like "firstItem"
> * describe the range syntactically in another way, like [1..3] instead
> of {1..3}
> * turn on backtrack option.
>
> Does anyone has an idea how to solve this problem with XText (if possible)?
--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com
---
Get professional support from the Xtext committers at www.typefox.io
|
|
|
Re: SetExpressions: Lists and Ranges [message #818984 is a reply to message #811412] |
Mon, 12 March 2012 10:47 |
Alex G Messages: 96 Registered: January 2012 |
Member |
|
|
Jan Kohnlein wrote on Fri, 02 March 2012 05:09Would unassigned rulecalls work?
SetDescription :
'{' SetList | SetRange '}'
SetList:
elements+=ArithExpr (',' elements+=ArithExpr)*;
SetRange
left=ArithExpr '..' right=ArithExpr;
No, this doesn't work, since it is again non-LL.
But I have found a solution for this (a little bit tricky, but it works):
SetDescription returns SetDescription:
'{' ArithExpr (
((',' {SetList.elements+=current} elements+=ArithExpr) (',' elements+=ArithExpr)*) |
('..' {SetRange.left=current} right=ArithExpr) |
({SetList.elements+=current})
) '}';
(1) left-factor the ArithExpr
(2) choose what follows after ArithExpr: "," or ".." or nothing
(3) create actions according to what follows. When "," follows, I had to split (ArithExpr)+ into ArithExpr (ArithExpr)* in order to be able to create the action elements for the first and second ArithExpr in the list.
|
|
| |
Re: SetExpressions: Lists and Ranges [message #819201 is a reply to message #819163] |
Mon, 12 March 2012 16:12 |
Stefano Zanotti Messages: 22 Registered: March 2012 |
Junior Member |
|
|
I haven't tested this, it's just an idea:
SetDescription:
'{'
( => ({SetRange} left = ArithExpr '..') right = ArithExpr
| {SetList} elements += ArithExpr
(',' elements += ArithExpr)*
)
'}'
;
I think that including the bare minimum number of rules/tokens inside the predicate should improve the error messages the user gets, so I included them only up to the '..'.
P.S. I've had problems with the '..' before, but you said you already had it solved. Anyhow, I solved that decimal point/.. conflict by replacing both the floating point number and the '..' with datatype rules, and using just a DOT: '.'; terminal rule (no '..' terminal, nor '..' literal string in parser rules):
FLOAT : INT? DOT INT ; // INT from common terminals
RANGE hidden(): DOT DOT ; // replacement for '..' in the previous code snippet
terminal DOT : '.' ;
The problem I've had is that '1 .. 2' is right, but with '1.. 2' the lexer matches '1.', so it assumes it is a floating point, but then it finds another '.' and raises an error.
Are you sure that your problem is not related to this "no space between 1 and .." problem?
|
|
|
Re: SetExpressions: Lists and Ranges [message #819701 is a reply to message #819201] |
Tue, 13 March 2012 08:13 |
Alex G Messages: 96 Registered: January 2012 |
Member |
|
|
Hi Stefano!
You are great! Your code works fine for me! Just what I searched for a long time. I worked also with syntactic predicates, but I tested it only on exactly one parser rule or on the whole alternative, but not on a part of the alternative (as you said: "bare minimum of rules/tokens"), which if thinking of it, makes of course much more sense!
Stefano Zanotti wrote on Mon, 12 March 2012 12:12
P.S. I've had problems with the '..' before, but you said you already had it solved. Anyhow, I solved that decimal point/.. conflict by replacing both the floating point number and the '..' with datatype rules, and using just a DOT: '.'; terminal rule (no '..' terminal, nor '..' literal string in parser rules):
FLOAT : INT? DOT INT ; // INT from common terminals
RANGE hidden(): DOT DOT ; // replacement for '..' in the previous code snippet
terminal DOT : '.' ;
The problem I've had is that '1 .. 2' is right, but with '1.. 2' the lexer matches '1.', so it assumes it is a floating point, but then it finds another '.' and raises an error.
Are you sure that your problem is not related to this "no space between 1 and .." problem?
I use my float numbers all the time as data type rules. And I don't have any conflicts with the '..', even if there is no space between the leading number and the '..'. Further I don't need a special RANGE-terminal, like in your case. It's working with '.' and '..' out of the box, if dealing with data type rules. (I think '.' and '..' are a type of implicitely defined terminal rules).
Thank you for your help!
|
|
| |
Goto Forum:
Current Time: Fri Apr 26 14:09:40 GMT 2024
Powered by FUDForum. Page generated in 0.04118 seconds
|