got rule scope going

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6866]
This commit is contained in:
parrt 2010-05-13 18:10:13 -08:00
parent 82b93e717d
commit 161dd26006
28 changed files with 327 additions and 94 deletions

View File

@ -0,0 +1,23 @@
package org.antlr.v4.runtime.misc;
import java.util.EmptyStackException;
/** A quicker stack than Stack */
public class QStack<T> {
Object[] elements;
int sp = -1;
public void push(T fset) {
if ( (sp+1)>=elements.length ) {
Object[] f = new Object[elements.length*2];
System.arraycopy(elements, 0, f, 0, elements.length);
elements = f;
}
elements[++sp] = fset;
}
public T pop() {
if ( sp<0 ) throw new EmptyStackException();
return (T)elements[sp--];
}
}

View File

@ -11,7 +11,7 @@ javaTypeInitMap ::= [
]
// args must be <object-model-object>, <fields-resulting-in-STs>
ParserFile(f, parser, dfaDefs, bitSetDefs) ::= <<
ParserFile(f, parser, dfaDecls, bitSetDecls) ::= <<
// $ANTLR ANTLRVersion> <f.fileName> generatedTimestamp>
import org.antlr.runtime.*;
@ -21,23 +21,33 @@ import org.antlr.runtime.*;
Parser(p, funcs) ::= <<
public class <p.name> {
<funcs; separator="\n">
<dfaDefs; separator="\n">
<bitSetDefs; separator="\n">
<dfaDecls; separator="\n">
<bitSetDecls; separator="\n">
}
>>
DFADef(dfa) ::= <<
// define <dfa.name>
>>
/*
// S.g:5:1: b returns [String q, float x] : A ;
public final S.b_return b() throws RecognitionException {
b_stack.push(new b_scope());
S.b_return retval = new S.b_return();
*/
BitSetDef(b) ::= <<
// define <b.name>
>>
RuleFunction(f,code,decls) ::= <<
<f.modifiers:{f | <f> }>void <f.name>(<f.args>) {
<decls>
<code>
RuleFunction(f,code,decls,args,retvals,scope) ::= <<
<args>
<retvals>
<scope>
<if(f.modifiers)><f.modifiers:{f | <f> }><else>public final <endif><if(f.retType)><f.retType><else>void<endif> <f.name>() {
<if(f.scope)><f.scope.name>.push(new <f.scope.name>);<endif>
<decls; separator="\n">
try {
<code>
}
finally {
<if(f.scope)><f.scope.name>.pop();<endif>
<if(f.args)>_args.pop();<endif>
_follow.pop();
}
}
>>
@ -129,9 +139,9 @@ cases(ttypes) ::= <<
>>
InvokeRule(r) ::= <<
pushFollow(<r.follow.name>);
_follow.push(<r.follow.name>);
<if(r.args)>_args.push(new );<endif>
<if(r.label)><r.label> = <endif><r.name>();
state._fsp--;
>>
MatchToken(m) ::= <<
@ -143,12 +153,47 @@ SemPred(p) ::= <<
if (!(<p.ast.text>)) throw new FailedPredicateException(input, "<ruleName>", "<description>");
>>
AddToList(a) ::= "<a.listName>.add(<a.opWithResultToAdd.label>);"
//Decl(d) ::= "<d.type> <d.varName> = <d.type:initValue()>;"
TokenDecl(t) ::= "Token <t.varName>;"
TokenListDecl(t) ::= "List\<Token> <t.varName> = new ArrayList\<Token>();"
CaptureNextToken(d) ::= "<d.varName> = input.LA(1);"
ArgStruct(rv,attrs) ::= <<
public static class <rv.name> {
<attrs:{a | <a>;}; separator="\n">
public <rv.name>(<attrs; separator=", ">) {
<rv.attrs:{a | this.<a.name> = <a.name>;}; separator="\n">
}
};
>>
ReturnValueStruct(rv,attrs) ::= <<
public static class <rv.name> extends ParserRuleReturnScope {
<attrs:{a | <a>;}; separator="\n">
};
>>
DynamicScopeStruct(rv,attrs) ::= <<
public static class <rv.name> {
<attrs:{a | <a>;}; separator="\n">
};
QStack b_stack = new QStack();
>>
AttributeDecl(d) ::= "<d.decl>"
DFADecl(dfa) ::= <<
// define <dfa.name>
>>
BitSetDecl(b) ::= <<
// define <b.name>
>>
/** Using a type to init value map, try to init a type; if not in table
* must be an object, default value is "null".
*/

View File

@ -407,6 +407,8 @@ public class Tool {
if ( generate_DFA_dot ) generateDFAs(g);
if ( g.tool.getNumErrors()>0 ) return;
// GENERATE CODE
CodeGenPipeline gen = new CodeGenPipeline(g);
gen.process();

View File

@ -68,7 +68,7 @@ public abstract class OutputModelFactory {
}
public abstract void defineBitSet(BitSetDef b);
public abstract void defineBitSet(BitSetDecl b);
public OutputModelObject getLL1Test(IntervalSet look, GrammarAST blkAST) {
OutputModelObject expr;
@ -81,7 +81,7 @@ public abstract class OutputModelFactory {
return expr;
}
public DFADef defineDFA(GrammarAST ast, DFA dfa) {
public DFADecl defineDFA(GrammarAST ast, DFA dfa) {
return null;
// DFADef d = new DFADef(name, dfa);
// outputModel.dfaDefs.add(d);
@ -95,21 +95,26 @@ public abstract class OutputModelFactory {
return "cnt"+ ast.token.getTokenIndex();
}
public BitSetDef createFollowBitSet(GrammarAST ast, IntSet set) {
public String getListLabel(String label) { return label+"_list"; }
public String getReturnStructName(String ruleName) { return ruleName+"_return"; }
public String getArgStructName(String ruleName) { return ruleName+"_args"; }
public String getDynamicScopeStructName(String ruleName) { return ruleName+"_scope"; }
public BitSetDecl createFollowBitSet(GrammarAST ast, IntSet set) {
String inRuleName = ast.nfaState.rule.name;
String elementName = ast.getText(); // assume rule ref
if ( ast.getType() == ANTLRParser.TOKEN_REF ) {
elementName = gen.target.getTokenTypeAsTargetLabel(g, g.tokenNameToTypeMap.get(elementName));
}
String name = "FOLLOW_"+elementName+"_in_"+inRuleName+"_"+ast.token.getTokenIndex();
BitSetDef b = new BitSetDef(this, name, set);
BitSetDecl b = new BitSetDecl(this, name, set);
return b;
}
public BitSetDef createTestBitSet(GrammarAST ast, IntSet set) {
public BitSetDecl createTestBitSet(GrammarAST ast, IntSet set) {
String inRuleName = ast.nfaState.rule.name;
String name = "LOOK_in_"+inRuleName+"_"+ast.token.getTokenIndex();
BitSetDef b = new BitSetDef(this, name, set);
BitSetDecl b = new BitSetDecl(this, name, set);
return b;
}
}

View File

@ -64,7 +64,7 @@ public class OutputModelWalker {
// COMPUTE STs FOR EACH NESTED MODEL OBJECT NAMED AS ARG BY TEMPLATE
if ( kids!=null ) for (String fieldName : kids) {
if ( !argNames.contains(fieldName) ) continue; // they won't use so don't compute
//System.out.println("computing ST for field "+fieldName+" of "+omo.getClass());
System.out.println("computing ST for field "+fieldName+" of "+omo.getClass());
try {
Field fi = omo.getClass().getField(fieldName);
Object o = fi.get(omo);
@ -98,6 +98,7 @@ public class OutputModelWalker {
tool.errMgr.toolError(ErrorType.CODE_TEMPLATE_ARG_ISSUE, templateName, fieldName);
}
}
st.impl.dump();
return st;
}

View File

@ -2,6 +2,7 @@ package org.antlr.v4.codegen;
import org.antlr.v4.codegen.src.*;
import org.antlr.v4.misc.Utils;
import org.antlr.v4.parse.ANTLRParser;
import org.antlr.v4.tool.GrammarAST;
import org.antlr.v4.tool.TerminalAST;
@ -30,12 +31,21 @@ public class ParserFactory extends OutputModelFactory {
@Override
public List<SrcOp> ruleRef(GrammarAST ID, GrammarAST label, GrammarAST args) {
InvokeRule r = new InvokeRule(this, ID, label);
return Utils.list(r);
AddToList a = null;
if ( label!=null && label.parent.getType()== ANTLRParser.PLUS_ASSIGN ) {
a = new AddToList(this, getListLabel(r.label), r);
}
return Utils.list(r, a);
}
@Override
public List<SrcOp> tokenRef(GrammarAST ID, GrammarAST label, GrammarAST args) {
return Utils.list(new MatchToken(this, (TerminalAST)ID, label));
MatchToken m = new MatchToken(this, (TerminalAST) ID, label);
AddToList a = null;
if ( label!=null && label.parent.getType()== ANTLRParser.PLUS_ASSIGN ) {
a = new AddToList(this, getListLabel(m.label), m);
}
return Utils.list(m, a);
}
@Override
@ -43,5 +53,5 @@ public class ParserFactory extends OutputModelFactory {
return tokenRef(ID, label, null);
}
public void defineBitSet(BitSetDef b) { ((ParserFile)file).defineBitSet(b); }
public void defineBitSet(BitSetDecl b) { ((ParserFile)file).defineBitSet(b); }
}

View File

@ -1,6 +1,15 @@
package org.antlr.v4.codegen.src;
import org.antlr.v4.codegen.OutputModelFactory;
/** */
public class AddToList extends SrcOp {
public SrcOp opWithResultToAdd;
public String listName;
public LabeledOp opWithResultToAdd;
public AddToList(OutputModelFactory factory, String listName, LabeledOp opWithResultToAdd) {
super(factory);
this.listName = listName;
this.opWithResultToAdd = opWithResultToAdd;
}
}

View File

@ -0,0 +1,11 @@
package org.antlr.v4.codegen.src;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.tool.Rule;
/** */
public class ArgStruct extends StructDecl {
public ArgStruct(OutputModelFactory factory, Rule r) {
super(factory, factory.getArgStructName(r.name), r.args.attributes.values());
}
}

View File

@ -0,0 +1,10 @@
package org.antlr.v4.codegen.src;
import org.antlr.v4.codegen.OutputModelFactory;
/** */
public class AttributeDecl extends Decl {
public AttributeDecl(OutputModelFactory factory, String name, String decl) {
super(factory, name, decl);
}
}

View File

@ -0,0 +1,13 @@
package org.antlr.v4.codegen.src;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.misc.IntSet;
/** */
public class BitSetDecl extends Decl {
public IntSet fset;
public BitSetDecl(OutputModelFactory factory, String name, IntSet fset) {
super(factory, name);
this.fset = fset;
}
}

View File

@ -1,15 +0,0 @@
package org.antlr.v4.codegen.src;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.misc.IntSet;
/** */
public class BitSetDef extends OutputModelObject {
public String name;
public IntSet fset;
public BitSetDef(OutputModelFactory factory, String name, IntSet fset) {
this.factory = factory;
this.name = name;
this.fset = fset;
}
}

View File

@ -0,0 +1,14 @@
package org.antlr.v4.codegen.src;
import org.antlr.v4.automata.DFA;
import org.antlr.v4.codegen.OutputModelFactory;
/** */
public class DFADecl extends Decl {
public DFA dfa;
public DFADecl(OutputModelFactory factory, String name, DFA dfa) {
super(factory, name);
this.dfa = dfa;
}
}

View File

@ -1,14 +0,0 @@
package org.antlr.v4.codegen.src;
import org.antlr.v4.automata.DFA;
/** */
public class DFADef extends OutputModelObject {
public String name;
public DFA dfa;
public DFADef(String name, DFA dfa) {
this.dfa = dfa;
this.name = name;
}
}

View File

@ -1,18 +1,29 @@
package org.antlr.v4.codegen.src;
import org.antlr.v4.codegen.OutputModelFactory;
/** */
public class Decl extends SrcOp {
public String varName;
public String type;
public Decl(String varName, String type) { this.varName = varName; this.type = type; }
public String name;
public String decl;
public Decl(OutputModelFactory factory, String name, String decl) {
this(factory, name);
this.decl = decl;
}
public Decl(OutputModelFactory factory, String name) {
super(factory);
this.name = name;
}
@Override
public int hashCode() {
return varName.hashCode();
return name.hashCode();
}
@Override
public boolean equals(Object obj) {
return varName.equals(((Decl)obj).varName);
return name.equals(((Decl)obj).name);
}
}

View File

@ -0,0 +1,11 @@
package org.antlr.v4.codegen.src;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.tool.Rule;
/** */
public class DynamicScopeStruct extends StructDecl {
public DynamicScopeStruct(OutputModelFactory factory, Rule r) {
super(factory, factory.getDynamicScopeStructName(r.name), r.scope.attributes.values());
}
}

View File

@ -3,25 +3,33 @@ package org.antlr.v4.codegen.src;
import org.antlr.v4.analysis.LinearApproximator;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.misc.IntervalSet;
import org.antlr.v4.parse.ANTLRParser;
import org.antlr.v4.tool.GrammarAST;
import java.util.List;
/** */
public class InvokeRule extends SrcOp {
public class InvokeRule extends SrcOp implements LabeledOp {
public String name;
public String label;
public List<String> args;
public BitSetDef follow;
public String args;
public BitSetDecl follow;
public InvokeRule(OutputModelFactory factory, GrammarAST ast, GrammarAST labelAST) {
this.factory = factory;
this.ast = ast;
this.name = ast.getText();
if ( labelAST!=null ) this.label = labelAST.getText();
if ( labelAST!=null ) {
label = labelAST.getText();
// TokenDecl d = new TokenDecl(label);
// factory.currentRule.peek().addDecl(d);
if ( labelAST.parent.getType() == ANTLRParser.PLUS_ASSIGN ) {
// TokenListDecl l = new TokenListDecl(factory.getListLabel(label));
// factory.currentRule.peek().addDecl(l);
}
}
if ( ast.getChildCount()>0 ) {
String argAction = ast.getChild(0).getText();
args = ast.getChild(0).getText();
// split and translate argAction
}
// compute follow
LinearApproximator approx = new LinearApproximator(factory.g, -1);
@ -30,4 +38,8 @@ public class InvokeRule extends SrcOp {
follow = factory.createFollowBitSet(ast, fset);
factory.defineBitSet(follow);
}
public String getLabel() {
return label;
}
}

View File

@ -25,7 +25,7 @@ public abstract class LL1Loop extends LL1Choice {
expr = factory.getLL1Test(look, ast);
if ( expr instanceof TestSetInline ) {
TestSetInline e = (TestSetInline) expr;
Decl d = new TokenDecl(e.varName);
Decl d = new TokenDecl(factory, e.varName);
factory.currentRule.peek().addDecl(d);
CaptureNextToken nextToken = new CaptureNextToken(e.varName);
addPreambleOp(nextToken);

View File

@ -7,9 +7,9 @@ import java.util.List;
/** */
public class LLStarOptionalBlock extends OptionalBlock {
public DFADef dfaDef;
public DFADecl dfaDecl;
public LLStarOptionalBlock(OutputModelFactory factory, BlockAST blkAST, List<CodeBlock> alts) {
super(factory, blkAST, alts);
dfaDef = factory.defineDFA(ast, factory.g.decisionDFAs.get(decision));
dfaDecl = factory.defineDFA(ast, factory.g.decisionDFAs.get(decision));
}
}

View File

@ -0,0 +1,6 @@
package org.antlr.v4.codegen.src;
/** */
public interface LabeledOp {
public String getLabel();
}

View File

@ -3,19 +3,28 @@ package org.antlr.v4.codegen.src;
import org.antlr.v4.analysis.LinearApproximator;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.misc.IntervalSet;
import org.antlr.v4.parse.ANTLRParser;
import org.antlr.v4.tool.GrammarAST;
import org.antlr.v4.tool.TerminalAST;
/** */
public class MatchToken extends SrcOp {
public class MatchToken extends SrcOp implements LabeledOp {
public String name;
public BitSetDef follow;
public BitSetDecl follow;
public String label;
public MatchToken(OutputModelFactory factory, TerminalAST ast, GrammarAST labelAST) {
this.factory = factory;
name = ast.getText();
if ( labelAST!=null ) this.label = labelAST.getText();
if ( labelAST!=null ) {
label = labelAST.getText();
TokenDecl d = new TokenDecl(factory, label);
factory.currentRule.peek().addDecl(d);
if ( labelAST.parent.getType() == ANTLRParser.PLUS_ASSIGN ) {
TokenListDecl l = new TokenListDecl(factory, factory.getListLabel(label));
factory.currentRule.peek().addDecl(l);
}
}
LinearApproximator approx = new LinearApproximator(factory.g, -1);
IntervalSet fset = approx.LOOK(ast.nfaState.transition(0).target);
@ -23,4 +32,8 @@ public class MatchToken extends SrcOp {
follow = factory.createFollowBitSet(ast, fset);
factory.defineBitSet(follow);
}
public String getLabel() {
return label;
}
}

View File

@ -9,8 +9,8 @@ import java.util.List;
public class ParserFile extends OutputModelObject {
public String fileName;
public Parser parser;
public List<DFADef> dfaDefs = new ArrayList<DFADef>();
public List<BitSetDef> bitSetDefs = new ArrayList<BitSetDef>();
public List<DFADecl> dfaDecls = new ArrayList<DFADecl>();
public List<BitSetDecl> bitSetDecls = new ArrayList<BitSetDecl>();
public ParserFile(OutputModelFactory factory, String fileName) {
super(factory);
@ -19,8 +19,8 @@ public class ParserFile extends OutputModelObject {
parser = new Parser(factory, this);
}
public void defineBitSet(BitSetDef b) {
bitSetDefs.add(b);
public void defineBitSet(BitSetDecl b) {
bitSetDecls.add(b);
}
@Override
@ -29,8 +29,8 @@ public class ParserFile extends OutputModelObject {
return new ArrayList<String>() {{
if ( sup!=null ) addAll(sup);
add("parser");
add("dfaDefs");
add("bitSetDefs");
add("dfaDecls");
add("bitSetDecls");
}};
}
}

View File

@ -0,0 +1,11 @@
package org.antlr.v4.codegen.src;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.tool.Rule;
/** */
public class ReturnValueStruct extends StructDecl {
public ReturnValueStruct(OutputModelFactory factory, Rule r) {
super(factory, factory.getReturnStructName(r.name), r.retvals.attributes.values());
}
}

View File

@ -7,7 +7,6 @@ import org.antlr.v4.misc.OrderedHashSet;
import org.antlr.v4.misc.Utils;
import org.antlr.v4.parse.ANTLRParser;
import org.antlr.v4.parse.GrammarASTAdaptor;
import org.antlr.v4.tool.Attribute;
import org.antlr.v4.tool.GrammarAST;
import org.antlr.v4.tool.Rule;
@ -19,9 +18,7 @@ import java.util.List;
public class RuleFunction extends OutputModelObject {
public String name;
public List<String> modifiers;
public Collection<Attribute> args;
public Collection<Attribute> retvals;
public Collection<Attribute> ruleScopeDecls;
public String retType;
public List<String> globalScopesUsed;
public Collection<String> ruleLabels;
public Collection<String> tokenLabels;
@ -29,7 +26,10 @@ public class RuleFunction extends OutputModelObject {
public List<String> exceptions;
public String finallyAction;
public OrderedHashSet<SrcOp> decls;
public ArgStruct args;
public DynamicScopeStruct scope;
public ReturnValueStruct retvals;
public OrderedHashSet<Decl> decls;
public SrcOp code;
public RuleFunction(OutputModelFactory factory, Rule r) {
@ -41,9 +41,16 @@ public class RuleFunction extends OutputModelObject {
}
modifiers = Utils.nodesToStrings(r.modifiers);
if ( r.args!=null ) args = r.args.attributes.values();
if ( r.retvals!=null ) retvals = r.retvals.attributes.values();
if ( r.scope!=null ) ruleScopeDecls = r.scope.attributes.values();
if ( r.args!=null ) {
args = new ArgStruct(factory, r);
}
if ( r.retvals!=null ) {
retvals = new ReturnValueStruct(factory, r);
retType = factory.getReturnStructName(r.name);
}
if ( r.scope!=null ) {
scope = new DynamicScopeStruct(factory, r);
}
ruleLabels = r.getLabelNames();
tokenLabels = r.getTokenRefs();
exceptions = Utils.nodesToStrings(r.exceptionActions);
@ -64,7 +71,7 @@ public class RuleFunction extends OutputModelObject {
}
public void addDecl(Decl d) {
if ( decls==null ) decls = new OrderedHashSet<SrcOp>();
if ( decls==null ) decls = new OrderedHashSet<Decl>();
decls.add(d);
}
@ -72,7 +79,9 @@ public class RuleFunction extends OutputModelObject {
public List<String> getChildren() {
final List<String> sup = super.getChildren();
return new ArrayList<String>() {{
if ( sup!=null ) addAll(sup); add("decls"); add("code");
if ( sup!=null ) addAll(sup);
add("args"); add("retvals");
add("scope"); add("decls"); add("code");
}};
}
}

View File

@ -0,0 +1,28 @@
package org.antlr.v4.codegen.src;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.tool.Attribute;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/** */
public class StructDecl extends Decl {
public List<Decl> attrs = new ArrayList<Decl>();
public StructDecl(OutputModelFactory factory, String name, Collection<Attribute> attrList) {
super(factory, name);
for (Attribute a : attrList) {
attrs.add(new AttributeDecl(factory, a.name, a.decl));
}
}
@Override
public List<String> getChildren() {
final List<String> sup = super.getChildren();
return new ArrayList<String>() {{
if ( sup!=null ) addAll(sup); add("attrs");
}};
}
}

View File

@ -6,7 +6,7 @@ import org.antlr.v4.tool.GrammarAST;
/** */
public class TestSet extends OutputModelObject {
public BitSetDef set;
public BitSetDecl set;
public TestSet(OutputModelFactory factory, GrammarAST blkAST, IntervalSet set) {
this.set = factory.createTestBitSet(blkAST, set);
factory.defineBitSet(this.set);

View File

@ -1,8 +1,10 @@
package org.antlr.v4.codegen.src;
import org.antlr.v4.codegen.OutputModelFactory;
/** */
public class TokenDecl extends Decl {
public TokenDecl(String varName) {
super(varName,null);
public TokenDecl(OutputModelFactory factory, String varName) {
super(factory, varName);
}
}

View File

@ -0,0 +1,10 @@
package org.antlr.v4.codegen.src;
import org.antlr.v4.codegen.OutputModelFactory;
/** */
public class TokenListDecl extends Decl {
public TokenListDecl(OutputModelFactory factory, String varName) {
super(factory, varName);
}
}

View File

@ -2,6 +2,7 @@ package org.antlr.v4.misc;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
/** A HashMap that remembers the order that the elements were added.
@ -49,7 +50,12 @@ public class OrderedHashSet<T> extends HashSet<T> {
super.clear();
}
/** Return the List holding list of table elements. Note that you are
@Override
public Iterator<T> iterator() {
return elements.iterator();
}
/** Return the List holding list of table elements. Note that you are
* NOT getting a copy so don't write to the list.
*/
public List<T> elements() {