not tested but put locals into attr lookup for rule and code gen chunks + java.stg

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 8917]
This commit is contained in:
parrt 2011-07-28 10:29:12 -08:00
parent 10d7a79324
commit 0cb91817d9
17 changed files with 225 additions and 133 deletions

View File

@ -360,6 +360,7 @@ if (!(<chunks>)) throw new FailedPredicateException(this, input, "<currentRule.n
ActionText(t) ::= "<t.text>"
ArgRef(a) ::= "_localctx.<a.name>"
LocalRef(a) ::= "_localctx.<a.name>"
RetValueRef(a) ::= "_localctx.<a.name>"
QRetValueRef(a) ::= "_localctx.<a.dict>.<a.name>"
/** How to translate $tokenLabel */
@ -391,6 +392,11 @@ 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>"
SetNonLocalAttr(s, rhsChunks) ::=
"<s.scope>.peek().<s.attr> =<rhsChunks>;"
AddToLabelList(a) ::= "_localctx.<a.listName>.add(<labelref(a.label)>);"
TokenDecl(t) ::= "Token <t.name>;"

View File

@ -225,8 +225,8 @@ public class Tool {
GrammarTransformPipeline.integrateImportedGrammars(g);
GrammarTransformPipeline transform = new GrammarTransformPipeline(this);
transform.process(g.ast);
GrammarTransformPipeline transform = new GrammarTransformPipeline(g, this);
transform.process();
LexerGrammar lexerg = null;
GrammarRootAST lexerAST = null;

View File

@ -116,7 +116,7 @@ public class ActionTranslator implements ActionSplitterListener {
Token tokenWithinAction = node.token;
ActionTranslator translator = new ActionTranslator(factory, node);
translator.rf = rf;
System.out.println("translate "+action);
System.out.println("translate " + action);
ANTLRStringStream in = new ANTLRStringStream(action);
in.setLine(tokenWithinAction.getLine());
in.setCharPositionInLine(tokenWithinAction.getCharPositionInLine());
@ -133,6 +133,7 @@ public class ActionTranslator implements ActionSplitterListener {
switch ( a.dict.type ) {
case ARG: chunks.add(new ArgRef(x.getText())); break;
case RET: chunks.add(new RetValueRef(x.getText())); break;
case LOCAL: chunks.add(new LocalRef(x.getText())); break;
case PREDEFINED_RULE: chunks.add(getRulePropertyRef(x)); break;
// case PREDEFINED_TREE_RULE: chunks.add(new RetValueRef(x.getText())); break;
}
@ -203,6 +204,18 @@ public class ActionTranslator implements ActionSplitterListener {
chunks.add(s);
}
public void nonLocalAttr(String expr, Token x, Token y) {
System.out.println("nonLocalAttr "+x+"."+y);
chunks.add(new NonLocalAttrRef(x.getText(), y.getText()));
}
public void setNonLocalAttr(String expr, Token x, Token y, Token rhs) {
System.out.println("setNonLocalAttr "+x+"::"+y+"="+rhs);
List<ActionChunk> rhsChunks = translateActionChunk(factory,rf,rhs.getText(),node);
SetNonLocalAttr s = new SetNonLocalAttr(x.getText(), y.getText(), rhsChunks);
chunks.add(s);
}
public void templateInstance(String expr) {
}

View File

@ -30,10 +30,8 @@
package org.antlr.v4.codegen.model.actions;
/** */
public class ArgRef extends ActionChunk {
public String name;
public class ArgRef extends LocalRef {
public ArgRef(String name) {
this.name = name;
super(name);
}
}

View File

@ -0,0 +1,38 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.codegen.model.actions;
public class LocalRef extends ActionChunk {
public String name;
public LocalRef(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,40 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.codegen.model.actions;
public class NonLocalAttrRef extends ActionChunk {
public String context;
public String name;
public NonLocalAttrRef(String context, String name) {
this.context = context;
this.name = name;
}
}

View File

@ -0,0 +1,40 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
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) {
super(name, rhsChunks);
this.context = context;
}
}

View File

@ -42,6 +42,15 @@ LINE_COMMENT
: '//' ~('\n'|'\r')* '\r'? '\n' {delegate.text($text);}
;
SET_DYNAMIC_SCOPE_ATTR
: '$' x=ID '::' y=ID WS? '=' expr=ATTR_VALUE_EXPR ';'
{delegate.setNonLocalAttr($text, $x, $y, $expr);}
;
DYNAMIC_SCOPE_ATTR
: '$' x=ID '::' y=ID {delegate.nonLocalAttr($text, $x, $y);}
;
SET_QUALIFIED_ATTR
: '$' x=ID '.' y=ID WS? '=' expr=ATTR_VALUE_EXPR ';'
{delegate.setQualifiedAttr($text, $x, $y, $expr);}

View File

@ -35,8 +35,11 @@ import org.antlr.runtime.Token;
public interface ActionSplitterListener {
void setQualifiedAttr(String expr, Token x, Token y, Token rhs);
void qualifiedAttr(String expr, Token x, Token y);
void setAttr(String expr, Token x, Token rhs);
void attr(String expr, Token x);
void setAttr(String expr, Token x, Token rhs);
void attr(String expr, Token x);
void setNonLocalAttr(String expr, Token x, Token y, Token rhs);
void nonLocalAttr(String expr, Token x, Token y);
void templateInstance(String expr);
void indirectTemplateInstance(String expr);

View File

@ -148,27 +148,53 @@ public class AttributeChecks implements ActionSplitterListener {
}
if ( isolatedRuleRef(x.getText())!=null ) {
errMgr.grammarError(ErrorType.ISOLATED_RULE_REF,
g.fileName, x, x.getText(), expr);
g.fileName, x, x.getText(), expr);
return;
}
errMgr.grammarError(ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE,
g.fileName, x, x.getText(), expr);
g.fileName, x, x.getText(), expr);
}
}
}
public void unknownSyntax(Token t) {
public void nonLocalAttr(String expr, Token x, Token y) {
Rule r = g.getRule(x.getText());
if ( r==null ) {
errMgr.toolError(ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF,
x.getText(), y.getText());
}
if ( r.resolveToAttribute(y.getText(), null)==null ) {
errMgr.grammarError(ErrorType.UNKNOWN_RULE_ATTRIBUTE,
g.fileName, y, y.getText(), x.getText(), expr);
}
}
public void setNonLocalAttr(String expr, Token x, Token y, Token rhs) {
Rule r = g.getRule(x.getText());
if ( r==null ) {
errMgr.toolError(ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF,
x.getText(), y.getText());
}
if ( r.resolveToAttribute(y.getText(), null)==null ) {
errMgr.grammarError(ErrorType.UNKNOWN_RULE_ATTRIBUTE,
g.fileName, y, y.getText(), x.getText(), expr);
}
}
public void unknownSyntax(Token t) {
errMgr.grammarError(ErrorType.INVALID_TEMPLATE_ACTION,
g.fileName, t, t.getText());
}
g.fileName, t, t.getText());
}
public void text(String text) { }
public void text(String text) { }
// don't care
public void templateInstance(String expr) { }
public void indirectTemplateInstance(String expr) { }
public void setExprAttribute(String expr) { }
public void setSTAttribute(String expr) { }
public void templateExpr(String expr) { }
// don't care
public void templateInstance(String expr) { }
public void indirectTemplateInstance(String expr) { }
public void setExprAttribute(String expr) { }
public void setSTAttribute(String expr) { }
public void templateExpr(String expr) { }
// SUPPORT

View File

@ -48,6 +48,11 @@ public class BlankActionSplitterListener implements ActionSplitterListener {
public void templateInstance(String expr) {
}
public void nonLocalAttr(String expr, Token x, Token y) {
}
public void setNonLocalAttr(String expr, Token x, Token y, Token rhs) {
}
public void indirectTemplateInstance(String expr) {
}

View File

@ -59,10 +59,8 @@ public class AttributeDict {
}};
public static enum DictType {
ARG, RET, TOKEN,
ARG, RET, LOCAL, TOKEN,
PREDEFINED_RULE, PREDEFINED_TREE_RULE, PREDEFINED_LEXER_RULE,
GLOBAL_SCOPE, // scope symbols { ...}
RULE_SCOPE; // scope { int i; int j; }
}
/** The list of Attribute objects */

View File

@ -74,6 +74,7 @@ public enum ErrorType {
REPEATED_PREQUEL("repeated grammar prequel spec (option, token, or import); please merge", ErrorSeverity.ERROR),
NO_TOKEN_DEFINITION("no lexer rule corresponding to token: <arg>", ErrorSeverity.ERROR),
UNDEFINED_RULE_REF("reference to undefined rule: <arg>", ErrorSeverity.ERROR),
UNDEFINED_RULE_IN_NONLOCAL_REF("reference to undefined rule in nonlocal ref: <arg>::<arg2>", ErrorSeverity.ERROR),
LITERAL_NOT_ASSOCIATED_WITH_LEXER_RULE("", ErrorSeverity.ERROR),
CANNOT_ALIAS_TOKENS("can't assign string value to token name <arg> in non-combined grammar", ErrorSeverity.ERROR),
TOKEN_NAMES_MUST_START_UPPER("token names must start with an uppercase letter: <arg>", ErrorSeverity.ERROR),

View File

@ -39,13 +39,16 @@ import java.util.*;
/** Handle left-recursion and block-set transforms */
public class GrammarTransformPipeline {
public Grammar g;
public Tool tool;
public GrammarTransformPipeline(Tool tool) {
public GrammarTransformPipeline(Grammar g, Tool tool) {
this.g = g;
this.tool = tool;
}
public void process(GrammarRootAST ast) {
public void process() {
GrammarRootAST ast = g.ast;
if ( ast==null ) return;
System.out.println("before: "+ast.toStringTree());
@ -61,7 +64,7 @@ public class GrammarTransformPipeline {
org.antlr.runtime.tree.CommonTreeNodeStream nodes =
new org.antlr.runtime.tree.CommonTreeNodeStream(ast);
GrammarASTAdaptor adaptor = new GrammarASTAdaptor();
BlockSetTransformer transformer = new BlockSetTransformer(nodes);
BlockSetTransformer transformer = new BlockSetTransformer(nodes, g);
transformer.setTreeAdaptor(adaptor);
transformer.downup(ast);
}

View File

@ -74,6 +74,7 @@ public class Rule implements AttributeResolver {
public RuleAST ast;
public AttributeDict args;
public AttributeDict retvals;
public AttributeDict locals;
public AttributeDict scope; // scope { int i; } // TODO: remove
/** In which grammar does this rule live? */
@ -195,6 +196,9 @@ public class Rule implements AttributeResolver {
if ( retvals!=null ) {
Attribute a = retvals.get(x); if ( a!=null ) return a;
}
if ( locals!=null ) {
Attribute a = locals.get(x); if ( a!=null ) return a;
}
AttributeDict properties = getPredefinedScope(LabelType.RULE_LABEL);
return properties.get(x);
}

View File

@ -9,23 +9,20 @@ import java.util.*;
public class TestActionSplitter extends BaseTest {
static String[] exprs = {
"foo", "['foo'<26>]",
"foo", "['foo'<22>]",
"$x", "['$x'<6>]",
"\\$x", "['\\$x'<26>]",
"$x.y", "['$x.y'<15>]",
"$ID.text", "['$ID.text'<15>]",
"\\$x", "['\\$x'<22>]",
"$x.y", "['$x.y'<13>]",
"$ID.text", "['$ID.text'<13>]",
"$ID", "['$ID'<6>]",
"$ID.getText()", "['$ID'<6>, '.getText()'<26>]",
"$ID.text = \"test\";", "['$ID.text = \"test\";'<23>]",
"$a.line == $b.line", "['$a.line'<15>, ' == '<26>, '$b.line'<15>]",
"$r.tree", "['$r.tree'<15>]",
"foo $a::n bar", "['foo '<26>, '$a::n'<11>, ' bar'<26>]",
"$Symbols[-1]::names.add($id.text);", "['$Symbols[-1]::names'<10>, '.add('<26>, '$id.text'<15>, ');'<26>]",
"$Symbols[0]::names.add($id.text);", "['$Symbols[0]::names'<9>, '.add('<26>, '$id.text'<15>, ');'<26>]",
"$Symbols::x;", "['$Symbols::x'<11>, ';'<26>]",
"$Symbols.size()>0", "['$Symbols'<6>, '.size()>0'<26>]",
"$field::x = $field.st;", "['$field::x = $field.st;'<21>]",
"$foo.get(\"ick\");", "['$foo'<6>, '.get(\"ick\");'<26>]",
"$ID.getText()", "['$ID'<6>, '.getText()'<22>]",
"$ID.text = \"test\";", "['$ID.text = \"test\";'<19>]",
"$a.line == $b.line", "['$a.line'<13>, ' == '<22>, '$b.line'<13>]",
"$r.tree", "['$r.tree'<13>]",
"foo $a::n bar", "['foo '<22>, '$a::n'<9>, ' bar'<22>]",
"$rule::x;", "['$rule::x'<9>, ';'<22>]",
"$field::x = $field.st;", "['$field::x = $field.st;'<17>]",
"$foo.get(\"ick\");", "['$foo'<6>, '.get(\"ick\");'<22>]",
};
@Test public void testExprs() {

View File

@ -145,96 +145,6 @@ public class TestActionTranslation extends BaseTest {
testActions(attributeTemplate, "inline", action, expected);
}
@Test public void testBasicGlobalScope() throws Exception {
String action = "$S::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.get(0).i";
testActions(scopeTemplate, "members", action, expected);
}
@Test public void testAbsoluteIndexedGlobalScope() throws Exception {
String action = "$S[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.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.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";
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 testRefToTextAttributeForCurrentRule() throws Exception {
String action = "$a.text; $text";
String expected =
@ -491,6 +401,7 @@ public class TestActionTranslation extends BaseTest {
@Test public void testGenericsAsReturnValue() throws Exception {
}
// TODO: nonlocal $rule::x
public void testActions(String templates, String actionName, String action, String expected) {