diff --git a/runtime/Java/src/org/antlr/v4/runtime/Parser.java b/runtime/Java/src/org/antlr/v4/runtime/Parser.java index 8c09e0d50..2ec5457b0 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/Parser.java +++ b/runtime/Java/src/org/antlr/v4/runtime/Parser.java @@ -80,18 +80,26 @@ public class Parser extends BaseRecognizer { } public TokenStream getTokenStream() { - return (TokenStream)input; + return input; } public String getSourceName() { return input.getSourceName(); } - public void traceIn(int ruleIndex, ParserRuleContext ctx) { - super.traceIn(getRuleNames()[ruleIndex], ruleIndex, input.LT(1)); - } + /** Always called by generated parsers upon entry to a rule. + * This occurs after the new context has been pushed. Access field + * _ctx get the current context. + * + * The HotSpot compiler should optimize/inline these empty methods + * so there is no overhead to always having the parser call them. + * It is also much more flexible because users do not have to + * regenerate parsers to get trace facilities. + * + * These methods along with an override of match() are used to build + * parse trees as well. + */ + public void enterRule(int ruleIndex) { } - public void traceOut(int ruleIndex, ParserRuleContext ctx) { - super.traceOut(getRuleNames()[ruleIndex], ruleIndex, input.LT(1)); - } + public void exitRule(int ruleIndex) { } } diff --git a/runtime/Java/src/org/antlr/v4/runtime/debug/Tracer.java b/runtime/Java/src/org/antlr/v4/runtime/debug/Tracer.java index 503b1efa0..105a6bacc 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/debug/Tracer.java +++ b/runtime/Java/src/org/antlr/v4/runtime/debug/Tracer.java @@ -42,19 +42,21 @@ public class Tracer extends BlankDebugEventListener { this.input = input; } - public void enterRule(String ruleName) { + @Override + public void enterRule(String grammarFileName, String ruleName) { for (int i=1; i<=level; i++) {System.out.print(" ");} System.out.println("> "+ruleName+" lookahead(1)="+getInputSymbol(1)); level++; } - public void exitRule(String ruleName) { + @Override + public void exitRule(String grammarFileName, String ruleName) { level--; for (int i=1; i<=level; i++) {System.out.print(" ");} System.out.println("< "+ruleName+" lookahead(1)="+getInputSymbol(1)); } - public Object getInputSymbol(int k) { + protected Object getInputSymbol(int k) { if ( input instanceof TokenStream) { return ((TokenStream)input).LT(k); } diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/ParseTree.java b/runtime/Java/src/org/antlr/v4/runtime/tree/ParseTree.java index d3ba7e022..0f0decdf9 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/ParseTree.java +++ b/runtime/Java/src/org/antlr/v4/runtime/tree/ParseTree.java @@ -27,63 +27,61 @@ */ package org.antlr.v4.runtime.tree; +import org.antlr.v4.runtime.RuleContext; import org.antlr.v4.runtime.Token; +import java.util.ArrayList; import java.util.List; /** A record of the rules used to match a token sequence. The tokens * end up as the leaves of this tree and rule nodes are the interior nodes. - * This really adds no functionality, it is just an alias for CommonTree - * that is more meaningful (specific) and holds a String to display for a node. */ -public class ParseTree extends BaseTree { - public Object payload; - public List hiddenTokens; +public abstract class ParseTree { - public ParseTree(Object label) { - this.payload = label; - } - - public Tree dupNode() { - return null; - } - - public int getType() { - return 0; - } - - public String getText() { - return toString(); - } - - public int getTokenStartIndex() { - return 0; - } - - public void setTokenStartIndex(int index) { - } - - public int getTokenStopIndex() { - return 0; - } - - public void setTokenStopIndex(int index) { - } - - public String toString() { - if ( payload instanceof Token ) { - Token t = (Token)payload; - if ( t.getType() == Token.EOF ) { - return ""; - } - return t.getText(); + public static class TokenNode extends ParseTree { + public Token token; + public TokenNode(Token token) { + this.token = token; + } + + @Override + public String toString() { + if ( token.getType() == Token.EOF ) return ""; + return token.getText(); } - return payload.toString(); } - /** Emit a token and all hidden nodes before. EOF node holds all - * hidden tokens after last real token. - */ + public static class RuleNode extends ParseTree { + public RuleContext ctx; + public String ruleName; + public RuleNode(String ruleName, RuleContext ctx) { + this.ruleName = ruleName; + this.ctx = ctx; + } + public String toString() { return ruleName; } + } + + protected ParseTree parent; + protected List children; + protected List hiddenTokens; + + /** Add t as child of this node. t must not be nil node. */ + public void addChild(ParseTree t) { + if ( children==null ) children = new ArrayList(); + children.add(t); + } + + public ParseTree getChild(int i) { + if ( children==null || i>=children.size() ) { + return null; + } + return children.get(i); + } + + public ParseTree getParent() { return parent; } + + public void setParent(ParseTree t) { parent = t; } + public String toStringWithHiddenTokens() { StringBuffer buf = new StringBuffer(); if ( hiddenTokens!=null ) { @@ -106,13 +104,13 @@ public class ParseTree extends BaseTree { return buf.toString(); } - public void _toStringLeaves(StringBuffer buf) { - if ( payload instanceof Token ) { // leaf node token? + protected void _toStringLeaves(StringBuffer buf) { + if ( children==null ) { // leaf node token? buf.append(this.toStringWithHiddenTokens()); return; } for (int i = 0; children!=null && i < children.size(); i++) { - ParseTree t = (ParseTree)children.get(i); + ParseTree t = children.get(i); t._toStringLeaves(buf); } } diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg index 2384c7aae..64264a605 100644 --- a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg @@ -128,8 +128,9 @@ public QStack\<\> _stk = new QStack\< }>public final () throws RecognitionException { _localctx = new (_ctx, }>); - _ctx = _localctx; _stk.push(_localctx); + _ctx = _localctx; + enterRule(); _localctx.start = input.LT(1); //System.out.println("enter "+ruleNames[]+", LT(1)="+input.LT(1).getText()); @@ -148,6 +149,7 @@ public QStack\<\> _stk = new QStack\<_stk.pop(); _ctx = (ParserRuleContext)_ctx.parent; + exitRule(); // System.out.println("exit "+ruleNames[]); } return _localctx;