working on parse trees

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 9036]
This commit is contained in:
parrt 2011-09-02 17:15:36 -08:00
parent 7aad57fe49
commit 104f39acde
4 changed files with 70 additions and 60 deletions

View File

@ -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) { }
}

View File

@ -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);
}

View File

@ -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 static class TokenNode extends ParseTree {
public Token token;
public TokenNode(Token token) {
this.token = token;
}
public Tree dupNode() {
@Override
public String toString() {
if ( token.getType() == Token.EOF ) return "<EOF>";
return token.getText();
}
}
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<ParseTree> 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<ParseTree>();
children.add(t);
}
public ParseTree getChild(int i) {
if ( children==null || i>=children.size() ) {
return null;
}
public int getType() {
return 0;
return children.get(i);
}
public String getText() {
return toString();
}
public ParseTree getParent() { return parent; }
public int getTokenStartIndex() {
return 0;
}
public void setParent(ParseTree t) { parent = t; }
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 "<EOF>";
}
return t.getText();
}
return payload.toString();
}
/** Emit a token and all hidden nodes before. EOF node holds all
* hidden tokens after last real token.
*/
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);
}
}

View File

@ -128,8 +128,9 @@ public QStack\<<currentRule.ctxType>\> <currentRule.name>_stk = new QStack\<<cur
<if(currentRule.modifiers)><currentRule.modifiers:{f | <f> }><else>public final <endif><currentRule.ctxType> <currentRule.name>(<currentRule.args; separator=",">) throws RecognitionException {
<currentRule.ctxType> _localctx = new <currentRule.ctxType>(_ctx, <currentRule.startState><currentRule.args:{a | , <a.name>}>);
_ctx = _localctx;
<currentRule.name>_stk.push(_localctx);
_ctx = _localctx;
enterRule(<currentRule.index>);
_localctx.start = input.LT(1);
//System.out.println("enter "+ruleNames[<currentRule.index>]+", LT(1)="+input.LT(1).getText());
<namedActions.init>
@ -148,6 +149,7 @@ public QStack\<<currentRule.ctxType>\> <currentRule.name>_stk = new QStack\<<cur
<currentRule.name>_stk.pop();
_ctx = (ParserRuleContext)_ctx.parent;
<finallyAction>
exitRule(<currentRule.index>);
// System.out.println("exit "+ruleNames[<currentRule.index>]);
}
return _localctx;