Balázs Édes
Balázs Édes

Reputation: 13807

XText typed literals

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:

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

Answers (3)

integragreg
integragreg

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

lorenzo-bettini
lorenzo-bettini

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

Joko
Joko

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

Related Questions