removes the individual stacks to track rule invocations. $a::x now looks up the context stack for rule index RULE_a. they're not done very often and so it's better to say all of the overhead pushing and popping the contexts.

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 9066]
This commit is contained in:
parrt 2011-09-11 16:12:01 -08:00
parent 0e608ab0a4
commit a1c682434d
6 changed files with 39 additions and 18 deletions

View File

@ -586,6 +586,20 @@ public abstract class BaseRecognizer extends Recognizer<ParserATNSimulator> {
}
}
public ParserRuleContext getInvokingContext(int ruleIndex) {
ParserRuleContext p = _ctx;
while ( p!=null ) {
if ( p.getRuleIndex() == ruleIndex ) return p;
p = (ParserRuleContext)p.parent;
}
return null;
}
public boolean inContext(String context) {
// TODO: useful in parser?
return false;
}
/** Return List<String> of the rules in your parser instance
* leading up to a call to this method. You could override if
* you want more details such as the file/line info of where
@ -595,6 +609,7 @@ public abstract class BaseRecognizer extends Recognizer<ParserATNSimulator> {
* error recovery.
*/
public List getRuleInvocationStack() {
// TODO: walk ctx chain now; this is legacy
String parserClassName = getClass().getName();
return getRuleInvocationStack(new Throwable(), parserClassName);
}
@ -609,6 +624,7 @@ public abstract class BaseRecognizer extends Recognizer<ParserATNSimulator> {
public static List getRuleInvocationStack(Throwable e,
String recognizerClassName)
{
// TODO: walk ctx chain now; this is legacy
List rules = new ArrayList();
StackTraceElement[] stack = e.getStackTrace();
int i = 0;

View File

@ -1,7 +1,7 @@
grammar T;
s : i=ifstat {System.out.println(_input.toString(0,_input.index()-1));} ;
ifstat : 'if' '(' INT ')' ID '=' ID ';' # DoIf;
ifstat : 'if' {$s::start = null;} '(' INT ')' ID '=' ID ';' # DoIf;
r[int x] returns [int y]
locals [int z]

View File

@ -159,11 +159,8 @@ RuleFunction(currentRule,code,locals,ruleCtx,altLabelCtxs,namedActions,finallyAc
<ruleCtx>
<altLabelCtxs; separator="\n">
public QStack\<<currentRule.ctxType>\> <currentRule.name>_stk = new QStack\<<currentRule.ctxType>\>();
<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>}>);
<currentRule.name>_stk.push(_localctx);
enterRule(_localctx, <currentRule.index>);
//System.out.println("enter "+ruleNames[<currentRule.index>]+", LT(1)="+_input.LT(1).getText());
<namedActions.init>
@ -179,7 +176,6 @@ public QStack\<<currentRule.ctxType>\> <currentRule.name>_stk = new QStack\<<cur
recover();
}
finally {
<currentRule.name>_stk.pop();
<finallyAction>
exitRule(<currentRule.index>);
// System.out.println("exit "+ruleNames[<currentRule.index>]);
@ -419,10 +415,9 @@ ThisRulePropertyRef_tree(r) ::= "_localctx.tree"
ThisRulePropertyRef_text(r) ::= "((TokenStream)_input).toString(_localctx.start, _input.LT(-1))"
ThisRulePropertyRef_st(r) ::= "_localctx.st"
//NonLocalContextRef(s) ::= "<s.scope>"
NonLocalAttrRef(s) ::= "<s.scope>.peek().<s.attr>"
NonLocalAttrRef(s) ::= "((<s.ruleName>Context)getInvokingContext(<s.ruleIndex>)).<s.name>"
SetNonLocalAttr(s, rhsChunks) ::=
"<s.scope>.peek().<s.attr> =<rhsChunks>;"
"((<s.ruleName>Context)getInvokingContext(<s.ruleIndex>)).<s.name> = <rhsChunks>;"
AddToLabelList(a) ::= "_localctx.<a.listName>.add(<labelref(a.label)>);"

View File

@ -207,14 +207,16 @@ public class ActionTranslator implements ActionSplitterListener {
}
public void nonLocalAttr(String expr, Token x, Token y) {
System.out.println("nonLocalAttr "+x+"."+y);
chunks.add(new NonLocalAttrRef(x.getText(), y.getText()));
System.out.println("nonLocalAttr "+x+"::"+y);
Rule r = factory.getGrammar().getRule(x.getText());
chunks.add(new NonLocalAttrRef(x.getText(), y.getText(), r.index));
}
public void setNonLocalAttr(String expr, Token x, Token y, Token rhs) {
System.out.println("setNonLocalAttr "+x+"::"+y+"="+rhs);
Rule r = factory.getGrammar().getRule(x.getText());
List<ActionChunk> rhsChunks = translateActionChunk(factory,rf,rhs.getText(),node);
SetNonLocalAttr s = new SetNonLocalAttr(x.getText(), y.getText(), rhsChunks);
SetNonLocalAttr s = new SetNonLocalAttr(x.getText(), y.getText(), r.index, rhsChunks);
chunks.add(s);
}

View File

@ -30,11 +30,14 @@
package org.antlr.v4.codegen.model.actions;
public class NonLocalAttrRef extends ActionChunk {
public String context;
public String ruleName;
public String name;
public NonLocalAttrRef(String context, String name) {
this.context = context;
public int ruleIndex;
public NonLocalAttrRef(String ruleName, String name, int ruleIndex) {
this.name = name;
this.ruleName = ruleName;
this.ruleIndex = ruleIndex;
}
}

View File

@ -32,9 +32,14 @@ package org.antlr.v4.codegen.model.actions;
import java.util.List;
public class SetNonLocalAttr extends SetAttr {
public String context;
public SetNonLocalAttr(String context, String name, List<ActionChunk> rhsChunks) {
public String ruleName;
public int ruleIndex;
public SetNonLocalAttr(String ruleName, String name, int ruleIndex,
List<ActionChunk> rhsChunks)
{
super(name, rhsChunks);
this.context = context;
this.ruleName = ruleName;
this.ruleIndex = ruleIndex;
}
}