grammarxtextbnfcontext-sensitive-grammar

How best to write this xtext grammar


I am using Xtext, and need suggestions on the following two problems.

Problem #1

Lets say I have three rules a, b and c. And I want to allow any sequence of these rules, except that b and c should appear only once. How best to write such a grammar?

Here is what I came up with:

root:
  a+=a*
  b=b
  a+=a*
  c=c
  a+=a*
;
a: 'a';
b: 'b';
c: 'c';

Is there a better way to write root grammar? b and c still have to be in a strict order, which is not ideal.

Problem #2

Have a look at this grammar:

root:
    any+=any*
    x=x
    any+=any*
;

any:
    name=ID
    '{'
        any+=any*
    '}'
;

x:
    name='x' '{' y=y '}'
;

y:
    name='y' '{' z=z '}'
;

z:
    name='z' '{' any+=any* '}'
;

Using this grammar I expected to be able to write a language like below:

a {
    b {

    }

    c {
        y {

        }
    }
}

x {
    y {
        z {
            the_end {}
        }
    }
}

However, I get an error due to the node "y" appearing under "c". Why is that? Is it because now that "y" has been used as a terminal in one of the rules, it cannot appear anywhere else in the grammar?

How to fix this grammar?


Solution

  • For problem #1:

    root: a+=a* (b=b a+=a* & c=c a+=a*);
    

    For problem #2 you need a datatype rule like this:

    IdOrABC: ID | 'a' | 'b' | 'c' ;
    

    and you have to use it in your any rule like name=IdOrABC instead of name=ID.