merged args/retvals into one object
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6867]
This commit is contained in:
parent
161dd26006
commit
5a1607e884
|
@ -16,6 +16,11 @@ public class QStack<T> {
|
|||
elements[++sp] = fset;
|
||||
}
|
||||
|
||||
public T peek() {
|
||||
if ( sp<0 ) throw new EmptyStackException();
|
||||
return (T)elements[sp];
|
||||
}
|
||||
|
||||
public T pop() {
|
||||
if ( sp<0 ) throw new EmptyStackException();
|
||||
return (T)elements[sp--];
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.antlr.runtime.*;
|
|||
|
||||
Parser(p, funcs) ::= <<
|
||||
public class <p.name> {
|
||||
public QStack _ctx;
|
||||
<funcs; separator="\n">
|
||||
<dfaDecls; separator="\n">
|
||||
<bitSetDecls; separator="\n">
|
||||
|
@ -33,20 +34,28 @@ public class <p.name> {
|
|||
S.b_return retval = new S.b_return();
|
||||
*/
|
||||
|
||||
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>
|
||||
RuleFunction(f,code,decls,context) ::= <<
|
||||
<context>
|
||||
|
||||
<if(f.isStartRule)>
|
||||
<if(f.modifiers)><f.modifiers:{f | <f> }><else>public final <endif><if(f.retType)><f.retType><else>void<endif> <f.name>(<f.args; separator=", ">) {
|
||||
<if(f.retType)>
|
||||
_ctx.push(new <f.context.name>(<f.args:{a|<a.name>}; separator=",">));
|
||||
_<f.name>(null);
|
||||
return _ctx.pop();
|
||||
<else>
|
||||
_<f.name>(null);
|
||||
<endif>
|
||||
}
|
||||
|
||||
<endif>
|
||||
<if(f.modifiers)><f.modifiers:{f | <f> }><else>public final <endif><if(f.retType)><f.retType><else>void<endif> <if(f.isStartRule)>_<endif><f.name>(BitSet _follow) {
|
||||
<! <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();
|
||||
}
|
||||
}
|
||||
>>
|
||||
|
@ -139,9 +148,9 @@ cases(ttypes) ::= <<
|
|||
>>
|
||||
|
||||
InvokeRule(r) ::= <<
|
||||
_follow.push(<r.follow.name>);
|
||||
<if(r.args)>_args.push(new );<endif>
|
||||
<if(r.label)><r.label> = <endif><r.name>();
|
||||
<if(r.ctxName)>_ctx.push(new <r.ctxName>(<r.argExprs; separator=",">));<endif>
|
||||
<if(r.label)><r.label> = <endif><r.name>(<r.follow.name>);
|
||||
<if(r.ctxName)>_ctx.pop();<endif>
|
||||
>>
|
||||
|
||||
MatchToken(m) ::= <<
|
||||
|
@ -162,18 +171,14 @@ TokenListDecl(t) ::= "List\<Token> <t.varName> = new ArrayList\<Token>();"
|
|||
|
||||
CaptureNextToken(d) ::= "<d.varName> = input.LA(1);"
|
||||
|
||||
ArgStruct(rv,attrs) ::= <<
|
||||
public static class <rv.name> {
|
||||
StructDecl(s,attrs) ::= <<
|
||||
public static class <s.name> extends ParserContextScope {
|
||||
<attrs:{a | <a>;}; separator="\n">
|
||||
public <rv.name>(<attrs; separator=", ">) {
|
||||
<rv.attrs:{a | this.<a.name> = <a.name>;}; separator="\n">
|
||||
<if(s.ctorAttrs)>
|
||||
public <s.name>(<s.ctorAttrs; separator=", ">) {
|
||||
<s.ctorAttrs:{a | this.<a.name> = <a.name>;}; separator="\n">
|
||||
}
|
||||
};
|
||||
>>
|
||||
|
||||
ReturnValueStruct(rv,attrs) ::= <<
|
||||
public static class <rv.name> extends ParserRuleReturnScope {
|
||||
<attrs:{a | <a>;}; separator="\n">
|
||||
<endif>
|
||||
};
|
||||
>>
|
||||
|
||||
|
|
|
@ -96,8 +96,7 @@ public abstract class OutputModelFactory {
|
|||
}
|
||||
|
||||
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 getRuleFunctionContextStructName(String ruleName) { return ruleName+"_ctx"; }
|
||||
public String getDynamicScopeStructName(String ruleName) { return ruleName+"_scope"; }
|
||||
|
||||
public BitSetDecl createFollowBitSet(GrammarAST ast, IntSet set) {
|
||||
|
|
|
@ -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,7 +98,7 @@ public class OutputModelWalker {
|
|||
tool.errMgr.toolError(ErrorType.CODE_TEMPLATE_ARG_ISSUE, templateName, fieldName);
|
||||
}
|
||||
}
|
||||
st.impl.dump();
|
||||
//st.impl.dump();
|
||||
return st;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
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());
|
||||
}
|
||||
}
|
|
@ -5,13 +5,15 @@ 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.Rule;
|
||||
|
||||
/** */
|
||||
public class InvokeRule extends SrcOp implements LabeledOp {
|
||||
public String name;
|
||||
public String label;
|
||||
public String args;
|
||||
public String argExprs;
|
||||
public BitSetDecl follow;
|
||||
public String ctxName;
|
||||
|
||||
public InvokeRule(OutputModelFactory factory, GrammarAST ast, GrammarAST labelAST) {
|
||||
this.factory = factory;
|
||||
|
@ -27,10 +29,14 @@ public class InvokeRule extends SrcOp implements LabeledOp {
|
|||
}
|
||||
}
|
||||
if ( ast.getChildCount()>0 ) {
|
||||
args = ast.getChild(0).getText();
|
||||
// split and translate argAction
|
||||
|
||||
argExprs = ast.getChild(0).getText();
|
||||
}
|
||||
|
||||
Rule r = factory.g.getRule(name);
|
||||
if ( r.retvals!=null || r.args!=null ) {
|
||||
ctxName = factory.getRuleFunctionContextStructName(r.name);
|
||||
}
|
||||
|
||||
// compute follow
|
||||
LinearApproximator approx = new LinearApproximator(factory.g, -1);
|
||||
IntervalSet fset = approx.LOOK(ast.nfaState.transition(0).target);
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
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());
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ 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;
|
||||
|
||||
|
@ -25,32 +26,42 @@ public class RuleFunction extends OutputModelObject {
|
|||
public List<String> elementsReferencedInRewrite;
|
||||
public List<String> exceptions;
|
||||
public String finallyAction;
|
||||
public boolean isStartRule;
|
||||
|
||||
public ArgStruct args;
|
||||
public DynamicScopeStruct scope;
|
||||
public ReturnValueStruct retvals;
|
||||
public StructDecl context;
|
||||
|
||||
public Collection<Attribute> args = null;
|
||||
public OrderedHashSet<Decl> decls;
|
||||
public SrcOp code;
|
||||
|
||||
public RuleFunction(OutputModelFactory factory, Rule r) {
|
||||
super(factory);
|
||||
this.name = r.name;
|
||||
this.isStartRule = r.isStartRule;
|
||||
if ( r.modifiers!=null && r.modifiers.size()>0 ) {
|
||||
this.modifiers = new ArrayList<String>();
|
||||
for (GrammarAST t : r.modifiers) modifiers.add(t.getText());
|
||||
}
|
||||
modifiers = Utils.nodesToStrings(r.modifiers);
|
||||
|
||||
List<Attribute> argsDynScopeAndReturnValues = new ArrayList<Attribute>();
|
||||
if ( r.args!=null ) {
|
||||
args = new ArgStruct(factory, r);
|
||||
this.args = r.args.attributes.values();
|
||||
argsDynScopeAndReturnValues.addAll(r.args.attributes.values());
|
||||
}
|
||||
if ( r.retvals!=null ) {
|
||||
retvals = new ReturnValueStruct(factory, r);
|
||||
retType = factory.getReturnStructName(r.name);
|
||||
retType = factory.getRuleFunctionContextStructName(r.name);
|
||||
argsDynScopeAndReturnValues.addAll(r.retvals.attributes.values());
|
||||
}
|
||||
if ( r.scope!=null ) {
|
||||
scope = new DynamicScopeStruct(factory, r);
|
||||
argsDynScopeAndReturnValues.addAll(r.scope.attributes.values());
|
||||
}
|
||||
if ( argsDynScopeAndReturnValues.size()>0 ) {
|
||||
context = new StructDecl(factory, factory.getRuleFunctionContextStructName(r.name),
|
||||
argsDynScopeAndReturnValues);
|
||||
context.ctorAttrs = args;
|
||||
}
|
||||
|
||||
ruleLabels = r.getLabelNames();
|
||||
tokenLabels = r.getTokenRefs();
|
||||
exceptions = Utils.nodesToStrings(r.exceptionActions);
|
||||
|
@ -80,8 +91,7 @@ public class RuleFunction extends OutputModelObject {
|
|||
final List<String> sup = super.getChildren();
|
||||
return new ArrayList<String>() {{
|
||||
if ( sup!=null ) addAll(sup);
|
||||
add("args"); add("retvals");
|
||||
add("scope"); add("decls"); add("code");
|
||||
add("context"); add("decls"); add("code");
|
||||
}};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.List;
|
|||
/** */
|
||||
public class StructDecl extends Decl {
|
||||
public List<Decl> attrs = new ArrayList<Decl>();
|
||||
public Collection<Attribute> ctorAttrs;
|
||||
|
||||
public StructDecl(OutputModelFactory factory, String name, Collection<Attribute> attrList) {
|
||||
super(factory, name);
|
||||
|
|
|
@ -75,6 +75,7 @@ public class SemanticPipeline {
|
|||
|
||||
// CHECK RULE REFS NOW (that we've defined rules in grammar)
|
||||
symcheck.checkRuleArgs(g, collector.rulerefs);
|
||||
identifyStartRules(collector);
|
||||
symcheck.checkForQualifiedRuleIssues(g, collector.qualifiedRulerefs);
|
||||
|
||||
// don't continue if we got symbol errors
|
||||
|
@ -91,6 +92,14 @@ public class SemanticPipeline {
|
|||
usedef.checkRewriteElementsPresentOnLeftSide(g, collector.rules);
|
||||
}
|
||||
|
||||
void identifyStartRules(CollectSymbols collector) {
|
||||
for (GrammarAST ref : collector.rulerefs) {
|
||||
String ruleName = ref.getText();
|
||||
Rule r = g.getRule(ruleName);
|
||||
if ( r!=null ) r.isStartRule = false;
|
||||
}
|
||||
}
|
||||
|
||||
void assignLexerTokenTypes(Grammar g, CollectSymbols collector) {
|
||||
Grammar G = g.getOutermostGrammar(); // put in root, even if imported
|
||||
for (GrammarAST def : collector.tokensDefs) {
|
||||
|
|
|
@ -72,6 +72,8 @@ public class Rule implements AttributeResolver {
|
|||
|
||||
public int numberOfAlts;
|
||||
|
||||
public boolean isStartRule = true; // nobody calls us
|
||||
|
||||
/** Labels are visible to all alts in a rule. Record all defs here.
|
||||
* We need to ensure labels are used to track same kind of symbols.
|
||||
* Tracks all label defs for a label.
|
||||
|
|
Loading…
Reference in New Issue