Search code examples
editorgrammarxtext

Xtext terminal overlapping


I am new to Xtext and I am facing following issue: Under every "error id :" line i can expect every printable character with spaces/tabs between. My language is indent-based so this "terminal" cannot start with space character.

Edit/: Example code for this language would look like this:

package somepkg:    
    error UNKNOWN:
        Unknown error.
    error ZERO_DIVISION:
        Do not divide by zero you {0} donkey!.

Closest i get to this language specification is this:

grammar com.example.lang.ermsglang.Ermsglang with org.eclipse.xtext.xbase.Xbase hidden(WS)

import "http://www.eclipse.org/emf/2002/Ecore" as ecore
generate ermsglang "http://www.example.com/lang/ermsglang/Ermsglang"

Model:
    {Model}
    'package' name=ENAME ':'
    (BEGIN
        (expressions+=Error)+
    END)?
;

Error:
    {Error}
    'error' name=ENAME ':'
    (BEGIN
        (expressions+=Anything)+
    END)?
;

Anything:
    (ENAME|EMSG|INT)
;

//Terminals must be disjunctive
terminal ENAME:
    ('_'|'A'..'Z') ('_'|'A'..'Z')*
;

terminal EMSG:
    ('!'..'/'|':'..'@'|'['..'~')+
;

terminal SL_COMMENT: 
    '#' !('\n'|'\r')* ('\r'? '\n')?
;

// The following synthetic tokens are used for the indentation-aware blocks
terminal BEGIN: 'synthetic:BEGIN';  // increase indentation
terminal END: 'synthetic:END';      // decrease indentation

But still, this allows either ENAME or EMSG or INT terminals, so you cant mix for example numbers with characters. Problem is terminals have to be disjunctive so if i modify rule "ANYTHING" like this:

terminal ANYTHING:
    (ENAME|EMSG|INT)+
;

or

Anything:
   (ENAME|EMSG|INT)+
;

will be a problem with lexer/parser which cannot determine which terminal is which. How to deal with this situation? Thanks.

//Edit: Thank to Christian for working example, there is still one problem with SL_COMMENT, in this example second error keyword is highlighted with message

missing RULE_END at 'error'

package A : 
    error B :
        a
        #bopsa Akfkfndsfio
    error A_C_S :
        :aasdasdasd

Solution

  • the follwoing grammar works for me

    grammar org.xtext.example.mydsl3.MyDsl hidden (WS, SL_COMMENT)
    
    generate myDsl "http://www.xtext.org/example/mydsl3/MyDsl"
    
    import "http://www.eclipse.org/emf/2002/Ecore" as ecore
    
    Model:
        {Model}
        'package' name=ENAME ':'
        (BEGIN
            (expressions+=Error)+
        END)?
    ;
    
    Error:
        {Error}
        'error' name=ENAME ':'
        (BEGIN
            (expressions+=Anything)+
        END)?
    ;
    
    Anything:
        (ENAME|EMSG|INT|':')
    ;
    
    //Terminals must be disjunctive
    terminal ENAME:
        ('_'|'A'..'Z'|'a'..'z') ('_'|'A'..'Z'|'a'..'z')*
    ;
    terminal INT returns ecore::EInt: ('0'..'9')+;
    
    terminal EMSG:
        ('!'..'/'|';'..'@'|'['..'~')+
    ;
    
    terminal SL_COMMENT: 
        '#' !('\n'|'\r')* ('\r'? '\n')?
    ;
    
    
    
    // The following synthetic tokens are used for the indentation-aware blocks
    terminal BEGIN: 'synthetic:BEGIN';  // increase indentation
    terminal END: 'synthetic:END';      // decrease indentation
    
    terminal WS         : (' '|'\t'|'\r'|'\n')+;
    
    terminal ANY_OTHER: .;