forked from jasder/antlr
finished dyn scope trans. unit tests
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6880]
This commit is contained in:
parent
be72c49e53
commit
33c8efe7e5
|
@ -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)>);"
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}};
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}};
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue