View Javadoc
1   /*
2    * Portions of this software was developed by employees of the National Institute
3    * of Standards and Technology (NIST), an agency of the Federal Government and is
4    * being made available as a public service. Pursuant to title 17 United States
5    * Code Section 105, works of NIST employees are not subject to copyright
6    * protection in the United States. This software may be subject to foreign
7    * copyright. Permission in the United States and in foreign countries, to the
8    * extent that NIST may hold copyright, to use, copy, modify, create derivative
9    * works, and distribute this software and its documentation without fee is hereby
10   * granted on a non-exclusive basis, provided that this notice and disclaimer
11   * of warranty appears in all copies.
12   *
13   * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER
14   * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY
15   * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF
16   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM
17   * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE
18   * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE.  IN NO EVENT
19   * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT,
20   * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM,
21   * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY,
22   * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR
23   * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT
24   * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER.
25   */
26  
27  package gov.nist.secauto.metaschema.core.metapath;
28  
29  import gov.nist.secauto.metaschema.core.metapath.antlr.metapath10Parser;
30  import gov.nist.secauto.metaschema.core.util.ObjectUtils;
31  
32  import org.antlr.v4.runtime.ParserRuleContext;
33  import org.antlr.v4.runtime.RuleContext;
34  import org.antlr.v4.runtime.tree.ParseTree;
35  
36  import java.io.PrintStream;
37  import java.util.List;
38  
39  import edu.umd.cs.findbugs.annotations.NonNull;
40  
41  class CSTPrinter {
42    @NonNull
43    private final PrintStream outputStream;
44    private boolean ignoringWrappers = true;
45  
46    /**
47     * Construct a new concrete syntax tree (CST) printer.
48     *
49     * @param outputStream
50     *          the stream to print to
51     */
52    public CSTPrinter(@NonNull PrintStream outputStream) {
53      this.outputStream = ObjectUtils.requireNonNull(outputStream, "outputStream");
54    }
55  
56    /**
57     * Set the behavior for handling wrapper nodes in the CST hierarchy.
58     *
59     * @param ignoringWrappers
60     *          {@code true} if wrappers should be ignored or {@code false}
61     *          otherwise
62     */
63    public void setIgnoringWrappers(boolean ignoringWrappers) {
64      this.ignoringWrappers = ignoringWrappers;
65    }
66  
67    /**
68     * Print a given CST {@link RuleContext} node.
69     *
70     * @param ctx
71     *          the CST node
72     */
73    public void print(@NonNull RuleContext ctx) {
74      explore(ctx, 0);
75    }
76  
77    /**
78     * Print a given CST {@link ParseTree} using the provided {@code ruleNames}.
79     *
80     * @param tree
81     *          the CST parse tree
82     * @param ruleNames
83     *          the list of rule names to use for human readability
84     */
85    public void print(ParseTree tree, List<String> ruleNames) {
86      explore((RuleContext) tree.getPayload(), 0);
87    }
88  
89    private void explore(RuleContext ctx, int indentation) {
90      boolean toBeIgnored = ignoringWrappers && ctx.getChildCount() == 1 && ctx.getChild(0) instanceof ParserRuleContext;
91      String ruleName = metapath10Parser.ruleNames[ctx.getRuleIndex()];
92      for (int i = 0; i < indentation; i++) {
93        outputStream.print("  ");
94      }
95      outputStream.print(ruleName);
96      if (toBeIgnored) {
97        outputStream.print("(ignored)");
98      }
99      outputStream.print(": ");
100     outputStream.print(ctx.getText());
101     outputStream.println();
102 
103     for (int i = 0; i < ctx.getChildCount(); i++) {
104       ParseTree element = ctx.getChild(i);
105       if (element instanceof RuleContext) {
106         explore((RuleContext) element, indentation + 1);
107       }
108     }
109   }
110 }