// Process the productions.
for (Production p : m.productions) analyzer.process(p);
// Print the header.
final Printer printer = runtime.console();
printer.sep();
printer.indent().p("// Generated by Rats!, version ").p(Constants.VERSION).
p(", ").p(Constants.COPY).pln('.');
printer.sep();
printer.pln();
printer.indent().p("/** AST structure for grammar ").p(m.name.name).
pln(". */");
// Ensure that all tuples are concrete and then print the result.
if (! runtime.test("optionVariant")) {
// Flat AST definition.
final VariantT node = ast.toVariant("Node", false);
ast.concretizeTuples(node, UnitT.TYPE);
printer.indent().p("module ").p(m.name.name).p("Tree").pln(';');
printer.pln();
ast.print(node, printer, true, false, null);
printer.pln();
} else {
// Hierarchical AST definition.
final VariantT root =
analyzer.lookup((NonTerminal)m.getProperty(Properties.ROOT)).
type.resolve().toVariant();
final AST.MetaData meta = ast.getMetaData(root);
final Set<String> processed = new HashSet<String>();
// Concretize variants.
for (Production p : m.productions) {
if (AST.isStaticNode(p.type)) {
final VariantT variant = p.type.resolve().toVariant();
final String name = variant.getName();
if (meta.reachable.contains(name) && ! processed.contains(name)) {
processed.add(name);
ast.concretizeTuples(variant, UnitT.TYPE);
}
}
}
processed.clear();
// Print variants...
if (! meta.modularize) {
// ... in a single module.
printer.indent().p("module ").p(m.name.name).p("Tree").pln(';');
printer.pln();
for (Production p : m.productions) {
if (AST.isStaticNode(p.type)) {
final VariantT variant = p.type.resolve().toVariant();
final String name = variant.getName();
if (meta.reachable.contains(name) && ! processed.contains(name)) {
processed.add(name);
ast.print(variant, printer, true, false, null);
printer.pln();
}
}
}
} else {
// ... across several modules.
boolean first = true;
String module;
do {
module = null;
for (Production p : m.productions) {
if (AST.isStaticNode(p.type)) {
final VariantT variant = p.type.resolve().toVariant();
final String name = variant.getName();
if (meta.reachable.contains(name) && ! processed.contains(name)) {
final String qualifier = variant.getQualifier();
if (null == module) {
module = qualifier;
if (first) {
first = false;
} else {
printer.sep().pln();
}
printer.indent().p("module ").p(module).pln(';');
printer.pln();
} else if (! module.equals(qualifier)) {
continue;
}
processed.add(name);
ast.print(variant, printer, true, true, module);
printer.pln();
}
}
}
} while (null != module);
}
}
printer.sep().flush();
}