Question

I am running into a problem with ambiguity in a rather complicated grammar I have been building up. It's too complex to post here, so I've reduced my problem down to aid comprehension.

I am getting the following error:

error(201): ../org.xtext.example.mydsl.ui/src-gen/org/xtext/example/mydsl/ui/contentassist/antlr/internal/InternalMyDsl.g:398:1: The following alternatives can never be matched: 2

From this grammar:

grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals

generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"

Model:
    (contents+=ModelMember)*;


ModelMember:  
    Field | Assignment | Static | Class
;

Static:
    "static" type=TypeDef name=ID
;

Class:
    "class" name=ID "{"
        (fields+=Field)*
    "}"
;

Field:
    "var" type=TypeDef name=ID
;

TypeDef:
    {Primtive} ("String" | "int") |
    {Object} clazz=[Class]
;

Reference:
    (
        {StaticField} static=[Static] (withDiamond?="<>")? 
        |
        {DynamicField} field=[Field]
    )
;

ObjectReference:
    reference=Reference ({ObjectReference.target=current} '.' reference=Reference)*

;

Assignment:
    field=ObjectReference "=" value=ObjectReference
;

I know the problem relates to Reference, which is struggling with the ambiguity of which rule to chose.

I can get it to compile with the following grammar change, but this allows syntax that I deem to be illegal:

Reference:
    ref=[RefType] (withDiamond?="<>")?
;

RefType:
    Static|Field
;

Where my use-case is:

static String a

class Person {
    String name
}

Person paul

// This should be legal
paul.name = a<>;

// This should be illegal, diamond not vaild against non-static vars
paul.name = paul.name<>;

// This sohuld be legal
paul.name = paul.name
Was it helpful?

Solution

Your second grammar is the way to go. The fact that diamond is only legal for static variables can be handled in your language's validator.

Generally, make your grammar loose and your validation strict. That makes your grammar easier to maintain. It also gives your users better error messages ("Diamand is not allowed for non-static vars" instead of "Invalid input '<'")

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top