got dyn scope code gen partially going

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6879]
This commit is contained in:
parrt 2010-05-20 15:28:34 -08:00
parent 89b05e0954
commit be72c49e53
14 changed files with 288 additions and 163 deletions

View File

@ -26,7 +26,7 @@ import org.antlr.runtime.*;
<parser>
>>
Parser(parser, funcs) ::= <<
Parser(parser, scopes, funcs) ::= <<
public class <parser.name> extends Parser {
<!
public enum TokenType {
@ -38,6 +38,7 @@ public class <parser.name> extends Parser {
}
!>
<parser.tokens.keys:{k | public static final int <k>=<parser.tokens.(k)>;}; separator="\n">
<scopes>
<namedActions.members>
<parser:ctor()>
<funcs; separator="\n">
@ -67,12 +68,13 @@ RuleFunction(f,code,decls,context,scope,namedActions,finallyAction) ::= <<
<scope>
<if(f.modifiers)><f.modifiers:{f | <f> }><else>public final <endif><if(f.ctxType)><f.ctxType><else>void<endif> <f.name>(<f.ctxType> _ctx) throws RecognitionException {
<if(f.scope)>
<f.scope.name>_stack.push(new <f.scope.name>());
<endif>
<if(f.ctxType)>
state.ctx.push(_ctx);
<endif>
<if(f.scope)>
<f.scope.name>_stack.push(new <f.scope.name>());
<endif>
<f.globalScopesUsed:{s | <s>_stack.push(new <s>());}; separator="\n">
<namedActions.init>
<decls; separator="\n">
try {
@ -80,6 +82,7 @@ RuleFunction(f,code,decls,context,scope,namedActions,finallyAction) ::= <<
}
finally {
<namedActions.after>
<f.globalScopesUsed:{s | <s>_stack.pop();}; separator="\n">
<if(f.scope)><f.scope.name>_stack.pop();<endif>
<finallyAction>
<if(f.ctxType)>return (<f.ctxType>)state.ctx.pop();<endif>
@ -214,6 +217,13 @@ 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>"
AddToList(a) ::= "<a.listName>.add(<first(a.opWithResultToAdd.labels)>);"
TokenDecl(t) ::= "Token <t.name>;"
@ -237,7 +247,7 @@ DynamicScopeStruct(d,attrs) ::= <<
public static class <d.name> {
<attrs:{a | <a>;}; separator="\n">
};
public QStack\<<f.scope.name>\> <f.scope.name>_stack = new QStack\<<f.scope.name>\>();
public QStack\<<d.name>\> <d.name>_stack = new QStack\<<d.name>\>();
>>
AttributeDecl(d) ::= "<d.decl>"

View File

@ -80,6 +80,7 @@ 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 ) {
@ -125,7 +126,13 @@ public class ActionTranslator implements ActionSplitterListener {
Attribute a = node.resolver.resolveToAttribute(x.getText(), y.getText(), node);
switch ( a.dict.type ) {
case ARG: chunks.add(new ArgRef(y.getText())); break; // has to be current rule
case RET: chunks.add(new QRetValueRef(getRuleLabel(x.getText()), y.getText())); break;
case RET:
if ( factory.currentRule.size()>0 && factory.currentRule.peek().name.equals(x.getText()) ) {
chunks.add(new RetValueRef(y.getText())); break;
}
else {
chunks.add(new QRetValueRef(getRuleLabel(x.getText()), y.getText())); break;
}
case PREDEFINED_RULE: chunks.add(getRulePropertyRef(x, y)); break;
case TOKEN: chunks.add(getTokenPropertyRef(x, y)); break;
// case PREDEFINED_LEXER_RULE: chunks.add(new RetValueRef(x.getText())); break;
@ -140,18 +147,30 @@ 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()));
}
public void setDynamicScopeAttr(String expr, Token x, Token y, Token rhs) {
}
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));
}
public void setDynamicNegativeIndexedScopeAttr(String expr, Token x, Token y, Token index, Token rhs) {
}
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));
}
public void setDynamicAbsoluteIndexedScopeAttr(String expr, Token x, Token y, Token index, Token rhs) {

View File

@ -135,7 +135,7 @@ public class Target {
if ( r.args==null && r.retvals==null ) return "ParserRuleContext";
return r.name+"_ctx";
}
public String getDynamicScopeStructName(String ruleName) { return ruleName+"_scope"; }
public String getRuleDynamicScopeStructName(String ruleName) { return ruleName+"_scope"; }
// 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

@ -1,6 +1,7 @@
package org.antlr.v4.codegen.src;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.tool.AttributeDict;
import org.antlr.v4.tool.Rule;
import java.util.ArrayList;
@ -13,7 +14,8 @@ public class Parser extends OutputModelObject {
public String name;
public Map<String,Integer> tokens;
public List<RuleFunction> funcs = new ArrayList<RuleFunction>();
ParserFile file;
public List<DynamicScopeStruct> scopes = new ArrayList<DynamicScopeStruct>();
public ParserFile file;
public Parser(OutputModelFactory factory, ParserFile file) {
this.factory = factory;
@ -24,12 +26,15 @@ public class Parser extends OutputModelObject {
Integer ttype = factory.g.tokenNameToTypeMap.get(t);
if ( ttype>0 ) tokens.put(t, ttype);
}
for (AttributeDict d : factory.g.scopes.values()) {
scopes.add( new DynamicScopeStruct(factory, d.name, d.attributes.values()) );
}
for (Rule r : factory.g.rules.values()) funcs.add( new RuleFunction(factory, r) );
}
@Override
public List<String> getChildren() {
final List<String> sup = super.getChildren();
return new ArrayList<String>() {{ if ( sup!=null ) addAll(sup); add("funcs"); }};
return new ArrayList<String>() {{ if ( sup!=null ) addAll(sup); add("funcs"); add("scopes"); }};
}
}

View File

@ -59,10 +59,14 @@ public class RuleFunction extends OutputModelObject {
argsAndReturnValues.addAll(r.retvals.attributes.values());
}
if ( r.scope!=null ) {
scope = new DynamicScopeStruct(factory, factory.gen.target.getDynamicScopeStructName(r.name),
scope = new DynamicScopeStruct(factory, factory.gen.target.getRuleDynamicScopeStructName(r.name),
r.scope.attributes.values());
}
//globalScopesUsed = new ArrayList<String>();
//for (Token t : r.useScopes) globalScopesUsed.add(t.getText());
globalScopesUsed = Utils.apply(r.useScopes, "getText");
if ( argsAndReturnValues.size()>0 ) {
context = new StructDecl(factory, factory.gen.target.getRuleFunctionContextStructName(r),
argsAndReturnValues);

View File

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

View File

@ -0,0 +1,22 @@
package org.antlr.v4.codegen.src.actions;
import java.util.ArrayList;
import java.util.List;
/** */
public class DynScopeAttrRef_index extends DynScopeAttrRef {
public List<ActionChunk> indexChunks;
public DynScopeAttrRef_index(String scope, String attr, List<ActionChunk> indexChunks) {
super(scope, attr);
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 DynScopeAttrRef_negIndex extends DynScopeAttrRef_index {
public DynScopeAttrRef_negIndex(String scope, String attr, List<ActionChunk> indexChunks) {
super(scope, attr, indexChunks);
}
}

View File

@ -2,6 +2,7 @@ package org.antlr.v4.misc;
import org.antlr.v4.tool.GrammarAST;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
@ -117,4 +118,20 @@ public class Utils {
}
return x;
}
public static <From,To> List<To> apply(List<From> list, String methodName) {
if ( list==null ) return null;
List<To> b = new ArrayList<To>();
for (From f : list) {
try {
Method m = f.getClass().getMethod(methodName, (Class[])null);
To r = (To)m.invoke(f, (Object[])null);
b.add(r);
}
catch (Exception e) {
e.printStackTrace(System.err);
}
}
return b;
}
}

View File

@ -82,7 +82,8 @@ public class AttributeChecks implements ActionSplitterListener {
if ( node.resolver.resolveToAttribute(x.getText(), y.getText(), node)==null ) {
Rule rref = isolatedRuleRef(x.getText());
if ( rref!=null ) {
if ( rref!=null && rref.args!=null && rref.args.get(y.getText())!=null ) {
//if ( r.name.equals(x.getText()) ) return; // $a.x in rule a is ok
if ( rref.args!=null && rref.args.get(y.getText())!=null ) {
g.tool.errMgr.grammarError(ErrorType.INVALID_RULE_PARAMETER_REF,
g.fileName, y, y.getText(), expr);
}

View File

@ -78,8 +78,7 @@ public class Alternative implements AttributeResolver {
*/
public Attribute resolveToAttribute(String x, String y, ActionAST node) {
if ( rule.name.equals(x) ) { // x is this rule?
AttributeDict d = rule.getPredefinedScope(LabelType.RULE_LABEL);
return d.get(y);
return rule.resolveToAttribute(x, y, node);
}
if ( tokenRefs.get(x)!=null ) { // token ref in this alt?
return rule.getPredefinedScope(LabelType.TOKEN_LABEL).get(y);

View File

@ -186,8 +186,7 @@ public class Rule implements AttributeResolver {
/** $x.y Attribute: x is surrounding rule, label ref (in any alts) */
public Attribute resolveToAttribute(String x, String y, ActionAST node) {
if ( this.name.equals(x) ) { // x is this rule?
AttributeDict d = getPredefinedScope(LabelType.RULE_LABEL);
return d.get(y);
return resolveToAttribute(y, node);
}
LabelElementPair anyLabelDef = getAnyLabelDef(x);
if ( anyLabelDef!=null ) {
@ -221,7 +220,7 @@ public class Rule implements AttributeResolver {
public boolean resolvesToToken(String x, ActionAST node) {
LabelElementPair anyLabelDef = getAnyLabelDef(x);
if ( anyLabelDef.type==LabelType.TOKEN_LABEL ) return true;
if ( anyLabelDef!=null && anyLabelDef.type==LabelType.TOKEN_LABEL ) return true;
return false;
}

View File

@ -16,9 +16,9 @@ public class TestActionTranslation extends BaseTest {
String attributeTemplate =
"parser grammar A;\n"+
"@members {#members#<members>#end-members#}\n" +
"a[int x] returns [int y]\n" +
"a[int x, int x1] returns [int y]\n" +
"@init {#init#<init>#end-init#}\n" +
" : id=ID ids+=ID lab=b[34] {\n" +
" : id=ID ids+=ID lab=b[34] c d {\n" +
" #inline#<inline>#end-inline#\n" +
" }\n" +
" c\n" +
@ -27,29 +27,24 @@ public class TestActionTranslation extends BaseTest {
"b[int d] returns [int e]\n" +
" : {#inline2#<inline2>#end-inline2#}\n" +
" ;\n" +
"c : ;\n" +
"c returns [int x, int y] : ;\n" +
"d : ;\n";
String scopeTemplate =
"parser grammar A;\n"+
"@members {\n" +
"<members>\n" +
"#members#<members>#end-members#\n" +
"}\n" +
"scope S { int i; }\n" +
"a[int x] returns [int y]\n" +
"a\n" +
"scope { int z; }\n" +
"scope S;\n" +
"@init {<init>}\n" +
" : lab=b[34] {\n" +
" <inline>" +
"@init {#init#<init>#end-init#}\n" +
" : {\n" +
" #inline#<inline>#end-inline#" +
" }\n" +
" ;\n" +
" finally {<finally>}\n" +
"b[int d] returns [int e]\n" +
"scope { int f; }\n" +
" : {<inline2>}\n" +
" ;\n" +
"c : ;";
" finally {#finally#<finally>#end-finally#}\n";
@Test public void testEscapedLessThanInAction() throws Exception {
String action = "i<3; '<xmltag>'";
@ -62,133 +57,125 @@ public class TestActionTranslation extends BaseTest {
}
@Test public void testEscaped$InAction() throws Exception {
String action = "int \\$n; \"\\$in string\\$\"";
}
@Test public void testArguments() throws Exception {
String action = "$i; $i.x; $u; $u.x";
}
@Test public void testComplicatedArgParsing() throws Exception {
String action = "x, (*a).foo(21,33), 3.2+1, '\\n', "+
"\"a,oo\\nick\", {bl, \"fdkj\"eck}";
}
@Test public void testBracketArgParsing() throws Exception {
}
@Test public void testStringArgParsing() throws Exception {
String action = "34, '{', \"it's<\", '\"', \"\\\"\", 19";
}
@Test public void testComplicatedSingleArgParsing() throws Exception {
String action = "(*a).foo(21,33,\",\")";
}
@Test public void testArgWithLT() throws Exception {
String action = "34<50";
}
@Test public void testGenericsAsArgumentDefinition() throws Exception {
String action = "$foo.get(\"ick\");";
}
@Test public void testGenericsAsArgumentDefinition2() throws Exception {
String action = "$foo.get(\"ick\"); x=3;";
}
@Test public void testGenericsAsReturnValue() throws Exception {
}
@Test public void testComplicatedArgParsingWithTranslation() throws Exception {
String action = "x, $A.text+\"3242\", (*$A).foo(21,33), 3.2+1, '\\n', "+
"\"a,oo\\nick\", {bl, \"fdkj\"eck}";
}
@Test public void testRefToReturnValueBeforeRefToPredefinedAttr() throws Exception {
String action = "$x.foo";
}
@Test public void testRuleLabelBeforeRefToPredefinedAttr() throws Exception {
String action = "$x.text";
}
@Test public void testInvalidArguments() throws Exception {
String action = "$x";
}
@Test public void testReturnValue() throws Exception {
String action = "$x.i";
}
@Test public void testReturnValueWithNumber() throws Exception {
String action = "$x.i1";
}
@Test public void testReturnValues() throws Exception {
String action = "$i; $i.x; $u; $u.x";
String action = "int \\$n; \"\\$in string\\$\"";
String expected = "int \\$n; \"\\$in string\\$\"";
testActions(attributeTemplate, "members", action, expected);
testActions(attributeTemplate, "init", action, expected);
testActions(attributeTemplate, "inline", action, expected);
testActions(attributeTemplate, "finally", action, expected);
testActions(attributeTemplate, "inline2", action, expected);
}
@Test public void testComplicatedArgParsing() throws Exception {
String action = "x, (*a).foo(21,33), 3.2+1, '\\n', "+
"\"a,oo\\nick\", {bl, \"fdkj\"eck}";
String expected = "x, (*a).foo(21,33), 3.2+1, '\\n', "+
"\"a,oo\\nick\", {bl, \"fdkj\"eck}";
testActions(attributeTemplate, "members", action, expected);
testActions(attributeTemplate, "init", action, expected);
testActions(attributeTemplate, "inline", action, expected);
testActions(attributeTemplate, "finally", action, expected);
testActions(attributeTemplate, "inline2", action, expected);
}
@Test public void testComplicatedArgParsingWithTranslation() throws Exception {
String action = "x, $ID.text+\"3242\", (*$ID).foo(21,33), 3.2+1, '\\n', "+
"\"a,oo\\nick\", {bl, \"fdkj\"eck}";
String expected = "x, (_rID!=null?_rID.getText():null)+\"3242\"," +
" (*_tID).foo(21,33), 3.2+1, '\\n', \"a,oo\\nick\", {bl, \"fdkj\"eck}";
testActions(attributeTemplate, "inline", action, expected);
}
@Test public void testArguments() throws Exception {
String action = "$x; $a.x";
String expected = "_ctx.x; _ctx.x";
testActions(attributeTemplate, "inline", action, expected);
}
@Test public void testReturnValue() throws Exception {
String action = "$x; $a.x";
String expected = "_ctx.x; _ctx.x";
testActions(attributeTemplate, "inline", action, expected);
}
@Test public void testReturnValueWithNumber() throws Exception {
String action = "$a.x1";
String expected = "_ctx.x1";
testActions(attributeTemplate, "inline", action, expected);
}
@Test public void testReturnValuesCurrentRule() throws Exception {
String action = "$y; $a.y;";
String expected = "_ctx.y; _ctx.y;";
testActions(attributeTemplate, "inline", action, expected);
}
@Test public void testReturnValues() throws Exception {
String action = "$lab.e; $b.e;";
String expected = "lab.e; _rb.e;";
testActions(attributeTemplate, "inline", action, expected);
}
@Test public void testReturnWithMultipleRuleRefs() throws Exception {
String action1 = "$obj = $rule2.obj;";
String action2 = "$obj = $rule3.obj;";
String expecting1 = "obj = rule21;";
String expecting2 = "obj = rule32;";
String action = action1;
String action = "$c.x; $c.y;";
String expected = "_rc.x; _rc.y;";
testActions(attributeTemplate, "inline", action, expected);
}
@Test public void testInvalidReturnValues() throws Exception {
String action = "$x";
@Test public void testTokenRefs() throws Exception {
String action = "$id; $ID; $id.text; $id.getText(); $id.line;";
String expected = "id; _tID; (id!=null?id.getText():null); id.getText(); (id!=null?id.getLine():0);";
testActions(attributeTemplate, "inline", action, expected);
}
@Test public void testTokenLabels() throws Exception {
String action = "$id; $f; $id.text; $id.getText(); $id.dork " +
"$id.type; $id.line; $id.pos; " +
"$id.channel; $id.index;";
}
@Test public void testRuleLabels() throws Exception {
String action = "$r.x; $r.start;\n $r.stop;\n $r.tree; $a.x; $a.stop;";
}
@Test public void testAmbiguRuleRef() throws Exception {
}
@Test public void testRuleLabelsWithSpecialToken() throws Exception {
String action = "$r.x; $r.start; $r.stop; $r.tree; $a.x; $a.stop;";
}
@Test public void testForwardRefRuleLabels() throws Exception {
String action = "$r.x; $r.start; $r.stop; $r.tree; $a.x; $a.tree;";
}
@Test public void testInvalidRuleLabelAccessesParameter() throws Exception {
String action = "$r.z";
}
@Test public void testInvalidRuleLabelAccessesScopeAttribute() throws Exception {
String action = "$r.n";
}
@Test public void testInvalidRuleAttribute() throws Exception {
String action = "$r.blort";
}
@Test public void testMissingRuleAttribute() throws Exception {
String action = "$r";
}
@Test public void testMissingUnlabeledRuleAttribute() throws Exception {
String action = "$a";
}
@Test public void testNonDynamicAttributeOutsideRule() throws Exception {
String action = "public void foo() { $x; }";
}
@Test public void testNonDynamicAttributeOutsideRule2() throws Exception {
String action = "public void foo() { $x.y; }";
@Test public void testRuleRefs() throws Exception {
String action = "$lab.start; $c.tree;";
String expected = "(lab!=null?(()lab.start):null); (_rc!=null?(()_rc.tree):null);";
testActions(attributeTemplate, "inline", action, expected);
}
@Test public void testBasicGlobalScope() throws Exception {
String action = "$Symbols::names.add($id.text);";
}
@Test public void testUnknownGlobalScope() throws Exception {
String action = "$Symbols::names.add($id.text);";
}
@Test public void testIndexedGlobalScope() throws Exception {
String action = "$Symbols[-1]::names.add($id.text);";
String action = "$S::i";
String expected = "((S)S_stack.peek()).i";
testActions(scopeTemplate, "members", action, expected);
}
@Test public void test0IndexedGlobalScope() throws Exception {
String action = "$Symbols[0]::names.add($id.text);";
String action = "$S[0]::i";
String expected = "(S_stack.elementAt(0)).i";
testActions(scopeTemplate, "members", action, expected);
}
@Test public void testAbsoluteIndexedGlobalScope() throws Exception {
String action = "$Symbols[3]::names.add($id.text);";
}
@Test public void testScopeAndAttributeWithUnderscore() throws Exception {
String action = "$foo_bar::a_b;";
}
@Test public void testSharedGlobalScope() throws Exception {
String action = "$Symbols::x;";
}
@Test public void testGlobalScopeOutsideRule() throws Exception {
String action = "public void foo() {$Symbols::names.add('foo');}";
}
@Test public void testRuleScopeOutsideRule() throws Exception {
String action = "public void foo() {$a::name;}";
String action = "$S[3]::i";
String expected = "(S_stack.elementAt(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";
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";
testActions(scopeTemplate, "members", action, expected);
}
@Test public void testBasicRuleScope() throws Exception {
String action = "$a::n;";
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";
testActions(scopeTemplate, "inline", action, expected);
}
@Test public void testUnqualifiedRuleScopeAccessInsideRule() throws Exception {
String action = "$n;";
}
@ -250,14 +237,6 @@ public class TestActionTranslation extends BaseTest {
@Test public void testRuleLabelFromMultipleAlts() throws Exception {
String action = "$b.text;"; // must be qualified
}
@Test public void testUnknownDynamicAttribute() throws Exception {
String action = "$a::x";
}
@Test public void testUnknownGlobalDynamicAttribute() throws Exception {
String action = "$Symbols::x";
}
@Test public void testUnqualifiedRuleScopeAttribute() throws Exception {
String action = "$n;"; // must be qualified
}
@ -433,6 +412,29 @@ public class TestActionTranslation extends BaseTest {
String action = "int x = $b::n;";
}
@Test public void testBracketArgParsing() throws Exception {
}
@Test public void testStringArgParsing() throws Exception {
String action = "34, '{', \"it's<\", '\"', \"\\\"\", 19";
}
@Test public void testComplicatedSingleArgParsing() throws Exception {
String action = "(*a).foo(21,33,\",\")";
}
@Test public void testArgWithLT() throws Exception {
String action = "34<50";
}
@Test public void testGenericsAsArgumentDefinition() throws Exception {
String action = "$foo.get(\"ick\");";
}
@Test public void testGenericsAsArgumentDefinition2() throws Exception {
String action = "$foo.get(\"ick\"); x=3;";
}
@Test public void testGenericsAsReturnValue() throws Exception {
}
public void testActions(String template, String actionName, String action, String expected) {
ST st = new ST(template);
st.add(actionName, action);
@ -451,7 +453,7 @@ public class TestActionTranslation extends BaseTest {
CodeGenerator gen = new CodeGenerator(g);
ST outputFileST = gen.generate();
String output = outputFileST.render();
System.out.println(output);
//System.out.println(output);
String b = "#" + actionName + "#";
int start = output.indexOf(b);
String e = "#end-" + actionName + "#";

View File

@ -62,11 +62,12 @@ public class TestAttributeChecks extends BaseTest {
"$a.q", "error(31): A.g:4:10: unknown attribute q for rule a in $a.q\n",
};
String[] inlineChecks = {
String[] inlineChecks = {
"$text", "",
"$start", "",
"$x = $y", "",
"$y = $x", "",
"$a.x = $a.y", "",
"$lab.e", "",
"$lab.text", "",
"$b.e", "",
@ -76,24 +77,26 @@ public class TestAttributeChecks extends BaseTest {
"$id", "",
"$id.text", "",
"$ids", "",
};
String[] bad_inlineChecks = {
"$a", "error(33): A.g:6:4: missing attribute access on rule reference a in $a\n",
"$b", "error(33): A.g:6:4: missing attribute access on rule reference b in $b\n",
"$lab", "error(33): A.g:6:4: missing attribute access on rule reference lab in $lab\n",
"$c", "error(33): A.g:6:4: missing attribute access on rule reference c in $c\n", // no scope
"$q", "error(29): A.g:6:4: unknown attribute reference q in $q\n",
"$q.y", "error(29): A.g:6:4: unknown attribute reference q in $q.y\n",
"$q = 3", "error(29): A.g:6:4: unknown attribute reference q in $q\n",
"$q = 3;", "error(29): A.g:6:4: unknown attribute reference q in $q = 3;\n",
"$q.y = 3;", "error(29): A.g:6:4: unknown attribute reference q in $q.y = 3;\n",
"$q = $blort;", "error(29): A.g:6:4: unknown attribute reference q in $q = $blort;\n" +
"$q.y", "error(29): A.g:6:4: unknown attribute reference q in $q.y\n",
"$q = 3", "error(29): A.g:6:4: unknown attribute reference q in $q\n",
"$q = 3;", "error(29): A.g:6:4: unknown attribute reference q in $q = 3;\n",
"$q.y = 3;", "error(29): A.g:6:4: unknown attribute reference q in $q.y = 3;\n",
"$q = $blort;", "error(29): A.g:6:4: unknown attribute reference q in $q = $blort;\n" +
"error(29): A.g:6:9: unknown attribute reference blort in $blort\n",
"$a.ick", "error(31): A.g:6:6: unknown attribute ick for rule a in $a.ick\n",
"$a.ick = 3;", "error(31): A.g:6:6: unknown attribute ick for rule a in $a.ick = 3;\n",
"$b.d", "error(30): A.g:6:6: cannot access rule d's parameter: $b.d\n", // can't see rule ref's arg
"$a.ick", "error(31): A.g:6:6: unknown attribute ick for rule a in $a.ick\n",
"$a.ick = 3;", "error(31): A.g:6:6: unknown attribute ick for rule a in $a.ick = 3;\n",
"$b.d", "error(30): A.g:6:6: cannot access rule d's parameter: $b.d\n", // can't see rule ref's arg
"$d.text", "error(29): A.g:6:4: unknown attribute reference d in $d.text\n", // valid rule, but no ref
"$lab.d", "error(30): A.g:6:8: cannot access rule d's parameter: $lab.d\n",
};
};
String[] finallyChecks = {
"$text", "",
@ -213,6 +216,10 @@ public class TestAttributeChecks extends BaseTest {
testActions("inline", inlineChecks, attributeTemplate);
}
@Test public void testBadInlineActions() throws RecognitionException {
testActions("inline", bad_inlineChecks, attributeTemplate);
}
@Test public void testFinallyActions() throws RecognitionException {
testActions("finally", finallyChecks, attributeTemplate);
}
@ -242,6 +249,24 @@ public class TestAttributeChecks extends BaseTest {
testErrors(new String[] {grammar, expected}, false);
}
@Test public void testNonDynamicAttributeOutsideRule() throws Exception {
String action = "public void foo() { $x; }";
}
@Test public void testNonDynamicAttributeOutsideRule2() throws Exception {
String action = "public void foo() { $x.y; }";
}
@Test public void testUnknownGlobalScope() throws Exception {
String action = "$Symbols::names.add($id.text);";
}
@Test public void testUnknownDynamicAttribute() throws Exception {
String action = "$a::x";
}
@Test public void testUnknownGlobalDynamicAttribute() throws Exception {
String action = "$Symbols::x";
}
public void testActions(String location, String[] pairs, String template) {
for (int i = 0; i < pairs.length; i+=2) {
String action = pairs[i];