finished dyn scope trans. unit tests

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6880]
This commit is contained in:
parrt 2010-05-21 13:45:12 -08:00
parent be72c49e53
commit 33c8efe7e5
9 changed files with 167 additions and 37 deletions

View File

@ -217,12 +217,18 @@ RulePropertyRef_tree(r) ::= "(<r.label>!=null?((<file.ASTLabelType>)<r.label>.t
RulePropertyRef_text(r) ::= "(<r.label>!=null?((TokenStream)state.input).toString(<r.label>.start,<r.label>.stop):null)"
RulePropertyRef_st(r) ::= "(<r.label>!=null?<r.label>.st:null)"
DynScopeAttrRef(s) ::= "(<s.scope>_stack.peek()).<s.attr>"
DynScopeAttrRef_negIndex(s, indexChunks) ::= <<
(<s.scope>_stack.elementAt(<s.scope>_stack.size()-<indexChunks>-1)).<s.attr>
>>
DynScopeAttrRef_index(s, indexChunks) ::=
"(<s.scope>_stack.elementAt(<indexChunks>)).<s.attr>"
DynScopeRef(s) ::= "<s.scope>_stack"
DynScopeAttrRef(s) ::= "<s.scope>_stack.peek().<s.attr>"
DynScopeAttrRef_negIndex(s, indexChunks) ::=
"<s.scope>_stack.get(<s.scope>_stack.size()-<indexChunks>-1).<s.attr>"
DynScopeAttrRef_index(s, indexChunks) ::=
"<s.scope>_stack.get(<indexChunks>).<s.attr>"
SetDynScopeAttr(s, rhsChunks) ::=
"<s.scope>_stack.peek().<s.attr> =<rhsChunks>;"
SetDynScopeAttr_negIndex(s, indexChunks, rhsChunks) ::=
"<s.scope>_stack.get(<s.scope>_stack.size()-<indexChunks>-1).<s.attr> =<rhsChunks>;"
SetDynScopeAttr_index(s, indexChunks, rhsChunks) ::=
"<s.scope>_stack.get(<indexChunks>).<s.attr> =<rhsChunks>;"
AddToList(a) ::= "<a.listName>.add(<first(a.opWithResultToAdd.labels)>);"

View File

@ -80,7 +80,6 @@ public class ActionTranslator implements ActionSplitterListener {
}
public void attr(String expr, Token x) {
// TODO: $SCOPENAME
System.out.println("attr "+x);
Attribute a = node.resolver.resolveToAttribute(x.getText(), node);
if ( a!=null ) {
@ -99,7 +98,8 @@ public class ActionTranslator implements ActionSplitterListener {
return; // $ids for ids+=ID etc...
}
if ( node.resolver.resolveToDynamicScope(x.getText(), node)!=null ) {
return; // $S for scope S is ok
chunks.add(new DynScopeRef(getDynamicScopeName(x.getText()))); // $S for scope S is ok
return;
}
// switch ( a.dict.type ) {
// case ARG: chunks.add(new ArgRef(x.getText())); break;
@ -149,31 +149,34 @@ public class ActionTranslator implements ActionSplitterListener {
public void dynamicScopeAttr(String expr, Token x, Token y) {
System.out.println("scoped "+x+"."+y);
// we assume valid, just gen code
String scope = x.getText();
if ( factory.g.getRule(x.getText())!=null ) {
scope = factory.gen.target.getRuleDynamicScopeStructName(scope);
}
chunks.add(new DynScopeAttrRef(scope, y.getText()));
chunks.add(new DynScopeAttrRef(getDynamicScopeName(x.getText()), y.getText()));
}
public void setDynamicScopeAttr(String expr, Token x, Token y, Token rhs) {
List<ActionChunk> rhsChunks = translateActionChunk(factory,rf,rhs.getText(),node);
chunks.add(new SetDynScopeAttr(getDynamicScopeName(x.getText()), y.getText(), rhsChunks));
}
public void dynamicNegativeIndexedScopeAttr(String expr, Token x, Token y, Token index) {
List<ActionChunk> indexChunks = translateActionChunk(factory,rf,index.getText(),node);
chunks.add(new DynScopeAttrRef_negIndex(x.getText(), y.getText(), indexChunks));
chunks.add(new DynScopeAttrRef_negIndex(getDynamicScopeName(x.getText()), y.getText(), indexChunks));
}
public void setDynamicNegativeIndexedScopeAttr(String expr, Token x, Token y, Token index, Token rhs) {
List<ActionChunk> indexChunks = translateActionChunk(factory,rf,index.getText(),node);
List<ActionChunk> rhsChunks = translateActionChunk(factory,rf,rhs.getText(),node);
chunks.add(new SetDynScopeAttr_negIndex(getDynamicScopeName(x.getText()), y.getText(), indexChunks, rhsChunks));
}
public void dynamicAbsoluteIndexedScopeAttr(String expr, Token x, Token y, Token index) {
List<ActionChunk> indexChunks = translateActionChunk(factory,rf,index.getText(),node);
chunks.add(new DynScopeAttrRef_index(x.getText(), y.getText(), indexChunks));
chunks.add(new DynScopeAttrRef_index(getDynamicScopeName(x.getText()), y.getText(), indexChunks));
}
public void setDynamicAbsoluteIndexedScopeAttr(String expr, Token x, Token y, Token index, Token rhs) {
List<ActionChunk> indexChunks = translateActionChunk(factory,rf,index.getText(),node);
List<ActionChunk> rhsChunks = translateActionChunk(factory,rf,rhs.getText(),node);
chunks.add(new SetDynScopeAttr_index(getDynamicScopeName(x.getText()), y.getText(), indexChunks, rhsChunks));
}
public void templateInstance(String expr) {
@ -236,6 +239,17 @@ public class ActionTranslator implements ActionSplitterListener {
return factory.gen.target.getImplicitRuleLabel(x);
}
public String getDynamicScopeName(String x) {
String scope;
if ( factory.g.getRule(x)==null ) {
scope = factory.gen.target.getGlobalDynamicScopeStructName(x);
}
else {
scope = factory.gen.target.getRuleDynamicScopeStructName(x);
}
return scope;
}
// public String getTokenLabel(String x, ActionAST node) {
// Alternative alt = node.resolver.
// Rule r = node.nfaState.rule;

View File

@ -55,7 +55,7 @@ public class OutputModelWalker {
// ENSURE TEMPLATE ARGS AND CHILD FIELDS MATCH UP
while ( it.hasNext() ) {
String argName = it.next();
if ( !kids.contains(argName) ) {
if ( kids==null || !kids.contains(argName) ) {
tool.errMgr.toolError(ErrorType.CODE_TEMPLATE_ARG_ISSUE, templateName, argName);
return st;
}

View File

@ -136,6 +136,7 @@ public class Target {
return r.name+"_ctx";
}
public String getRuleDynamicScopeStructName(String ruleName) { return ruleName+"_scope"; }
public String getGlobalDynamicScopeStructName(String scopeName) { return scopeName; }
// should be same for all refs to same token like $ID within single rule function
public String getImplicitTokenLabel(String tokenName) { return "_t"+tokenName; }

View File

@ -0,0 +1,10 @@
package org.antlr.v4.codegen.src.actions;
/** */
public class DynScopeRef extends ActionChunk {
public String scope;
public DynScopeRef(String scope) {
this.scope = scope;
}
}

View File

@ -0,0 +1,26 @@
package org.antlr.v4.codegen.src.actions;
import java.util.ArrayList;
import java.util.List;
/** */
public class SetDynScopeAttr extends ActionChunk {
public String scope;
public String attr;
public List<ActionChunk> rhsChunks;
public SetDynScopeAttr(String scope, String attr, List<ActionChunk> rhsChunks) {
this.scope = scope;
this.attr = attr;
this.rhsChunks = rhsChunks;
}
@Override
public List<String> getChildren() {
final List<String> sup = super.getChildren();
return new ArrayList<String>() {{
if ( sup!=null ) addAll(sup);
add("rhsChunks");
}};
}
}

View File

@ -0,0 +1,22 @@
package org.antlr.v4.codegen.src.actions;
import java.util.ArrayList;
import java.util.List;
/** */
public class SetDynScopeAttr_index extends SetDynScopeAttr {
public List<ActionChunk> indexChunks;
public SetDynScopeAttr_index(String scope, String attr, List<ActionChunk> indexChunks, List<ActionChunk> rhsChunks) {
super(scope, attr, rhsChunks);
this.indexChunks = indexChunks;
}
@Override
public List<String> getChildren() {
final List<String> sup = super.getChildren();
return new ArrayList<String>() {{
if ( sup!=null ) addAll(sup);
add("indexChunks");
}};
}
}

View File

@ -0,0 +1,10 @@
package org.antlr.v4.codegen.src.actions;
import java.util.List;
/** */
public class SetDynScopeAttr_negIndex extends SetDynScopeAttr_index {
public SetDynScopeAttr_negIndex(String scope, String attr, List<ActionChunk> indexChunks, List<ActionChunk> rhsChunks) {
super(scope, attr, indexChunks, rhsChunks);
}
}

View File

@ -136,58 +136,99 @@ public class TestActionTranslation extends BaseTest {
@Test public void testBasicGlobalScope() throws Exception {
String action = "$S::i";
String expected = "((S)S_stack.peek()).i";
String expected = "S_stack.peek().i";
testActions(scopeTemplate, "members", action, expected);
}
@Test public void test0IndexedGlobalScope() throws Exception {
String action = "$S[0]::i";
String expected = "(S_stack.elementAt(0)).i";
String expected = "S_stack.get(0).i";
testActions(scopeTemplate, "members", action, expected);
}
@Test public void testAbsoluteIndexedGlobalScope() throws Exception {
String action = "$S[3]::i";
String expected = "(S_stack.elementAt(3)).i";
String expected = "S_stack.get(3).i";
testActions(scopeTemplate, "members", action, expected);
}
@Test public void testNegIndexedGlobalScope() throws Exception {
String action = "$S[-1]::i";
String expected = "(S_stack.elementAt(S_stack.size()-1-1)).i";
String expected = "S_stack.get(S_stack.size()-1-1).i";
testActions(scopeTemplate, "members", action, expected);
}
@Test public void testNegIndexedGlobalScope2() throws Exception {
String action = "$S[-$S::i]::i";
String expected = "(S_stack.elementAt(S_stack.size()-(S_stack.peek()).i-1)).i";
String expected = "S_stack.get(S_stack.size()-S_stack.peek().i-1).i";
testActions(scopeTemplate, "members", action, expected);
}
@Test public void testBasicRuleScope() throws Exception {
String action = "$a::z";
String expected = "(a_scope_stack.peek()).z";
testActions(scopeTemplate, "inline", action, expected);
}
@Test public void testBasicGlobalScopeInRule() throws Exception {
String action = "$S::i";
String expected = "(S_stack.peek()).i";
@Test public void testBasicRuleScope() throws Exception {
String action = "$a::z";
String expected = "a_scope_stack.peek().z";
testActions(scopeTemplate, "inline", action, expected);
}
@Test public void testUnqualifiedRuleScopeAccessInsideRule() throws Exception {
String action = "$n;";
}
@Test public void testBasicGlobalScopeInRule() throws Exception {
String action = "$S::i";
String expected = "S_stack.peek().i";
testActions(scopeTemplate, "inline", action, expected);
}
@Test public void testSetBasicRuleScope() throws Exception {
String action = "$a::z = 3;";
String expected = "a_scope_stack.peek().z = 3;";
testActions(scopeTemplate, "inline", action, expected);
}
@Test public void testSetBasicGlobalScopeInRule() throws Exception {
String action = "$S::i = 3;";
String expected = "S_stack.peek().i = 3;";
testActions(scopeTemplate, "inline", action, expected);
}
@Test public void testSet0IndexedGlobalScope() throws Exception {
String action = "$S[0]::i = $S::i;";
String expected = "S_stack.get(0).i = S_stack.peek().i;";
testActions(scopeTemplate, "members", action, expected);
}
@Test public void testSetAbsoluteIndexedGlobalScope() throws Exception {
String action = "$S[3]::i = $S::i;";
String expected = "S_stack.get(3).i = S_stack.peek().i;";
testActions(scopeTemplate, "members", action, expected);
}
@Test public void testSetNegIndexedGlobalScope() throws Exception {
String action = "$S[-1]::i = $S::i;";
String expected = "S_stack.get(S_stack.size()-1-1).i = S_stack.peek().i;";
testActions(scopeTemplate, "members", action, expected);
}
@Test public void testSetNegIndexedGlobalScope2() throws Exception {
String action = "$S[-$S::i]::i = $S::i;";
String expected = "S_stack.get(S_stack.size()-S_stack.peek().i-1).i = S_stack.peek().i;";
testActions(scopeTemplate, "members", action, expected);
}
@Test public void testIsolatedDynamicRuleScopeRef() throws Exception {
String action = "$a;"; // refers to stack not top of stack
String expected = "a_scope_stack;";
testActions(scopeTemplate, "inline", action, expected);
}
@Test public void testIsolatedGlobalScopeRef() throws Exception {
String action = "$S;";
String expected = "S_stack;";
testActions(scopeTemplate, "inline", action, expected);
}
@Test public void testDynamicRuleScopeRefInSubrule() throws Exception {
String action = "$a::n;";
}
@Test public void testIsolatedGlobalScopeRef() throws Exception {
String action = "$Symbols;";
}
@Test public void testRuleScopeFromAnotherRule() throws Exception {
String action = "$a::n;"; // must be qualified
}