antlr4/java: pretty print parse tree to stdout

前端 未结 4 1528
抹茶落季
抹茶落季 2021-02-06 04:14

Beginners question: how do I print a readable version of the parse tree to stdout?

CharStream input = CharStreams.fromFileName(\"testdata/test.txt\");
MyLexer le         


        
4条回答
  •  孤独总比滥情好
    2021-02-06 04:44

    Extracted from SnippetsTest as a standalone utility class:

    import java.util.List;
    
    import org.antlr.v4.runtime.misc.Utils;
    import org.antlr.v4.runtime.tree.Tree;
    import org.antlr.v4.runtime.tree.Trees;
    
    public class TreeUtils {
    
        /** Platform dependent end-of-line marker */
        public static final String Eol = System.lineSeparator();
        /** The literal indent char(s) used for pretty-printing */
        public static final String Indents = "  ";
        private static int level;
    
        private TreeUtils() {}
    
        /**
         * Pretty print out a whole tree. {@link #getNodeText} is used on the node payloads to get the text
         * for the nodes. (Derived from Trees.toStringTree(....))
         */
        public static String toPrettyTree(final Tree t, final List ruleNames) {
            level = 0;
            return process(t, ruleNames).replaceAll("(?m)^\\s+$", "").replaceAll("\\r?\\n\\r?\\n", Eol);
        }
    
        private static String process(final Tree t, final List ruleNames) {
            if (t.getChildCount() == 0) return Utils.escapeWhitespace(Trees.getNodeText(t, ruleNames), false);
            StringBuilder sb = new StringBuilder();
            sb.append(lead(level));
            level++;
            String s = Utils.escapeWhitespace(Trees.getNodeText(t, ruleNames), false);
            sb.append(s + ' ');
            for (int i = 0; i < t.getChildCount(); i++) {
                sb.append(process(t.getChild(i), ruleNames));
            }
            level--;
            sb.append(lead(level));
            return sb.toString();
        }
    
        private static String lead(int level) {
            StringBuilder sb = new StringBuilder();
            if (level > 0) {
                sb.append(Eol);
                for (int cnt = 0; cnt < level; cnt++) {
                    sb.append(Indents);
                }
            }
            return sb.toString();
        }
    }
    

    Call the method as follows:

    List ruleNamesList = Arrays.asList(parser.getRuleNames());
    String prettyTree = TreeUtils.toPrettyTree(tree, ruleNamesList);
    

提交回复
热议问题