1 module antlr.v4.runtime.tree.ParseTreeWalker;
2 
3 import antlr.v4.runtime.ParserRuleContext;
4 import antlr.v4.runtime.tree.ErrorNode;
5 import antlr.v4.runtime.tree.RuleNode;
6 import antlr.v4.runtime.tree.TerminalNode;
7 import antlr.v4.runtime.tree.ParseTreeWalker;
8 import antlr.v4.runtime.tree.ParseTreeListener;
9 import antlr.v4.runtime.tree.ParseTree;
10 
11 class ParseTreeWalker
12 {
13     public static immutable ParseTreeWalker DEFAULT;
14 
15     /**
16      * Performs a walk on the given parse tree starting at the root and going down recursively
17      * with depth-first search. On each node, {@link ParseTreeWalker#enterRule} is called before
18      * recursively walking down into child nodes, then
19      * {@link ParseTreeWalker#exitRule} is called after the recursive call to wind up.
20      * @param listener The listener used by the walker to process grammar rules
21      * @param t The parse tree to be walked on
22      */
23     public void walk(ParseTreeListener listener, ParseTree t)
24     {
25         if (cast(ErrorNode) t) {
26             listener.visitErrorNode(cast(ErrorNode)t);
27             return;
28         }
29         else if (cast(TerminalNode) t) {
30             listener.visitTerminal(cast(TerminalNode)t);
31             return;
32         }
33         RuleNode r = cast(RuleNode) t;
34         enterRule(listener, r);
35         int n = r.getChildCount();
36         for (int i = 0; i<n; i++) {
37             walk(listener, r.getChild(i));
38         }
39         exitRule(listener, r);
40     }
41 
42 	/**
43 	 * Enters a grammar rule by first triggering the generic event {@link ParseTreeListener#enterEveryRule}
44 	 * then by triggering the event specific to the given parse tree node
45 	 * @param listener The listener responding to the trigger events
46 	 * @param r The grammar rule containing the rule context
47 	 */
48     protected void enterRule(ParseTreeListener listener, RuleNode r)
49     {
50         ParserRuleContext ctx = cast(ParserRuleContext) r.getRuleContext();
51         listener.enterEveryRule(ctx);
52         ctx.enterRule(listener);
53     }
54 
55 	/**
56 	 * Exits a grammar rule by first triggering the event specific to the given parse tree node
57 	 * then by triggering the generic event {@link ParseTreeListener#exitEveryRule}
58 	 * @param listener The listener responding to the trigger events
59 	 * @param r The grammar rule containing the rule context
60 	 */
61     public void exitRule(ParseTreeListener listener, RuleNode r)
62     {
63         ParserRuleContext ctx = cast(ParserRuleContext) r.getRuleContext();
64         ctx.exitRule(listener);
65         listener.exitEveryRule(ctx);
66     }
67 }