I've started my first Xtext project and I run into a problem with Cross-Reference (That's what I think is maybe the problem). I've got a DatType, InterfaceDescription rule and an Enumeration. What I want to do is to describe an interface by leting the user choose a datatype from the enumeration or define a new one.

The Enum works without a problem, but when I define a new Datatype with "datatype test1" and use it inside the InterfaceDescription, I get the following Error: 'XtextReconcilerJob' has encountered a problem. An internal error occurred during: "XtextReconcileJon". And that's the error stack: http://pastebin.com/evFki2mB

    DataType:
        'datatype' name=ID ('mapto' mappedType = JAVAID)?
    ;

    Interface:
        interfaceType=InterfaceType name=ID datatype=([DataType]| DataTypeEnum)
    ;

enum InterfaceType:
    INLET = 'inlet' |
    OUTLET = 'outlet'
;

    DataTypeEnum:
        INT8 = 'int8' | INT16 = 'int16' | INT32 = 'int32' |
        DOUBLE = 'double' | SINGLE = 'single' | REAL = 'real' |
        BOOLEAN = 'boolean' | CHAR = 'char'
    ;

When I use the DataType Cross-Reference in another Rule, it works:

ParamList:
    'param:' datatype=[DataType] name=ID
;

Anyone knows what's the problem?

有帮助吗?

解决方案

There are a few issues with the grammar, that together cause this strange behaviour:

  1. DataTypeEnum, as opposed to its name is not an enum but a strange object that might represent a few string values. This hides the issue of the alternate type assignment in the interface rule in the editor.
  2. When generating the editor, some cryptic error messages appear in the output:
    • error(208): ../org.xtext.example.mydsl/src-gen/org/xtext/example/mydsl/parser/antlr/internal/InternalMyDsl.g:447:1: The following token definitions can never be matched because prior tokens match the same input: RULE_ID
    • ebnf2 is not supported for CrossReference - this means, that an extended construct, such as the '|' pattern is not allowed when defining references
  3. By prefixing the DataTypeEnum with the enum keyword, the datatype attribute definition becomes erroneous in the editor, as there is no type in EMF that can be both an enum and an EObject, thus the problem location becomes obvious.

Finally, the runtime error was caused by the fact, that something was missing from the generated parser/lexer tooling, and the resulting model was also incorrect.

To be more constructive, I suggest replacing the offending line by defining a TypeReference element, that can either refer to types mapped to Java or data types. I could extend your grammar in the following way:

Interface:
        interfaceType=InterfaceType name=ID datatype=(TypeReference)
;

TypeReference:
    JavaTypeReference | DataTypeReference
;

JavaTypeReference:
    type = [DataType]
;

DataTypeReference:
    type = DataTypeEnum
;

enum DataTypeEnum:
        INT8 = 'int8' | INT16 = 'int16' | INT32 = 'int32' |
        DOUBLE = 'double' | SINGLE = 'single' | REAL = 'real' |
        BOOLEAN = 'boolean' | CHAR = 'char'
;

PS.: I suggest adding some keywords to the language to ease parsing, especially error recovery. See the following blog post for details: http://zarnekow.blogspot.hu/2012/11/xtext-corner-7-parser-error-recovery.html

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top