Reputation: 13807
Another XText question. While experimenting with XText, i tried to create a language which is capable of a basic variable declaration, and value assignment. My first try was something like this:
Grammar:
elements+=Element*;
Element:
Declaration | ValueAssignment;
Declaration:
type=Type isArray='[]'? name=ID;
enum Type:
int | string;
ValueAssignment:
declaration=[Declaration] '=' ???;
So a simple example would look like this:
int foo
int[] bar
string fooBar
foo = 10
bar = { 10, 20, 30 }
fooBar = "Sample text"
So my questions:
Declaration
has a type of
int
, then only such a literal can be on the right hand side of an
assignment, what matches an integer regex? Same for string
?ArrayLiteral: {ArrayLiteral}'{' elements+=???* '}';
but what would be the type of the elements rule? How could i ensure the type there?I went through the XText guides, but anywhere, where types came into play, it used XBase elements which were very confusing. Any help, or pointers on where to start would be greatly appreciated!
Update:
I managed to perform basic type checking on this simple example, however I'm not sure if this is the optimal solution:
The slightly modified grammar:
Grammar:
elements+=Element*;
Element:
Declaration | ValueAssignment;
Declaration:
type=Type isArray?='[]'? name=ID;
enum Type:
int | string;
ValueAssignment:
declaration=[Declaration] '=' value=Literal;
IntLiteral:
value=INT;
StringLiteral:
value=STRING;
PrimitiveLiteral:
IntLiteral | StringLiteral;
ArrayLiteral:
{ArrayLiteral} '{' elements+=PrimitiveLiteral* '}';
Literal:
PrimitiveLiteral | ArrayLiteral;
And a validator on top of it (the grammar itself has no constraints on the types):
class MyDslValidator extends AbstractMyDslValidator {
public static val INVALID_TYPE = 'invalidType'
@Check
def checkTypeOfValueAssignment(ValueAssignment valAssign) {
val isArray = valAssign.declaration.isArray
val type = valAssign.declaration.type
val literal = valAssign.value
if (isArray) {
if (!(literal instanceof ArrayLiteral)) {
error(
"Invalid primitive literal, array required"
, MyDslPackage.Literals.VALUE_ASSIGNMENT__VALUE
, INVALID_TYPE
)
return
}
val arrLiteral = literal as ArrayLiteral
arrLiteral.elements.forEach[l | l.checkType(type) ]
} else {
val primLiteral = literal as PrimitiveLiteral
primLiteral.checkType(type)
}
}
def checkType(PrimitiveLiteral element, Type type) {
if (type == Type.INT && !(element instanceof IntLiteral)) {
error(
"Invalid primitive literal, int required"
, MyDslPackage.Literals.VALUE_ASSIGNMENT__VALUE
, INVALID_TYPE
)
return
}
if (type == Type.STRING && !(element instanceof StringLiteral)) {
error(
"Invalid primitive literal, string required"
, MyDslPackage.Literals.VALUE_ASSIGNMENT__VALUE
, INVALID_TYPE
)
}
}
}
My modified question: Is it OK to do it like this?
Upvotes: 0
Views: 1066
Reputation: 335
I would suggest also writing a type computer class to provide expected and actual types and then using it in your Validator.
Upvotes: 0
Reputation: 2655
One small addition about Xsemantics (I'm its author, and it's still actively developed): the syntax of the DSL is meant to mimic the one of formal type systems; so it might be hard to understand if you're not familiar with formal type systems. I think, however, that a small and basic understanding of formal type systems is required anyway if you plan to implement any non trivial type system.
Upvotes: 2
Reputation: 590
With the grammar you can write the syntax of your language. The semantics of the source code often cannot be implemented with the grammar. For this reason there is the validation class in Xtext projects. It should be used to check the semantics of the source code.
Yes, you solved your problem as provided by Xtext. I don't know if your websearch was that deep, but maybe you have read something about 'Xsemantics' which is an other Eclipse plug-in for implementing a type system for Xtext languages. It has a fancy and hard to understand DSL to write type rules which will then be translated into Java source code and integrated into the type hierarchy of your '...MyDslValidator' class.
Upvotes: 1