got simple LL1 (..) and (..)? in; added Decl concept
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6851]
This commit is contained in:
parent
3e1f43117e
commit
883a00a4b0
|
@ -32,16 +32,54 @@ CodeBlock(c, ops) ::= <<
|
||||||
<ops; separator="\n">
|
<ops; separator="\n">
|
||||||
>>
|
>>
|
||||||
|
|
||||||
LL1Choice(c, alts) ::= <<
|
LL1Choice(choice, alts) ::= <<
|
||||||
switch ( input.LA(1) ) {
|
switch ( input.LA(1) ) {
|
||||||
<alts; separator="\n">
|
<choice.altLook,alts:{look,alt| <look:cases()><alt>}; separator="\n">
|
||||||
|
default :
|
||||||
|
error
|
||||||
}
|
}
|
||||||
>>
|
>>
|
||||||
|
|
||||||
MatchToken(m) ::= <<
|
LL1OptionalBlock(choice, expr, alts) ::= <<
|
||||||
match(<m.name>, <m.follow.name>);
|
switch ( <expr> ) {
|
||||||
|
<choice.altLook,alts:{look,alt| <look:cases()><alt>}; separator="\n">
|
||||||
|
}
|
||||||
>>
|
>>
|
||||||
|
|
||||||
|
LL1OptionalBlockSingleAlt(choice, expr, alts, decls) ::= <<
|
||||||
|
<decls>
|
||||||
|
if ( <expr> ) {
|
||||||
|
<alts; separator="\n">
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
NoViableAltException nvae = new NoViableAltException("", 4, 0, input);
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
TestSet(s) ::= <<
|
||||||
|
<s.set.name>.member(input.LA(1))
|
||||||
|
>>
|
||||||
|
|
||||||
|
TestSetInline(s) ::= <<
|
||||||
|
<s.ttypes:{ttype | <first(choice.decls).varName>==<ttype>}; separator=" || ">
|
||||||
|
>>
|
||||||
|
|
||||||
|
cases(look) ::= <<
|
||||||
|
<look:{case <it>:<\n>}>
|
||||||
|
>>
|
||||||
|
|
||||||
|
InvokeRule(r) ::= <<
|
||||||
|
pushFollow(<r.follow.name>);
|
||||||
|
<if(r.label)><r.label> = <endif><r.name>();
|
||||||
|
state._fsp--;
|
||||||
|
>>
|
||||||
|
|
||||||
|
MatchToken(m) ::= <<
|
||||||
|
<if(m.label)><m.label> = <endif>match(<m.name>, <m.follow.name>);
|
||||||
|
>>
|
||||||
|
|
||||||
|
NextTokenDecl(d) ::= "Token <d.varName> = input.LA(1);"
|
||||||
|
|
||||||
codeFileExtension() ::= ".java"
|
codeFileExtension() ::= ".java"
|
||||||
|
|
||||||
true() ::= "true"
|
true() ::= "true"
|
||||||
|
|
|
@ -154,6 +154,16 @@ public class LinearApproximator {
|
||||||
return dfa;
|
return dfa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** From linear approximate LL(1) DFA, get lookahead per alt; 1..n */
|
||||||
|
public static IntervalSet[] getLL1LookaheadSets(DFA dfa) {
|
||||||
|
IntervalSet[] look = new IntervalSet[dfa.nAlts+1];
|
||||||
|
DFAState s0 = dfa.startState;
|
||||||
|
for (int a=1; a<=dfa.nAlts; a++) {
|
||||||
|
look[a] = s0.edges.get(a-1).label;
|
||||||
|
}
|
||||||
|
return look;
|
||||||
|
}
|
||||||
|
|
||||||
/** From an NFA state, s, find the set of all labels reachable from s at
|
/** From an NFA state, s, find the set of all labels reachable from s at
|
||||||
* depth k.
|
* depth k.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -241,7 +241,7 @@ public class ParserNFAFactory implements NFAFactory {
|
||||||
Handle first = els.get(0);
|
Handle first = els.get(0);
|
||||||
Handle last = els.get(els.size()-1);
|
Handle last = els.get(els.size()-1);
|
||||||
if ( first==null || last==null ) {
|
if ( first==null || last==null ) {
|
||||||
System.out.println("huh?");
|
g.tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, "alt Handle has first|last == null");
|
||||||
}
|
}
|
||||||
return new Handle(first.left, last.right);
|
return new Handle(first.left, last.right);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package org.antlr.v4.codegen;
|
package org.antlr.v4.codegen;
|
||||||
|
|
||||||
import org.antlr.v4.codegen.src.BitSetDef;
|
import org.antlr.v4.automata.DFA;
|
||||||
import org.antlr.v4.codegen.src.OutputModelObject;
|
import org.antlr.v4.codegen.src.*;
|
||||||
import org.antlr.v4.codegen.src.ParserFile;
|
|
||||||
import org.antlr.v4.misc.IntSet;
|
import org.antlr.v4.misc.IntSet;
|
||||||
import org.antlr.v4.parse.ANTLRParser;
|
import org.antlr.v4.parse.ANTLRParser;
|
||||||
|
import org.antlr.v4.tool.BlockAST;
|
||||||
import org.antlr.v4.tool.ErrorType;
|
import org.antlr.v4.tool.ErrorType;
|
||||||
import org.antlr.v4.tool.Grammar;
|
import org.antlr.v4.tool.Grammar;
|
||||||
import org.antlr.v4.tool.GrammarAST;
|
import org.antlr.v4.tool.GrammarAST;
|
||||||
|
@ -12,6 +12,7 @@ import org.stringtemplate.v4.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
public abstract class CodeGenerator {
|
public abstract class CodeGenerator {
|
||||||
|
@ -105,6 +106,27 @@ public abstract class CodeGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Choice getChoiceBlock(BlockAST blkAST, GrammarAST ebnfRoot, List<CodeBlock> alts) {
|
||||||
|
// TODO: assumes LL1
|
||||||
|
int ebnf = 0;
|
||||||
|
if ( ebnfRoot!=null ) ebnf = ebnfRoot.getType();
|
||||||
|
Choice c = null;
|
||||||
|
switch ( ebnf ) {
|
||||||
|
case ANTLRParser.OPTIONAL :
|
||||||
|
if ( alts.size()==1 ) c = new LL1OptionalBlockSingleAlt(this, ebnfRoot, alts);
|
||||||
|
else c = new LL1OptionalBlock(this, ebnfRoot, alts);
|
||||||
|
break;
|
||||||
|
case ANTLRParser.CLOSURE :
|
||||||
|
break;
|
||||||
|
case ANTLRParser.POSITIVE_CLOSURE :
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
c = new LL1Choice(this, blkAST, alts);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
public void write(ST code, String fileName) throws IOException {
|
public void write(ST code, String fileName) throws IOException {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
Writer w = g.tool.getOutputFile(g, fileName);
|
Writer w = g.tool.getOutputFile(g, fileName);
|
||||||
|
@ -136,14 +158,28 @@ public abstract class CodeGenerator {
|
||||||
return g.name+VOCAB_FILE_EXTENSION;
|
return g.name+VOCAB_FILE_EXTENSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BitSetDef defineBitSet(GrammarAST ast, IntSet follow) {
|
public DFADef defineDFA(GrammarAST ast, DFA dfa) {
|
||||||
|
return null;
|
||||||
|
// DFADef d = new DFADef(name, dfa);
|
||||||
|
// outputModel.dfaDefs.add(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitSetDef defineFollowBitSet(GrammarAST ast, IntSet set) {
|
||||||
String inRuleName = ast.nfaState.rule.name;
|
String inRuleName = ast.nfaState.rule.name;
|
||||||
String elementName = ast.getText(); // assume rule ref
|
String elementName = ast.getText(); // assume rule ref
|
||||||
if ( ast.getType() == ANTLRParser.TOKEN_REF ) {
|
if ( ast.getType() == ANTLRParser.TOKEN_REF ) {
|
||||||
target.getTokenTypeAsTargetLabel(g, ast.getType() );
|
elementName = target.getTokenTypeAsTargetLabel(g, g.tokenNameToTypeMap.get(elementName));
|
||||||
}
|
}
|
||||||
String name = "FOLLOW_"+elementName+"_in_"+inRuleName+ast.token.getTokenIndex();
|
String name = "FOLLOW_"+elementName+"_in_"+inRuleName+"_"+ast.token.getTokenIndex();
|
||||||
BitSetDef b = new BitSetDef(this, name, follow);
|
BitSetDef b = new BitSetDef(this, name, set);
|
||||||
|
outputModel.bitSetDefs.add(b);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitSetDef defineTestBitSet(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);
|
||||||
outputModel.bitSetDefs.add(b);
|
outputModel.bitSetDefs.add(b);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,9 +73,16 @@ public class OutputModelWalker {
|
||||||
ST nestedST = walk(nestedOmo);
|
ST nestedST = walk(nestedOmo);
|
||||||
st.add(fieldName, nestedST);
|
st.add(fieldName, nestedST);
|
||||||
}
|
}
|
||||||
else if ( o instanceof Collection ) { // LIST OF MODEL OBJECTS?
|
else if ( o instanceof Collection || o instanceof OutputModelObject[] ) {
|
||||||
|
// LIST OF MODEL OBJECTS?
|
||||||
|
if ( o instanceof OutputModelObject[] ) {
|
||||||
|
o = Arrays.asList((OutputModelObject[])o);
|
||||||
|
}
|
||||||
Collection<? extends OutputModelObject> nestedOmos = (Collection)o;
|
Collection<? extends OutputModelObject> nestedOmos = (Collection)o;
|
||||||
for (OutputModelObject nestedOmo : nestedOmos) {
|
for (OutputModelObject nestedOmo : nestedOmos) {
|
||||||
|
if ( nestedOmo==null ) {
|
||||||
|
System.out.println("collection has nulls: "+nestedOmos);
|
||||||
|
}
|
||||||
ST nestedST = walk(nestedOmo);
|
ST nestedST = walk(nestedOmo);
|
||||||
st.add(fieldName, nestedST);
|
st.add(fieldName, nestedST);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,14 +24,14 @@ import java.util.HashMap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
block returns [CodeBlock omo]
|
block[GrammarAST label, GrammarAST ebnfRoot] returns [SrcOp omo]
|
||||||
: ^( BLOCK (^(OPTIONS .+))?
|
: ^( blk=BLOCK (^(OPTIONS .+))?
|
||||||
{List<CodeBlock> alts = new ArrayList<CodeBlock>();}
|
{List<CodeBlock> alts = new ArrayList<CodeBlock>();}
|
||||||
( alternative {alts.add($alternative.omo);} )+
|
( alternative {alts.add($alternative.omo);} )+
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Choice c = new LL1Choice(gen, alts); // TODO: assumes LL1
|
if ( alts.size()==1 && ebnfRoot==null) return alts.get(0);
|
||||||
$omo = new CodeBlock(gen, c);
|
$omo = gen.getChoiceBlock((BlockAST)$blk, $ebnfRoot, alts);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -43,9 +43,9 @@ alternative returns [CodeBlock omo]
|
||||||
;
|
;
|
||||||
|
|
||||||
element returns [SrcOp omo]
|
element returns [SrcOp omo]
|
||||||
: labeledElement
|
: labeledElement {$omo = $labeledElement.omo;}
|
||||||
| atom {$omo = $atom.omo;}
|
| atom[null] {$omo = $atom.omo;}
|
||||||
| ebnf
|
| ebnf {$omo = $ebnf.omo;}
|
||||||
| ACTION
|
| ACTION
|
||||||
| SEMPRED
|
| SEMPRED
|
||||||
| GATED_SEMPRED
|
| GATED_SEMPRED
|
||||||
|
@ -53,10 +53,10 @@ element returns [SrcOp omo]
|
||||||
;
|
;
|
||||||
|
|
||||||
labeledElement returns [SrcOp omo]
|
labeledElement returns [SrcOp omo]
|
||||||
: ^(ASSIGN ID atom )
|
: ^(ASSIGN ID atom[$ID] ) {$omo = $atom.omo;}
|
||||||
| ^(ASSIGN ID block)
|
| ^(ASSIGN ID block[$ID,null]) {$omo = $block.omo;}
|
||||||
| ^(PLUS_ASSIGN ID atom)
|
| ^(PLUS_ASSIGN ID atom[$ID]) {$omo = $atom.omo;}
|
||||||
| ^(PLUS_ASSIGN ID block)
|
| ^(PLUS_ASSIGN ID block[$ID,null]) {$omo = $block.omo;}
|
||||||
;
|
;
|
||||||
|
|
||||||
treeSpec returns [SrcOp omo]
|
treeSpec returns [SrcOp omo]
|
||||||
|
@ -64,14 +64,12 @@ treeSpec returns [SrcOp omo]
|
||||||
;
|
;
|
||||||
|
|
||||||
ebnf returns [SrcOp omo]
|
ebnf returns [SrcOp omo]
|
||||||
: ^(astBlockSuffix block)
|
: ^(astBlockSuffix block[null,null])
|
||||||
| ^(OPTIONAL block)
|
| ^(OPTIONAL block[null,$OPTIONAL]) {$omo = $block.omo;}
|
||||||
|
| ^(CLOSURE block[null,$CLOSURE]) {$omo = $block.omo;}
|
||||||
| ^(CLOSURE block)
|
| ^(POSITIVE_CLOSURE block[null,$POSITIVE_CLOSURE])
|
||||||
|
{$omo = $block.omo;}
|
||||||
| ^(POSITIVE_CLOSURE block)
|
| block[null, null] {$omo = $block.omo;}
|
||||||
|
|
||||||
| block
|
|
||||||
;
|
;
|
||||||
|
|
||||||
astBlockSuffix
|
astBlockSuffix
|
||||||
|
@ -80,43 +78,44 @@ astBlockSuffix
|
||||||
| BANG
|
| BANG
|
||||||
;
|
;
|
||||||
|
|
||||||
atom returns [SrcOp omo]
|
// TODO: combine ROOT/BANG into one then just make new op ref'ing return value of atom/terminal...
|
||||||
: ^(ROOT range)
|
// TODO: same for NOT
|
||||||
| ^(BANG range)
|
atom[GrammarAST label] returns [SrcOp omo]
|
||||||
| ^(ROOT notSet)
|
: ^(ROOT range[label])
|
||||||
| ^(BANG notSet)
|
| ^(BANG range[label]) {$omo = $range.omo;}
|
||||||
| notSet
|
| ^(ROOT notSet[label])
|
||||||
| range
|
| ^(BANG notSet[label]) {$omo = $notSet.omo;}
|
||||||
| ^(DOT ID terminal)
|
| notSet[label]
|
||||||
| ^(DOT ID ruleref)
|
| range[label] {$omo = $range.omo;}
|
||||||
|
| ^(DOT ID terminal[label])
|
||||||
|
| ^(DOT ID ruleref[label])
|
||||||
| ^(WILDCARD .)
|
| ^(WILDCARD .)
|
||||||
| WILDCARD
|
| WILDCARD
|
||||||
| terminal {$omo = $terminal.omo;}
|
| terminal[label] {$omo = $terminal.omo;}
|
||||||
| ruleref {$omo = $ruleref.omo;}
|
| ruleref[label] {$omo = $ruleref.omo;}
|
||||||
;
|
;
|
||||||
|
|
||||||
notSet returns [SrcOp omo]
|
notSet[GrammarAST label] returns [SrcOp omo]
|
||||||
: ^(NOT terminal)
|
: ^(NOT terminal[label])
|
||||||
| ^(NOT block)
|
| ^(NOT block[label,null])
|
||||||
;
|
;
|
||||||
|
|
||||||
ruleref returns [SrcOp omo]
|
ruleref[GrammarAST label] returns [SrcOp omo]
|
||||||
: ^(ROOT ^(RULE_REF ARG_ACTION?))
|
: ^(ROOT ^(RULE_REF ARG_ACTION?))
|
||||||
| ^(BANG ^(RULE_REF ARG_ACTION?))
|
| ^(BANG ^(RULE_REF ARG_ACTION?)) {$omo = new InvokeRule(gen, $RULE_REF, $label);}
|
||||||
| ^(RULE_REF ARG_ACTION?)
|
| ^(RULE_REF ARG_ACTION?) {$omo = new InvokeRule(gen, $RULE_REF, $label);}
|
||||||
;
|
;
|
||||||
|
|
||||||
range returns [SrcOp omo]
|
range[GrammarAST label] returns [SrcOp omo]
|
||||||
: ^(RANGE a=STRING_LITERAL b=STRING_LITERAL)
|
: ^(RANGE a=STRING_LITERAL b=STRING_LITERAL)
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
terminal returns [MatchToken omo]
|
terminal[GrammarAST label] returns [MatchToken omo]
|
||||||
: ^(STRING_LITERAL .)
|
: ^(STRING_LITERAL .) {$omo = new MatchToken(gen, (TerminalAST)$STRING_LITERAL, $label);}
|
||||||
| STRING_LITERAL
|
| STRING_LITERAL {$omo = new MatchToken(gen, (TerminalAST)$STRING_LITERAL, $label);}
|
||||||
| ^(TOKEN_REF ARG_ACTION .)
|
| ^(TOKEN_REF ARG_ACTION .) {$omo = new MatchToken(gen, (TerminalAST)$TOKEN_REF, $label);}
|
||||||
| ^(TOKEN_REF .)
|
| ^(TOKEN_REF .) {$omo = new MatchToken(gen, (TerminalAST)$TOKEN_REF, $label);}
|
||||||
| TOKEN_REF {$omo = new MatchToken(gen, (TerminalAST)$TOKEN_REF);}
|
| TOKEN_REF {$omo = new MatchToken(gen, (TerminalAST)$TOKEN_REF, $label);}
|
||||||
| ^(ROOT terminal)
|
| ^(ROOT terminal[label])
|
||||||
| ^(BANG terminal)
|
| ^(BANG terminal[label])
|
||||||
;
|
;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -74,6 +74,14 @@ public class Target {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String[] getTokenTypeAsTargetLabel(Grammar g, int[] ttypes) {
|
||||||
|
String[] labels = new String[ttypes.length];
|
||||||
|
for (int i=0; i<ttypes.length; i++) {
|
||||||
|
labels[i] = getTokenTypeAsTargetLabel(g, ttypes[i]);
|
||||||
|
}
|
||||||
|
return labels;
|
||||||
|
}
|
||||||
|
|
||||||
/** Convert from an ANTLR char literal found in a grammar file to
|
/** Convert from an ANTLR char literal found in a grammar file to
|
||||||
* an equivalent char literal in the target language. For most
|
* an equivalent char literal in the target language. For most
|
||||||
* languages, this means leaving 'x' as 'x'. Actually, we need
|
* languages, this means leaving 'x' as 'x'. Actually, we need
|
||||||
|
@ -112,4 +120,5 @@ public class Target {
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getInlineTestsVsBitsetThreshold() { return 20; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,28 @@
|
||||||
package org.antlr.v4.codegen.src;
|
package org.antlr.v4.codegen.src;
|
||||||
|
|
||||||
|
import org.antlr.v4.automata.BlockStartState;
|
||||||
import org.antlr.v4.codegen.CodeGenerator;
|
import org.antlr.v4.codegen.CodeGenerator;
|
||||||
|
import org.antlr.v4.tool.GrammarAST;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
public abstract class Choice extends SrcOp {
|
public abstract class Choice extends SrcOp {
|
||||||
public DFADef dfaDef;
|
public int decision;
|
||||||
public List<CodeBlock> alts;
|
public List<CodeBlock> alts;
|
||||||
|
public List<Decl> decls;
|
||||||
|
|
||||||
public Choice(CodeGenerator gen, List<CodeBlock> alts) {
|
public Choice(CodeGenerator gen, GrammarAST blkOrEbnfRootAST, List<CodeBlock> alts) {
|
||||||
this.gen = gen;
|
this.gen = gen;
|
||||||
|
this.ast = blkOrEbnfRootAST;
|
||||||
this.alts = alts;
|
this.alts = alts;
|
||||||
|
this.decision = ((BlockStartState)blkOrEbnfRootAST.nfaState).decision;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getChildren() {
|
public List<String> getChildren() {
|
||||||
return new ArrayList<String>() {{ add("alts"); }};
|
final List<String> sup = super.getChildren();
|
||||||
|
return new ArrayList<String>() {{ if ( sup!=null ) addAll(sup); add("alts"); add("decls"); }};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ public class CodeBlock extends SrcOp {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getChildren() {
|
public List<String> getChildren() {
|
||||||
return new ArrayList<String>() {{ add("ops"); }};
|
final List<String> sup = super.getChildren();
|
||||||
|
return new ArrayList<String>() {{ if ( sup!=null ) addAll(sup); add("ops"); }};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package org.antlr.v4.codegen.src;
|
||||||
|
|
||||||
|
/** */
|
||||||
|
public class Decl extends SrcOp {
|
||||||
|
public String varName;
|
||||||
|
public Decl(String varName) { this.varName = varName; }
|
||||||
|
}
|
|
@ -1,7 +1,9 @@
|
||||||
package org.antlr.v4.codegen.src;
|
package org.antlr.v4.codegen.src;
|
||||||
|
|
||||||
|
import org.antlr.v4.analysis.LinearApproximator;
|
||||||
import org.antlr.v4.codegen.CodeGenerator;
|
import org.antlr.v4.codegen.CodeGenerator;
|
||||||
import org.antlr.v4.misc.IntervalSet;
|
import org.antlr.v4.misc.IntervalSet;
|
||||||
|
import org.antlr.v4.tool.GrammarAST;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -10,17 +12,21 @@ public class InvokeRule extends SrcOp {
|
||||||
public String name;
|
public String name;
|
||||||
public String label;
|
public String label;
|
||||||
public List<String> args;
|
public List<String> args;
|
||||||
public IntervalSet[] follow;
|
public BitSetDef follow;
|
||||||
|
|
||||||
public InvokeRule(CodeGenerator gen, String name, String argAction, IntervalSet[] follow) {
|
public InvokeRule(CodeGenerator gen, GrammarAST ast, GrammarAST labelAST) {
|
||||||
this.gen = gen;
|
this.gen = gen;
|
||||||
|
this.ast = ast;
|
||||||
|
this.name = ast.getText();
|
||||||
|
if ( labelAST!=null ) this.label = labelAST.getText();
|
||||||
|
if ( ast.getChildCount()>0 ) {
|
||||||
|
String argAction = ast.getChild(0).getText();
|
||||||
// split and translate argAction
|
// split and translate argAction
|
||||||
// compute follow
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public InvokeRule(CodeGenerator gen, String name, IntervalSet[] follow) {
|
|
||||||
this.gen = gen;
|
|
||||||
// split and translate argAction
|
|
||||||
// compute follow
|
// compute follow
|
||||||
|
LinearApproximator approx = new LinearApproximator(gen.g, -1);
|
||||||
|
IntervalSet fset = approx.LOOK(ast.nfaState.transition(0).target);
|
||||||
|
System.out.println("follow="+follow);
|
||||||
|
follow = gen.defineFollowBitSet(ast, fset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,28 @@
|
||||||
package org.antlr.v4.codegen.src;
|
package org.antlr.v4.codegen.src;
|
||||||
|
|
||||||
|
import org.antlr.v4.analysis.LinearApproximator;
|
||||||
|
import org.antlr.v4.automata.DFA;
|
||||||
import org.antlr.v4.codegen.CodeGenerator;
|
import org.antlr.v4.codegen.CodeGenerator;
|
||||||
|
import org.antlr.v4.misc.IntervalSet;
|
||||||
|
import org.antlr.v4.tool.GrammarAST;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/** */
|
/** (A | B | C) */
|
||||||
public class LL1Choice extends Choice {
|
public class LL1Choice extends Choice {
|
||||||
public LL1Choice(CodeGenerator gen, List<CodeBlock> alts) {
|
/** Token names for each alt 0..n-1 */
|
||||||
super(gen, alts);
|
public List<String[]> altLook;
|
||||||
|
/** Lookahead for each alt 1..n */
|
||||||
|
public IntervalSet[] altLookSets;
|
||||||
|
public LL1Choice(CodeGenerator gen, GrammarAST blkAST, List<CodeBlock> alts) {
|
||||||
|
super(gen, blkAST, alts);
|
||||||
|
DFA dfa = gen.g.decisionDFAs.get(decision);
|
||||||
|
altLookSets = LinearApproximator.getLL1LookaheadSets(dfa);
|
||||||
|
altLook = new ArrayList<String[]>();
|
||||||
|
for (int a=1; a<altLookSets.length; a++) {
|
||||||
|
IntervalSet s = altLookSets[a];
|
||||||
|
altLook.add(gen.target.getTokenTypeAsTargetLabel(gen.g, s.toArray()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package org.antlr.v4.codegen.src;
|
package org.antlr.v4.codegen.src;
|
||||||
|
|
||||||
import org.antlr.v4.codegen.CodeGenerator;
|
import org.antlr.v4.codegen.CodeGenerator;
|
||||||
|
import org.antlr.v4.tool.GrammarAST;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
public class LL1OptionalBlock extends OptionalBlock {
|
public class LL1OptionalBlock extends LL1Choice {
|
||||||
public LL1OptionalBlock(CodeGenerator gen, List<CodeBlock> alts) {
|
public LL1OptionalBlock(CodeGenerator gen, GrammarAST blkAST, List<CodeBlock> alts) {
|
||||||
super(gen, alts);
|
super(gen, blkAST, alts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,31 @@
|
||||||
package org.antlr.v4.codegen.src;
|
package org.antlr.v4.codegen.src;
|
||||||
|
|
||||||
import org.antlr.v4.codegen.CodeGenerator;
|
import org.antlr.v4.codegen.CodeGenerator;
|
||||||
|
import org.antlr.v4.misc.IntervalSet;
|
||||||
|
import org.antlr.v4.tool.GrammarAST;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
public class LL1OptionalBlockSingleAlt extends OptionalBlock {
|
public class LL1OptionalBlockSingleAlt extends LL1OptionalBlock {
|
||||||
public LL1OptionalBlockSingleAlt(CodeGenerator gen, List<CodeBlock> alts) {
|
public Object expr;
|
||||||
super(gen, alts);
|
public LL1OptionalBlockSingleAlt(CodeGenerator gen, GrammarAST blkAST, List<CodeBlock> alts) {
|
||||||
|
super(gen, blkAST, alts);
|
||||||
|
IntervalSet look = altLookSets[1];
|
||||||
|
if ( look.size() < gen.target.getInlineTestsVsBitsetThreshold() ) {
|
||||||
|
expr = new TestSetInline(gen, blkAST, look);
|
||||||
|
decls = new ArrayList<Decl>();
|
||||||
|
decls.add(new NextTokenDecl("la34"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
expr = new TestSet(gen, blkAST, look);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getChildren() {
|
||||||
|
final List<String> sup = super.getChildren();
|
||||||
|
return new ArrayList<String>() {{ if ( sup!=null ) addAll(sup); add("expr"); }};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
package org.antlr.v4.codegen.src;
|
package org.antlr.v4.codegen.src;
|
||||||
|
|
||||||
import org.antlr.v4.codegen.CodeGenerator;
|
import org.antlr.v4.codegen.CodeGenerator;
|
||||||
|
import org.antlr.v4.tool.BlockAST;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
public class LLStarOptionalBlock extends OptionalBlock {
|
public class LLStarOptionalBlock extends OptionalBlock {
|
||||||
public LLStarOptionalBlock(CodeGenerator gen, List<CodeBlock> alts) {
|
public DFADef dfaDef;
|
||||||
super(gen, alts);
|
public LLStarOptionalBlock(CodeGenerator gen, BlockAST blkAST, List<CodeBlock> alts) {
|
||||||
|
super(gen, blkAST, alts);
|
||||||
|
dfaDef = gen.defineDFA(ast, gen.g.decisionDFAs.get(decision));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package org.antlr.v4.codegen.src;
|
package org.antlr.v4.codegen.src;
|
||||||
|
|
||||||
import org.antlr.v4.codegen.CodeGenerator;
|
import org.antlr.v4.codegen.CodeGenerator;
|
||||||
|
import org.antlr.v4.tool.BlockAST;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
public class LLkOptionalBlock extends OptionalBlock {
|
public class LLkOptionalBlock extends OptionalBlock {
|
||||||
public LLkOptionalBlock(CodeGenerator gen, List<CodeBlock> alts) {
|
public LLkOptionalBlock(CodeGenerator gen, BlockAST blkAST, List<CodeBlock> alts) {
|
||||||
super(gen, alts);
|
super(gen, blkAST, alts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,20 +3,23 @@ package org.antlr.v4.codegen.src;
|
||||||
import org.antlr.v4.analysis.LinearApproximator;
|
import org.antlr.v4.analysis.LinearApproximator;
|
||||||
import org.antlr.v4.codegen.CodeGenerator;
|
import org.antlr.v4.codegen.CodeGenerator;
|
||||||
import org.antlr.v4.misc.IntervalSet;
|
import org.antlr.v4.misc.IntervalSet;
|
||||||
|
import org.antlr.v4.tool.GrammarAST;
|
||||||
import org.antlr.v4.tool.TerminalAST;
|
import org.antlr.v4.tool.TerminalAST;
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
public class MatchToken extends SrcOp {
|
public class MatchToken extends SrcOp {
|
||||||
public String name;
|
public String name;
|
||||||
public BitSetDef follow;
|
public BitSetDef follow;
|
||||||
|
public String label;
|
||||||
|
|
||||||
public MatchToken(CodeGenerator gen, TerminalAST ast) {
|
public MatchToken(CodeGenerator gen, TerminalAST ast, GrammarAST labelAST) {
|
||||||
this.gen = gen;
|
this.gen = gen;
|
||||||
name = ast.getText();
|
name = ast.getText();
|
||||||
|
if ( labelAST!=null ) this.label = labelAST.getText();
|
||||||
|
|
||||||
LinearApproximator approx = new LinearApproximator(gen.g, -1);
|
LinearApproximator approx = new LinearApproximator(gen.g, -1);
|
||||||
IntervalSet fset = approx.LOOK(ast.nfaState.transition(0).target);
|
IntervalSet fset = approx.LOOK(ast.nfaState.transition(0).target);
|
||||||
System.out.println("follow="+follow);
|
System.out.println("follow="+follow);
|
||||||
follow = gen.defineBitSet(ast, fset);
|
follow = gen.defineFollowBitSet(ast, fset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package org.antlr.v4.codegen.src;
|
||||||
|
|
||||||
|
/** */
|
||||||
|
public class NextTokenDecl extends Decl {
|
||||||
|
public NextTokenDecl(String varName) { super(varName); }
|
||||||
|
}
|
|
@ -1,17 +1,13 @@
|
||||||
package org.antlr.v4.codegen.src;
|
package org.antlr.v4.codegen.src;
|
||||||
|
|
||||||
import org.antlr.v4.codegen.CodeGenerator;
|
import org.antlr.v4.codegen.CodeGenerator;
|
||||||
|
import org.antlr.v4.tool.GrammarAST;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
public class OptionalBlock extends Choice {
|
public abstract class OptionalBlock extends Choice {
|
||||||
public OptionalBlock(CodeGenerator gen, List<CodeBlock> alts) {
|
public OptionalBlock(CodeGenerator gen, GrammarAST blkAST, List<CodeBlock> alts) {
|
||||||
super(gen, alts);
|
super(gen, blkAST, alts);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getChildren() {
|
|
||||||
return super.getChildren();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ public class Parser extends OutputModelObject {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getChildren() {
|
public List<String> getChildren() {
|
||||||
return new ArrayList<String>() {{ add("funcs"); }};
|
final List<String> sup = super.getChildren();
|
||||||
|
return new ArrayList<String>() {{ if ( sup!=null ) addAll(sup); add("funcs"); }};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,9 @@ public class ParserFile extends OutputModelObject {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getChildren() {
|
public List<String> getChildren() {
|
||||||
|
final List<String> sup = super.getChildren();
|
||||||
return new ArrayList<String>() {{
|
return new ArrayList<String>() {{
|
||||||
|
if ( sup!=null ) addAll(sup);
|
||||||
add("parser");
|
add("parser");
|
||||||
add("dfaDefs");
|
add("dfaDefs");
|
||||||
add("bitSetDefs");
|
add("bitSetDefs");
|
||||||
|
|
|
@ -28,7 +28,7 @@ public class RuleFunction extends OutputModelObject {
|
||||||
public List<String> exceptions;
|
public List<String> exceptions;
|
||||||
public String finallyAction;
|
public String finallyAction;
|
||||||
|
|
||||||
public CodeBlock code;
|
public SrcOp code;
|
||||||
|
|
||||||
public RuleFunction(CodeGenerator gen, Rule r) {
|
public RuleFunction(CodeGenerator gen, Rule r) {
|
||||||
this.gen = gen;
|
this.gen = gen;
|
||||||
|
@ -52,7 +52,7 @@ public class RuleFunction extends OutputModelObject {
|
||||||
CommonTreeNodeStream nodes = new CommonTreeNodeStream(adaptor,blk);
|
CommonTreeNodeStream nodes = new CommonTreeNodeStream(adaptor,blk);
|
||||||
SourceGenTriggers genTriggers = new SourceGenTriggers(nodes, gen);
|
SourceGenTriggers genTriggers = new SourceGenTriggers(nodes, gen);
|
||||||
try {
|
try {
|
||||||
code = genTriggers.block(); // GEN Instr OBJECTS
|
code = genTriggers.block(null,null); // GEN Instr OBJECTS
|
||||||
}
|
}
|
||||||
catch (Exception e){
|
catch (Exception e){
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
|
@ -61,6 +61,7 @@ public class RuleFunction extends OutputModelObject {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getChildren() {
|
public List<String> getChildren() {
|
||||||
return new ArrayList<String>() {{ add("code"); }};
|
final List<String> sup = super.getChildren();
|
||||||
|
return new ArrayList<String>() {{ if ( sup!=null ) addAll(sup); add("code"); }};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package org.antlr.v4.codegen.src;
|
||||||
|
|
||||||
|
import org.antlr.v4.codegen.CodeGenerator;
|
||||||
|
import org.antlr.v4.misc.IntervalSet;
|
||||||
|
import org.antlr.v4.tool.GrammarAST;
|
||||||
|
|
||||||
|
/** */
|
||||||
|
public class TestSet extends OutputModelObject {
|
||||||
|
public BitSetDef set;
|
||||||
|
public TestSet(CodeGenerator gen, GrammarAST blkAST, IntervalSet set) {
|
||||||
|
this.set = gen.defineTestBitSet(blkAST, set);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package org.antlr.v4.codegen.src;
|
||||||
|
|
||||||
|
import org.antlr.v4.codegen.CodeGenerator;
|
||||||
|
import org.antlr.v4.misc.IntervalSet;
|
||||||
|
import org.antlr.v4.tool.GrammarAST;
|
||||||
|
|
||||||
|
/** */
|
||||||
|
public class TestSetInline extends OutputModelObject {
|
||||||
|
public String[] ttypes;
|
||||||
|
public TestSetInline(CodeGenerator gen, GrammarAST blkAST, IntervalSet set) {
|
||||||
|
this.ttypes = gen.target.getTokenTypeAsTargetLabel(gen.g, set.toArray());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue