This is my grammar:
grammar test;
text: foo EOF;
foo:
\'X\'
|
foo
\'!\'
|
foo
\'?\'
|
foo
tail
;
tail: (\' \' foo)+;
<
As far as I can tell, what you want is this:
item: 'X' ('!' | '?')*;
// Alternatively to get a tree per operator instead of a list of operators:
// item
// : 'X'
// | item '!'
// | item '?'
// ;
foo: item (' ' item)*;
Maybe this, if you want the tail still to have its own node in the tree:
item: 'X' ('!' | '?')*;
foo: item tail;
tail: (' ' item)*;
The reason that your version only gave you 1-item lists is that the mutual recursion between foo
and tail
consumed all the items, so there's nothing left for the repetition to consume.
Generally when you have something that can be repeated, you either want to implement this using *
/+
(if you want lists in the resulting tree) or using recursion (if you want a more tree-like tree) - not both.