How best to write this xtext grammar

159 views Asked by At

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?

2

There are 2 answers

1
Bernhard Stadler On BEST ANSWER

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.

2
Waqas Ilyas On

For problem #1, we can adjust the grammar like below:

root:
  a+=a*
  (
    b=b a+=a* c=c
    |
    c=c a+=a* b=b
  )
  a+=a*
;
a: 'a';
b: 'b';
c: 'c';

On the other hand, the problem #2 cannot really be solved via the grammar as parser can never differentiate between an ID and the special keyword "x", "y" or "z". Perhaps a better strategy would be to keep the grammar simple like below: root: any+=any+ ;

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

And enforce the special x/y/z hierarchy via validators.