问题
Is there a way to tell ANTLR4 to inline the parser rule?
It seems reasonable to have such feature. After reading the book on ANTLR ("The Definitive ANTLR 4 Reference") I haven't found such possibility, but changes might've been introduced in the 4 years since the book was released, so I guess it is better to ask here.
Consider the following piece of grammar:
file: ( item | class_decl )*;
class_decl: 'class' class_name '{' type_decl* data_decl* code_decl* '}';
type_decl: 'typedef' ('bool'|'int'|'real') type_name;
const_decl: 'const' type_name const_name;
var_decl: 'var' type_name var_name;
...
fragment item: type_decl | data_decl | code_decl;
fragment data_decl: const_decl | var_decl;
fragment code_decl: function_decl | procedure_decl;
fragment class_name: ID;
fragment type_name: ID;
fragment const_name: ID;
fragment var_name: ID;
The rules marked as fragment are there for clarity/documentation and reusability, however from syntax point of view it is f.e. really a var_decl that is actual direct element of file or class_decl and I'd like to have it reflected in content of contexts created by the parser. All the intermediate contexts created for item, data_decl etc. are superfluous, needlessly take space and make it so visitor is bound to organizational structure of the grammar instead of its actual meaning.
To sum up - I'd expect ANTLR to turn the above grammar into the following before generation of a parser:
file: ( type_decl | const_decl | var_decl | function_decl | procedure_decl | class_decl )*;
class_decl: 'class' ID '{' type_decl* ( const_decl | var_decl )* ( function_decl | procedure_decl )* '}';
type_decl: 'typedef' ('bool'|'int'|'real') ID;
const_decl: 'const' ID ID;
var_decl: 'var' ID ID;
...
回答1:
No, there is no such thing in parser rules. You could raise an issue/RFE in ANTLRs Github repo for such a thing: https://github.com/antlr/antlr4/issues
回答2:
You can use rule element labels. They provide the similar functionality but more restricted (applicatble for only single token or rule):
file: ( item | class_decl )*;
class_decl: 'class' class_name=ID '{' type_decl* data_decl* code_decl* '}';
type_decl: 'typedef' ('bool'|'int'|'real') type_name=ID;
const_decl: 'const' type_name=ID const_name=ID;
var_decl: 'var' type_name=ID var_name=ID;
...
item: type_decl | data_decl | code_decl;
data_decl: const_decl | var_decl;
code_decl: function_decl | procedure_decl;
来源:https://stackoverflow.com/questions/45191221/is-there-a-parser-equivalent-of-fragment-marking-in-antlr4