scoping, auto complete and validation [message #1312613] |
Thu, 24 April 2014 11:51 |
Yoel Pinhas Messages: 17 Registered: October 2013 |
Junior Member |
|
|
Hi
I have created a simple grammar using xtext called unit. The main concept is that everything is a unit. Units are constructed from units (Struct/Class equivalent). A unit value is pair of a 'unit type reference' and an 'instance name'.
primitives are a special case of units and this allows me to have a unified unit system where everything is a unit
for more details please look at full grammar and full code snippet attached below
so, everything works great... well, almost everything
I'm having trouble with the validation/scoping/autocomplete of the following code:
a = new Point { x = this.line0.a.x, y = this.line0.a.y },
specifically my problem is with 'this.line0.a.x'
The grammar rule I used is this:
UnitThisValueReference:
'this' '.' next=UnitRecursiveValueReference;
UnitRecursiveValueReference:
prev=[UnitValue] ('.' next=UnitRecursiveValueReference)?;
I have used the following scoping methods to reduce list of unit values in the 'this' rule to values that only belong to this. And a scoping method to reduce unit values in case of recursive ref, and suggest the values for next from the values in prev
class UnitScopeProvider extends AbstractDeclarativeScopeProvider {
// scope for values inside previous reference
def IScope scope_UnitRecursiveValueReference_next(UnitRecursiveValueReference reference, EReference erefence) {
Scopes::scopeFor(reference.prev.type.body.values)
}
// find the 'this' unit and scope for all values in it
def IScope scope_UnitThisValueReference_next(UnitThisValueReference reference, EReference erefence) {
var eContainer = reference.eContainer
while ((!(eContainer instanceof Unit) && (eContainer != null))) {
eContainer = eContainer.eContainer
}
if (eContainer != null && (eContainer instanceof Unit)) {
var Unit thisUnit = eContainer as Unit;
Scopes::scopeFor(thisUnit.body.values)
} else {
null
}
}
}
When i try to auto complete 'this.' I get: [a, b, line0, line1 and line2, x , y]. x, y belongs to Point. I get the same autocomplete list after every '.'
- Is there something wrong with my grammar rules?
- Should I use validate and autocomplete to reduce suggestions and make sure everything is valid?
Thanks in advance,
Yoel.
==========
Full example snippet using unit dsl:
package altair.example
import altair.example.Point.*
// primitive unit definitions
int unit Int {
val Int value
}
unit Point {
val Int x
val Int y
}
unit Line {
val Point a
val Point b
}
unit Lines {
val Point a = new Point { x = 0, y = 0 }
val Point b = new Point { x = 1, y = 1 }
val Line line0 = new Line { a = this.a, b = this.b }
val Line line1 = new Line {
a = new Point { x = 0, y = 1 },
b = new Point { x = 2, y = 1 }
}
val Line line2 = new Line {
a = new Point { x = this.line0.a.x, y = this.line0.a.y },
b = new Point { x = new Point { x = 0, y = 1 }, y = this.b }
}
}
Full grammar for unit dsl
grammar altair.lang.xtext.unit.Unit with org.eclipse.xtext.common.Terminals
import -You can only use links to eclipse.org sites while you have fewer than 5 msgs-
generate unit -You can only use links to eclipse.org sites while you have fewer than 5 msgs-
UnitModel:
'package' name=QualifiedName
imports+=Import*
units+=Unit*;
QualifiedName:
ID ('.' ID)*;
QualifiedNameWithWildcard: QualifiedName '.' '*';
Import:
'import' (importedNamespace=QualifiedNameWithWildcard | importedNamespace=QualifiedName);
BOOLEAN returns ecore::EBoolean:
'true' | 'false';
enum PrimitiveModifier:
INT='int' | BOOLEAN='boolean' | STRING='string';
UnitModifier:
{UnitModifier} ((abstract?='abstract'? & static?='static'?) & (literal=PrimitiveModifier)?);
Unit:
modifier=UnitModifier 'unit' name=ID ('extends' supers+=[Unit] (',' supers+=[Unit])*)? '{' body=UnitBody '}';
UnitBody:
{UnitBody} values+=UnitValue*;
UnitValue:
'val' type=[Unit] (array?=('[]'))? name=ID ('=' ctor=UnitCtor)?;
UnitCtor:
UnitLiteralCtor | UnitNewCtor | UnitCopyCtor | UnitCtorList;
UnitLiteralCtor:
int=INT | boolean=BOOLEAN | str=STRING; // only for primitive unit types
UnitNewCtor:
'new' type=[Unit] '{' (assginments+=UnitParameterizedAssignment ','?)* '}';
UnitParameterizedAssignment:
parameter=[UnitValue] '=' ctor=UnitCtor;
UnitCopyCtor:
UnitThisValueReference | UnitStaticValueReference;
UnitThisValueReference:
'this' '.' next=UnitRecursiveValueReference;
// static units will be checked in validation
UnitStaticValueReference:
static=[Unit] '.' next=UnitRecursiveValueReference;
UnitRecursiveValueReference:
prev=[UnitValue] ('.' next=UnitRecursiveValueReference)?;
UnitCtorList:
'new' type=[Unit] '[]' '{' (list+=UnitCtor (',' list+=UnitCtor)*)? '}';
|
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.04892 seconds