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?
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
.