For a grammar like, how to preserver the order in which productions appear.
class: 'class' ID
'{' (fields
| methods) * '}' -> ^(CLASS ID ^(FIELD fields*) ^(METHOD methods)
;
The production works as I expect, but if there’s a class like
class abc {
field 1
field 2
method 1
method 2
field 3
method 3
field 4
}
All of the fields end up in single list and the methods in second list. What is the correct way of preserving their order? I tried doing..
class: 'class' ID
'{' (fields -> ^(FIELD fields)
| methods -> ^(METHOD methods)
)* '}' -> ^(CLASS ID $class)
;
I even tried inserting a dummy head in between with no luck.
class: 'class' ID
'{' (fields
| methods) * '}' -> ^(CLASS ID ^(FIELD fields*) ^NODE ^(METHOD methods)
;
but this didn’t work.
In this first case, the
CLASSnode contains a series ofFIELDnodes (FIELD fields*) followed by a series ofMETHODnodes (METHOD methods*) because the production explicitly states thatfieldexpressions be processed together and thenmethodexpressions be processed together:You didn’t mention what the second and third approaches produced, but it was probably less ideal than the first.
Try the following approach with a
bodyexpression instead:You’ll get the following AST result:
If you’d like to test the grammar with ANTLRWorks, open (or create) the grammar with it:
and press CTRL+D to start the debugger (don’t use the interpreter, it’s buggy!):
Paste your input in the window that pops up and make sure you select the correct start production rule (
klass, in this case). Then press OK.When the debugger is launched, press the end-arrow button >| to parse the input and then click the AST button to see what the AST the parser created looks like: