after much bullshit, got sets working for ast stuff.

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 8855]
This commit is contained in:
parrt 2011-07-13 17:29:20 -08:00
parent 8a1a9d39cd
commit 42f6b7cf86
40 changed files with 774 additions and 382 deletions

View File

@ -144,7 +144,7 @@ public abstract class ATNInterpreter {
case Transition.FORCED_ACTION : return new ActionTransition(target, arg1, arg2); case Transition.FORCED_ACTION : return new ActionTransition(target, arg1, arg2);
case Transition.SET : return new SetTransition(sets.get(arg1), target); case Transition.SET : return new SetTransition(sets.get(arg1), target);
case Transition.NOT_ATOM : return new NotAtomTransition(arg1, target); case Transition.NOT_ATOM : return new NotAtomTransition(arg1, target);
case Transition.NOT_SET : return new NotSetTransition(sets.get(arg1), target); case Transition.NOT_SET : return new NotSetTransition(null, sets.get(arg1), target);
case Transition.WILDCARD : return new WildcardTransition(target); case Transition.WILDCARD : return new WildcardTransition(target);
} }
return null; return null;

View File

@ -95,7 +95,8 @@ public class LL1Analyzer {
} }
else { else {
// System.out.println("adding "+ t); // System.out.println("adding "+ t);
look.addAll(t.label()); IntervalSet set = t.label();
look.addAll(set);
} }
} }
} }

View File

@ -262,8 +262,8 @@ public class LexerInterpreter extends ATNInterpreter {
else if ( trans instanceof SetTransition ) { else if ( trans instanceof SetTransition ) {
SetTransition st = (SetTransition)trans; SetTransition st = (SetTransition)trans;
boolean not = trans instanceof NotSetTransition; boolean not = trans instanceof NotSetTransition;
if ( !not && st.label.member(t) || not && !st.label.member(t) ) { if ( !not && st.set.member(t) || not && !st.set.member(t) ) {
if ( debug ) System.out.println("match set "+st.label.toString()); if ( debug ) System.out.println("match set "+st.set.toString());
return st.target; return st.target;
} }
} }

View File

@ -32,14 +32,22 @@ package org.antlr.v4.runtime.atn;
import org.antlr.v4.runtime.misc.IntervalSet; import org.antlr.v4.runtime.misc.IntervalSet;
public class NotSetTransition extends SetTransition { public class NotSetTransition extends SetTransition {
public NotSetTransition(IntervalSet label, ATNState target) { // keep both set, notSet; we can only compute at construction time
super(label, target); // since only then do we have grammar, which knows token set for complement.
public IntervalSet notSet;
public NotSetTransition(IntervalSet set, IntervalSet notSet, ATNState target) {
super(set, target);
this.notSet = notSet;
} }
public NotSetTransition(ATNState target) { public NotSetTransition(ATNState target) {
super(target); super(target);
} }
@Override
public IntervalSet label() { return notSet; }
@Override @Override
public String toString() { public String toString() {
return '~'+super.toString(); return '~'+super.toString();

View File

@ -386,15 +386,15 @@ public class ParserInterpreter extends ATNInterpreter {
public ATNState getReachableTarget(Transition trans, int ttype) { public ATNState getReachableTarget(Transition trans, int ttype) {
if ( trans instanceof AtomTransition ) { if ( trans instanceof AtomTransition ) {
AtomTransition at = (AtomTransition)trans; AtomTransition at = (AtomTransition)trans;
boolean not = trans instanceof NotAtomTransition; // boolean not = trans instanceof NotAtomTransition;
if ( !not && at.label == ttype || not && at.label!=ttype ) { if ( at.label == ttype ) {
return at.target; return at.target;
} }
} }
else if ( trans instanceof SetTransition ) { else if ( trans instanceof SetTransition ) {
SetTransition st = (SetTransition)trans; SetTransition st = (SetTransition)trans;
boolean not = trans instanceof NotSetTransition; boolean not = trans instanceof NotSetTransition;
if ( !not && st.label.member(ttype) || not && !st.label.member(ttype) ) { if ( !not && st.set.member(ttype) || not && !st.set.member(ttype) ) {
return st.target; return st.target;
} }
} }
@ -648,7 +648,8 @@ public class ParserInterpreter extends ATNInterpreter {
} }
else if ( t instanceof SetTransition ) { else if ( t instanceof SetTransition ) {
SetTransition st = (SetTransition)t; SetTransition st = (SetTransition)t;
trans = "Set "+st.label.toString(); boolean not = st instanceof NotSetTransition;
trans = (not?"~":"")+"Set "+st.set.toString();
} }
System.err.println(c.toString(parser, true)+":"+trans); System.err.println(c.toString(parser, true)+":"+trans);
} }

View File

@ -34,21 +34,21 @@ import org.antlr.v4.runtime.misc.IntervalSet;
/** A transition containing a set of values */ /** A transition containing a set of values */
public class SetTransition extends Transition { public class SetTransition extends Transition {
public IntervalSet label; public IntervalSet set;
public SetTransition(IntervalSet label, ATNState target) { public SetTransition(IntervalSet set, ATNState target) {
super(target); super(target);
if ( label==null ) label = IntervalSet.of(Token.INVALID_TYPE); if ( set == null ) set = IntervalSet.of(Token.INVALID_TYPE);
this.label = label; this.set = set;
} }
public SetTransition(ATNState target) { public SetTransition(ATNState target) {
super(target); super(target);
} }
public IntervalSet label() { return label; } public IntervalSet label() { return set; }
public String toString() { public String toString() {
return label.toString(); return set.toString();
} }
} }

View File

@ -1,10 +1,11 @@
grammar T; grammar T;
options {output=AST;} options {output=AST;}
a : (ID INT) ; a : ('+' | '-')^ ;
b returns [int i] : ID; b returns [int i] : ID;
ID : 'a'..'z'+ ; ID : 'a'..'z'+ ;
INT : '0'..'9'+; INT : '0'..'9'+;
PLUS : '+';
WS : (' '|'\n') {$channel=HIDDEN;} ; WS : (' '|'\n') {$channel=HIDDEN;} ;
/* /*

View File

@ -235,6 +235,8 @@ case <i>:
} }
>> >>
// TODO: we we need uniqueID? a single _alt might work
StarBlock(choice, alts, sync) ::= << StarBlock(choice, alts, sync) ::= <<
int _alt<choice.uniqueID> = _interp.adaptivePredict(input,<choice.decision>,_ctx); int _alt<choice.uniqueID> = _interp.adaptivePredict(input,<choice.decision>,_ctx);
while ( _alt<choice.uniqueID>!=<choice.exitAlt> ) { while ( _alt<choice.uniqueID>!=<choice.exitAlt> ) {
@ -285,6 +287,18 @@ _localctx.s = <m.stateNumber>;
<if(m.labels)><m.labels:{l | <labelref(l)> = }>(Token)<endif>match(<m.name>); <if(m.labels)><m.labels:{l | <labelref(l)> = }>(Token)<endif>match(<m.name>);
>> >>
MatchSet(m, expr, capture) ::= "<CommonSetStuff(m, expr, capture, false)>"
MatchNotSet(m, expr, capture) ::= "<CommonSetStuff(m, expr, capture, true)>"
CommonSetStuff(m, expr, capture, invert) ::= <<
_localctx.s = <m.stateNumber>;
<if(m.labels)><m.labels:{l | <labelref(l)> = }><endif>input.LT(1);
<capture>
if ( <if(!invert)>!<endif>(<expr>) ) throw new MismatchedSetException(this, input);
input.consume();
>>
Wildcard(w) ::= << Wildcard(w) ::= <<
_localctx.s = <w.stateNumber>; _localctx.s = <w.stateNumber>;
<if(w.labels)><w.labels:{l | <labelref(l)> = }><endif>input.LT(1); input.consume(); <if(w.labels)><w.labels:{l | <labelref(l)> = }><endif>input.LT(1); input.consume();
@ -354,6 +368,7 @@ ParserRuleContext() ::= "ParserRuleContext"
RuleDynamicScopeStructName(ruleName) ::= "<ruleName>_stk" RuleDynamicScopeStructName(ruleName) ::= "<ruleName>_stk"
ImplicitTokenLabel(tokenName) ::= "_t<tokenName>" ImplicitTokenLabel(tokenName) ::= "_t<tokenName>"
ImplicitRuleLabel(ruleName) ::= "_r<ruleName>" ImplicitRuleLabel(ruleName) ::= "_r<ruleName>"
ImplicitSetLabel(id) ::= "_tset<id>"
ListLabelName(label) ::= "<label>_list" ListLabelName(label) ::= "<label>_list"
CaptureNextToken(d) ::= "<d.varName> = input.LT(1);" CaptureNextToken(d) ::= "<d.varName> = input.LT(1);"

View File

@ -206,8 +206,11 @@ public class Tool {
GrammarAST t = load(fileName); GrammarAST t = load(fileName);
if ( t instanceof GrammarASTErrorNode ) return; // came back as error node if ( t instanceof GrammarASTErrorNode ) return; // came back as error node
if ( ((GrammarRootAST)t).hasErrors ) return; if ( ((GrammarRootAST)t).hasErrors ) return;
GrammarRootAST ast = (GrammarRootAST)t; GrammarRootAST ast = (GrammarRootAST)t;
GrammarTransformPipeline transform = new GrammarTransformPipeline(ast);
transform.process();
Grammar g = createGrammar(ast); Grammar g = createGrammar(ast);
g.fileName = fileName; g.fileName = fileName;
process(g); process(g);

View File

@ -30,7 +30,6 @@
package org.antlr.v4.automata; package org.antlr.v4.automata;
import org.antlr.v4.runtime.atn.*; import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.misc.IntervalSet;
import org.antlr.v4.tool.*; import org.antlr.v4.tool.*;
import java.util.List; import java.util.List;
@ -68,16 +67,13 @@ public interface ATNFactory {
Handle tokenRef(TerminalAST node); Handle tokenRef(TerminalAST node);
/** From set build single edge graph o->o-set->o. To conform to Handle set(GrammarAST associatedAST, List<GrammarAST> terminals, boolean invert);
* what an alt block looks like, must have extra state on left.
*/
Handle set(IntervalSet set, GrammarAST associatedAST);
Handle tree(List<Handle> els); Handle tree(List<Handle> els);
Handle range(GrammarAST a, GrammarAST b); Handle range(GrammarAST a, GrammarAST b);
Handle not(GrammarAST a); // Handle not(GrammarAST a);
/** For a non-lexer, just build a simple token reference atom. /** For a non-lexer, just build a simple token reference atom.
* For a lexer, a string is a sequence of char to match. That is, * For a lexer, a string is a sequence of char to match. That is,
@ -149,7 +145,7 @@ public interface ATNFactory {
*/ */
Handle block(BlockAST blockAST, GrammarAST ebnfRoot, List<Handle> alternativeGrips); Handle block(BlockAST blockAST, GrammarAST ebnfRoot, List<Handle> alternativeGrips);
Handle notBlock(GrammarAST blockAST, List<GrammarAST> terminals); // Handle notBlock(GrammarAST blockAST, Handle set);
/** From (A)? build either: /** From (A)? build either:
* *

View File

@ -79,6 +79,11 @@ public class ATNPrinter {
ActionTransition a = (ActionTransition)t; ActionTransition a = (ActionTransition)t;
buf.append("-"+a.toString()+"->"+ getStateString(t.target)+'\n'); buf.append("-"+a.toString()+"->"+ getStateString(t.target)+'\n');
} }
else if ( t instanceof SetTransition ) {
SetTransition st = (SetTransition)t;
boolean not = st instanceof NotSetTransition;
buf.append("-"+(not?"~":"")+st.toString()+"->"+ getStateString(t.target)+'\n');
}
else if ( t instanceof AtomTransition ) { else if ( t instanceof AtomTransition ) {
AtomTransition a = (AtomTransition)t; AtomTransition a = (AtomTransition)t;
String label = a.toString(); String label = a.toString();

View File

@ -87,7 +87,7 @@ public class ATNSerializer {
int edgeType = Transition.serializationTypes.get(t.getClass()); int edgeType = Transition.serializationTypes.get(t.getClass());
if ( edgeType == Transition.SET || edgeType == Transition.NOT_SET ) { if ( edgeType == Transition.SET || edgeType == Transition.NOT_SET ) {
SetTransition st = (SetTransition)t; SetTransition st = (SetTransition)t;
sets.add(st.label); sets.add(st.set);
} }
} }
} }

View File

@ -29,8 +29,10 @@
package org.antlr.v4.automata; package org.antlr.v4.automata;
import org.antlr.runtime.Token;
import org.antlr.v4.misc.CharSupport; import org.antlr.v4.misc.CharSupport;
import org.antlr.v4.runtime.atn.*; import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.misc.IntervalSet;
import org.antlr.v4.tool.*; import org.antlr.v4.tool.*;
import java.util.List; import java.util.List;
@ -98,6 +100,27 @@ public class LexerATNFactory extends ParserATNFactory {
return new Handle(left, right); return new Handle(left, right);
} }
@Override
public Handle set(GrammarAST associatedAST, List<GrammarAST> terminals, boolean invert) {
ATNState left = newState(associatedAST);
ATNState right = newState(associatedAST);
IntervalSet set = new IntervalSet();
for (GrammarAST t : terminals) {
int c = CharSupport.getCharValueFromGrammarCharLiteral(t.getText());
set.add(c);
}
if ( invert ) {
IntervalSet notSet = (IntervalSet)set.complement(Token.MIN_TOKEN_TYPE, g.getMaxTokenType());
left.transition = new NotSetTransition(set, notSet, right);
}
else {
left.transition = new SetTransition(set, right);
}
right.incidentTransition = left.transition;
associatedAST.atnState = left;
return new Handle(left, right);
}
/** For a lexer, a string is a sequence of char to match. That is, /** For a lexer, a string is a sequence of char to match. That is,
* "fog" is treated as 'f' 'o' 'g' not as a single transition in * "fog" is treated as 'f' 'o' 'g' not as a single transition in
* the DFA. Machine== o-'f'->o-'o'->o-'g'->o and has n+1 states * the DFA. Machine== o-'f'->o-'o'->o-'g'->o and has n+1 states

View File

@ -110,11 +110,23 @@ public class ParserATNFactory implements ATNFactory {
/** From set build single edge graph o->o-set->o. To conform to /** From set build single edge graph o->o-set->o. To conform to
* what an alt block looks like, must have extra state on left. * what an alt block looks like, must have extra state on left.
* This handles ~A also, converted to ~{A} set.
*/ */
public Handle set(IntervalSet set, GrammarAST associatedAST) { public Handle set(GrammarAST associatedAST, List<GrammarAST> terminals, boolean invert) {
ATNState left = newState(associatedAST); ATNState left = newState(associatedAST);
ATNState right = newState(associatedAST); ATNState right = newState(associatedAST);
IntervalSet set = new IntervalSet();
for (GrammarAST t : terminals) {
int ttype = g.getTokenType(t.getText());
set.add(ttype);
}
if ( invert ) {
IntervalSet notSet = (IntervalSet)set.complement(Token.MIN_TOKEN_TYPE, g.getMaxTokenType());
left.transition = new NotSetTransition(set, notSet, right);
}
else {
left.transition = new SetTransition(set, right); left.transition = new SetTransition(set, right);
}
right.incidentTransition = left.transition; right.incidentTransition = left.transition;
associatedAST.atnState = left; associatedAST.atnState = left;
return new Handle(left, right); return new Handle(left, right);
@ -128,6 +140,7 @@ public class ParserATNFactory implements ATNFactory {
public Handle range(GrammarAST a, GrammarAST b) { throw new UnsupportedOperationException(); } public Handle range(GrammarAST a, GrammarAST b) { throw new UnsupportedOperationException(); }
/** ~atom only */ /** ~atom only */
/*
public Handle not(GrammarAST node) { public Handle not(GrammarAST node) {
ATNState left = newState(node); ATNState left = newState(node);
ATNState right = newState(node); ATNState right = newState(node);
@ -137,6 +150,7 @@ public class ParserATNFactory implements ATNFactory {
node.atnState = left; node.atnState = left;
return new Handle(left, right); return new Handle(left, right);
} }
*/
protected int getTokenType(GrammarAST atom) { protected int getTokenType(GrammarAST atom) {
int ttype; int ttype;
@ -300,27 +314,12 @@ public class ParserATNFactory implements ATNFactory {
return h; return h;
} }
public Handle notBlock(GrammarAST notAST, List<GrammarAST> terminals) { // public Handle notBlock(GrammarAST notAST, Handle set) {
// assume list of atoms // SetTransition st = (SetTransition)set.left.transition;
IntervalSet notSet = new IntervalSet(); // set.left.transition = new NotSetTransition(st.label, set.right);
for (GrammarAST elemAST : terminals) { // notAST.atnState = set.left;
if ( elemAST.getType()==ANTLRParser.RANGE ) { // return set;
GrammarAST from = (GrammarAST)elemAST.getChild(0); // }
GrammarAST to = (GrammarAST)elemAST.getChild(1);
notSet.add(getTokenType(from), getTokenType(to));
}
else {
notSet.add(getTokenType(elemAST));
}
}
ATNState left = newState(notAST);
ATNState right = newState(notAST);
left.transition = new NotSetTransition(notSet, right);
right.incidentTransition = left.transition;
notAST.atnState = left;
return new Handle(left, right);
}
public Handle alt(List<Handle> els) { public Handle alt(List<Handle> els) {
Handle prev = null; Handle prev = null;

View File

@ -63,6 +63,8 @@ public abstract class BlankOutputModelFactory implements OutputModelFactory {
public List<SrcOp> stringRef(GrammarAST ID, GrammarAST label, GrammarAST astOp) { return tokenRef(ID, label, null, astOp); } public List<SrcOp> stringRef(GrammarAST ID, GrammarAST label, GrammarAST astOp) { return tokenRef(ID, label, null, astOp); }
public List<SrcOp> set(GrammarAST setAST, GrammarAST label, GrammarAST astOp, boolean invert) { return null; }
// ACTIONS // ACTIONS
public List<SrcOp> action(GrammarAST ast) { return null; } public List<SrcOp> action(GrammarAST ast) { return null; }

View File

@ -66,6 +66,8 @@ public class CodeGeneratorExtension {
public List<SrcOp> tokenRef(List<SrcOp> ops) { return ops; } public List<SrcOp> tokenRef(List<SrcOp> ops) { return ops; }
public List<SrcOp> set(List<SrcOp> ops) { return ops; }
public List<SrcOp> stringRef(List<SrcOp> ops) { return ops; } public List<SrcOp> stringRef(List<SrcOp> ops) { return ops; }
public List<SrcOp> wildcard(List<SrcOp> ops) { return ops; } public List<SrcOp> wildcard(List<SrcOp> ops) { return ops; }
@ -92,11 +94,15 @@ public class CodeGeneratorExtension {
public List<SrcOp> leafString(List<SrcOp> ops) { return ops; } public List<SrcOp> leafString(List<SrcOp> ops) { return ops; }
public List<SrcOp> rootSet(List<SrcOp> ops) { return ops; }
public List<SrcOp> leafSet(List<SrcOp> ops) { return ops; }
// BLOCKS // BLOCKS
public List<SrcOp> getChoiceBlock(List<SrcOp> ops) { return ops; } public Choice getChoiceBlock(Choice c) { return c; }
public List<SrcOp> getEBNFBlock(List<SrcOp> ops) { return ops; } public Choice getEBNFBlock(Choice c) { return c; }
public boolean needsImplicitLabel(GrammarAST ID, LabeledOp op) { return false; } public boolean needsImplicitLabel(GrammarAST ID, LabeledOp op) { return false; }

View File

@ -215,6 +215,22 @@ public class OutputModelController {
return ops; return ops;
} }
/** (A|B|C) possibly with ebnfRoot and label */
public List<SrcOp> set(GrammarAST setAST, GrammarAST labelAST,
GrammarAST astOp, boolean invert) {
List<SrcOp> ops = delegate.set(setAST, labelAST, astOp, invert);
for (CodeGeneratorExtension ext : extensions) {
ops = ext.set(ops);
if ( astOp!=null && astOp.getType()==ANTLRParser.ROOT ) {
ops = ext.rootSet(ops);
}
else if ( astOp==null ) {
ops = ext.leafSet(ops);
}
}
return ops;
}
public CodeBlockForAlt epsilon() { public CodeBlockForAlt epsilon() {
CodeBlockForAlt blk = delegate.epsilon(); CodeBlockForAlt blk = delegate.epsilon();
for (CodeGeneratorExtension ext : extensions) blk = ext.epsilon(blk); for (CodeGeneratorExtension ext : extensions) blk = ext.epsilon(blk);
@ -259,15 +275,13 @@ public class OutputModelController {
public Choice getChoiceBlock(BlockAST blkAST, List<CodeBlockForAlt> alts, GrammarAST label) { public Choice getChoiceBlock(BlockAST blkAST, List<CodeBlockForAlt> alts, GrammarAST label) {
Choice c = delegate.getChoiceBlock(blkAST, alts, label); Choice c = delegate.getChoiceBlock(blkAST, alts, label);
List<SrcOp> ops = DefaultOutputModelFactory.list(c); for (CodeGeneratorExtension ext : extensions) c = ext.getChoiceBlock(c);
for (CodeGeneratorExtension ext : extensions) ops = ext.getChoiceBlock(ops);
return c; return c;
} }
public Choice getEBNFBlock(GrammarAST ebnfRoot, List<CodeBlockForAlt> alts) { public Choice getEBNFBlock(GrammarAST ebnfRoot, List<CodeBlockForAlt> alts) {
Choice c = delegate.getEBNFBlock(ebnfRoot, alts); Choice c = delegate.getEBNFBlock(ebnfRoot, alts);
List<SrcOp> ops = DefaultOutputModelFactory.list(c); for (CodeGeneratorExtension ext : extensions) c = ext.getEBNFBlock(c);
for (CodeGeneratorExtension ext : extensions) ops = ext.getEBNFBlock(ops);
return c; return c;
} }

View File

@ -70,6 +70,8 @@ public interface OutputModelFactory {
List<SrcOp> stringRef(GrammarAST ID, GrammarAST label, GrammarAST astOp); List<SrcOp> stringRef(GrammarAST ID, GrammarAST label, GrammarAST astOp);
List<SrcOp> set(GrammarAST setAST, GrammarAST label, GrammarAST astOp, boolean invert);
List<SrcOp> action(GrammarAST ast); List<SrcOp> action(GrammarAST ast);
List<SrcOp> forcedAction(GrammarAST ast); List<SrcOp> forcedAction(GrammarAST ast);

View File

@ -45,13 +45,12 @@ public class ParserASTExtension extends CodeGeneratorExtension {
} }
@Override @Override
public List<SrcOp> getChoiceBlock(List<SrcOp> ops) { public Choice getChoiceBlock(Choice choice) {
Choice choice = (Choice)Utils.find(ops, Choice.class);
Alternative alt = factory.getCurrentOuterMostAlt(); Alternative alt = factory.getCurrentOuterMostAlt();
if ( alt.hasRewrite() && choice.label!=null ) { if ( alt.hasRewrite() && choice.label!=null ) {
trackExplicitLabel(choice.preamble, choice.label, choice); trackExplicitLabel(choice.preamble, choice.label, choice);
} }
return ops; return choice;
} }
@Override @Override
@ -168,11 +167,15 @@ public class ParserASTExtension extends CodeGeneratorExtension {
TokenDecl label = (TokenDecl)((LabeledOp)matchOp).getLabels().get(0); TokenDecl label = (TokenDecl)((LabeledOp)matchOp).getLabels().get(0);
// First declare tracking lists for elements, labels // First declare tracking lists for elements, labels
// track the named element like _track_A // track the named element like _track_A
String elemListName = factory.getGenerator().target.getElementListName(matchOp.ast.getText()); String elemName = matchOp.ast.getText();
if ( matchOp.ast.getType()==ANTLRParser.SET ) {
elemName = String.valueOf(matchOp.ast.token.getTokenIndex());
}
String elemListName = factory.getGenerator().target.getElementListName(elemName);
blk.addLocalDecl(new ElementListDecl(factory, elemListName)); blk.addLocalDecl(new ElementListDecl(factory, elemListName));
// Now, generate track instructions for element and any labels // Now, generate track instructions for element and any labels
// do element // do element
String trackName = factory.getGenerator().target.getElementListName(matchOp.ast.getText()); String trackName = factory.getGenerator().target.getElementListName(elemName);
TrackTokenElement t = new TrackTokenElement(factory, matchOp.ast, trackName, TrackTokenElement t = new TrackTokenElement(factory, matchOp.ast, trackName,
label); label);
ops.add(t); ops.add(t);
@ -180,6 +183,12 @@ public class ParserASTExtension extends CodeGeneratorExtension {
return ops; return ops;
} }
@Override
public List<SrcOp> rootSet(List<SrcOp> ops) { return rootToken(ops); }
@Override
public List<SrcOp> leafSet(List<SrcOp> ops) { return leafToken(ops); }
@Override @Override
public List<SrcOp> wildcard(List<SrcOp> ops) { public List<SrcOp> wildcard(List<SrcOp> ops) {
Wildcard wild = (Wildcard)Utils.find(ops, Wildcard.class); Wildcard wild = (Wildcard)Utils.find(ops, Wildcard.class);

View File

@ -103,6 +103,28 @@ public class ParserFactory extends DefaultOutputModelFactory {
return list(matchOp, listLabelOp); return list(matchOp, listLabelOp);
} }
@Override
public List<SrcOp> set(GrammarAST setAST, GrammarAST labelAST,
GrammarAST astOp, boolean invert)
{
LabeledOp matchOp;
if ( invert ) matchOp = new MatchNotSet(this, setAST);
else matchOp = new MatchSet(this, setAST);
if ( labelAST!=null ) {
String label = labelAST.getText();
TokenDecl d = new TokenDecl(this, label);
((MatchSet)matchOp).labels.add(d);
getCurrentRuleFunction().addContextDecl(d);
if ( labelAST.parent.getType() == ANTLRParser.PLUS_ASSIGN ) {
TokenListDecl l = new TokenListDecl(this, gen.target.getListLabel(label));
getCurrentRuleFunction().addContextDecl(l);
}
}
if ( controller.needsImplicitLabel(setAST, matchOp) ) defineImplicitLabel(setAST, matchOp);
AddToLabelList listLabelOp = getListLabelIfPresent(matchOp, labelAST);
return list(matchOp, listLabelOp);
}
@Override @Override
public List<SrcOp> wildcard(GrammarAST ast, GrammarAST labelAST) { public List<SrcOp> wildcard(GrammarAST ast, GrammarAST labelAST) {
Wildcard wild = new Wildcard(this, ast); Wildcard wild = new Wildcard(this, ast);
@ -348,18 +370,24 @@ public class ParserFactory extends DefaultOutputModelFactory {
return op; return op;
} }
public void defineImplicitLabel(GrammarAST ID, LabeledOp op) { public void defineImplicitLabel(GrammarAST ast, LabeledOp op) {
Decl d; Decl d;
Rule r = g.getRule(ID.getText()); Rule r = g.getRule(ast.getText());
if ( r!=null ) { if ( ast.getType()==ANTLRParser.SET ) {
String implLabel = gen.target.getImplicitRuleLabel(ID.getText()); String implLabel =
gen.target.getImplicitSetLabel(String.valueOf(ast.token.getTokenIndex()));
d = new TokenDecl(this, implLabel);
((TokenDecl)d).isImplicit = true;
}
else if ( r!=null ) {
String implLabel = gen.target.getImplicitRuleLabel(ast.getText());
String ctxName = String ctxName =
gen.target.getRuleFunctionContextStructName(r); gen.target.getRuleFunctionContextStructName(r);
d = new RuleContextDecl(this, implLabel, ctxName); d = new RuleContextDecl(this, implLabel, ctxName);
((RuleContextDecl)d).isImplicit = true; ((RuleContextDecl)d).isImplicit = true;
} }
else { else {
String implLabel = gen.target.getImplicitTokenLabel(ID.getText()); String implLabel = gen.target.getImplicitTokenLabel(ast.getText());
d = new TokenDecl(this, implLabel); d = new TokenDecl(this, implLabel);
((TokenDecl)d).isImplicit = true; ((TokenDecl)d).isImplicit = true;
} }

View File

@ -78,8 +78,8 @@ alternative returns [CodeBlockForAlt altCodeBlock, List<SrcOp> ops]
element returns [List<? extends SrcOp> omos] element returns [List<? extends SrcOp> omos]
: labeledElement {$omos = $labeledElement.omos;} : labeledElement {$omos = $labeledElement.omos;}
| atom[null] {$omos = $atom.omos;} | atom[null,null,false] {$omos = $atom.omos;}
| ebnf {$omos = $ebnf.omos;} | subrule {$omos = $subrule.omos;}
| ACTION {$omos = controller.action($ACTION);} | ACTION {$omos = controller.action($ACTION);}
| FORCED_ACTION {$omos = controller.forcedAction($FORCED_ACTION);} | FORCED_ACTION {$omos = controller.forcedAction($FORCED_ACTION);}
| SEMPRED {$omos = controller.sempred($SEMPRED);} | SEMPRED {$omos = controller.sempred($SEMPRED);}
@ -88,9 +88,9 @@ element returns [List<? extends SrcOp> omos]
; ;
labeledElement returns [List<? extends SrcOp> omos] labeledElement returns [List<? extends SrcOp> omos]
: ^(ASSIGN ID atom[$ID] ) {$omos = $atom.omos;} : ^(ASSIGN ID atom[$ID,null,false] ) {$omos = $atom.omos;}
| ^(ASSIGN ID block[$ID,null,null]) {$omos = $block.omos;} | ^(PLUS_ASSIGN ID atom[$ID,null,false]) {$omos = $atom.omos;}
| ^(PLUS_ASSIGN ID atom[$ID]) {$omos = $atom.omos;} | ^(ASSIGN ID block[$ID,null,null] ) {$omos = $block.omos;}
| ^(PLUS_ASSIGN ID block[$ID,null,null]) {$omos = $block.omos;} | ^(PLUS_ASSIGN ID block[$ID,null,null]) {$omos = $block.omos;}
; ;
@ -98,8 +98,8 @@ treeSpec returns [SrcOp omo]
: ^(TREE_BEGIN (e=element )+) : ^(TREE_BEGIN (e=element )+)
; ;
ebnf returns [List<? extends SrcOp> omos] subrule returns [List<? extends SrcOp> omos]
: ^(astBlockSuffix block[null,null,null]) : ^(astBlockSuffix block[null,null,$astBlockSuffix.start]) {$omos = $block.omos;}
| ^(OPTIONAL block[null,$OPTIONAL,null]) {$omos = $block.omos;} | ^(OPTIONAL block[null,$OPTIONAL,null]) {$omos = $block.omos;}
| ^(CLOSURE block[null,$CLOSURE,null]) {$omos = $block.omos;} | ^(CLOSURE block[null,$CLOSURE,null]) {$omos = $block.omos;}
| ^(POSITIVE_CLOSURE block[null,$POSITIVE_CLOSURE,null]) | ^(POSITIVE_CLOSURE block[null,$POSITIVE_CLOSURE,null])
@ -113,29 +113,31 @@ astBlockSuffix
| BANG | BANG
; ;
// TODO: combine ROOT/BANG into one then just make new op ref'ing return value of atom/terminal... blockSet[GrammarAST label, GrammarAST astOp, boolean invert] returns [List<SrcOp> omos]
// TODO: same for NOT : ^(SET atom[null,null,false]+) {$omos = controller.set($SET, $label, $astOp, invert);}
atom[GrammarAST label] returns [List<SrcOp> omos]
: ^(ROOT notSet[label, $ROOT]) {$omos = $notSet.omos;}
| ^(BANG notSet[label, $BANG]) {$omos = $notSet.omos;}
| notSet[label, null] {$omos = $notSet.omos;}
| range[label] {$omos = $range.omos;}
| ^(DOT ID terminal[label, null])
| ^(DOT ID ruleref[label, null])
| ^(WILDCARD .) {$omos = controller.wildcard($WILDCARD, $label);}
| WILDCARD {$omos = controller.wildcard($WILDCARD, $label);}
| ^(ROOT terminal[label, $ROOT]) {$omos = $terminal.omos;}
| ^(BANG terminal[label, $BANG]) {$omos = $terminal.omos;}
| terminal[label, null] {$omos = $terminal.omos;}
| ^(ROOT ruleref[label, $ROOT]) {$omos = $ruleref.omos;}
| ^(BANG ruleref[label, $BANG]) {$omos = $ruleref.omos;}
| ruleref[label, null] {$omos = $ruleref.omos;}
; ;
// TODO: send NOT to factory methods /*
notSet[GrammarAST label, GrammarAST astOp] returns [List<SrcOp> omos] setElement
: ^(NOT terminal[label, astOp]) : STRING_LITERAL
| ^(NOT block[label,null, astOp]) | TOKEN_REF
| ^(RANGE STRING_LITERAL STRING_LITERAL)
;
*/
// TODO: combine ROOT/BANG into one then just make new op ref'ing return value of atom/terminal...
// TODO: same for NOT
atom[GrammarAST label, GrammarAST astOp, boolean invert] returns [List<SrcOp> omos]
: ^(op=(ROOT|BANG) a=atom[$label, $op, $invert] ) {$omos = $a.omos;}
| ^(NOT a=atom[$label, $astOp, true]) {$omos = $a.omos;}
| range[label] {$omos = $range.omos;}
| ^(DOT ID terminal[$label, null])
| ^(DOT ID ruleref[$label, null])
| ^(WILDCARD .) {$omos = controller.wildcard($WILDCARD, $label);}
| WILDCARD {$omos = controller.wildcard($WILDCARD, $label);}
| terminal[label, $astOp] {$omos = $terminal.omos;}
| ruleref[label, $astOp] {$omos = $ruleref.omos;}
| blockSet[$label, $astOp, invert] {$omos = $blockSet.omos;}
; ;
ruleref[GrammarAST label, GrammarAST astOp] returns [List<SrcOp> omos] ruleref[GrammarAST label, GrammarAST astOp] returns [List<SrcOp> omos]

View File

@ -239,6 +239,13 @@ public class Target {
return st.render(); return st.render();
} }
// x=(A|B)
public String getImplicitSetLabel(String id) {
ST st = gen.templates.getInstanceOf("ImplicitSetLabel");
st.add("id", id);
return st.render();
}
public String getImplicitRuleLabel(String ruleName) { public String getImplicitRuleLabel(String ruleName) {
ST st = gen.templates.getInstanceOf("ImplicitRuleLabel"); ST st = gen.templates.getInstanceOf("ImplicitRuleLabel");
st.add("ruleName", ruleName); st.add("ruleName", ruleName);

View File

@ -77,7 +77,7 @@ public abstract class Choice extends RuleElement {
public SrcOp addCodeForLookaheadTempVar(IntervalSet look) { public SrcOp addCodeForLookaheadTempVar(IntervalSet look) {
List<SrcOp> testOps = factory.getLL1Test(look, ast); List<SrcOp> testOps = factory.getLL1Test(look, ast);
SrcOp expr = (SrcOp)Utils.find(testOps, TestSetInline.class); SrcOp expr = (SrcOp) Utils.find(testOps, TestSetInline.class);
if ( expr instanceof TestSetInline) { if ( expr instanceof TestSetInline) {
TestSetInline e = (TestSetInline)expr; TestSetInline e = (TestSetInline)expr;
Decl d = new TokenTypeDecl(factory, e.varName); Decl d = new TokenTypeDecl(factory, e.varName);
@ -87,5 +87,4 @@ public abstract class Choice extends RuleElement {
} }
return expr; return expr;
} }
} }

View File

@ -0,0 +1,39 @@
/*
[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;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.tool.GrammarAST;
public class MatchNotSet extends MatchSet {
public MatchNotSet(OutputModelFactory factory, GrammarAST ast) {
super(factory, ast);
}
}

View File

@ -0,0 +1,49 @@
/*
[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;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.codegen.model.decl.*;
import org.antlr.v4.runtime.atn.SetTransition;
import org.antlr.v4.tool.GrammarAST;
public class MatchSet extends MatchToken {
@ModelElement public TestSetInline expr;
@ModelElement public CaptureNextTokenType capture;
public MatchSet(OutputModelFactory factory, GrammarAST ast) {
super(factory, ast);
SetTransition st = (SetTransition)ast.atnState.transition;
expr = new TestSetInline(factory, null, st.set);
Decl d = new TokenTypeDecl(factory, expr.varName);
factory.getCurrentRuleFunction().addLocalDecl(d);
capture = new CaptureNextTokenType(factory,expr.varName);
}
}

View File

@ -48,5 +48,9 @@ public class MatchToken extends RuleElement implements LabeledOp {
name = gen.target.getTokenTypeAsTargetLabel(g, ttype); name = gen.target.getTokenTypeAsTargetLabel(g, ttype);
} }
public MatchToken(OutputModelFactory factory, GrammarAST ast) {
super(factory, ast);
}
public List<Decl> getLabels() { return labels; } public List<Decl> getLabels() { return labels; }
} }

View File

@ -40,4 +40,5 @@ public class RuleElement extends SrcOp {
super(factory, ast); super(factory, ast);
if ( ast.atnState!=null ) stateNumber = ast.atnState.stateNumber; if ( ast.atnState!=null ) stateNumber = ast.atnState.stateNumber;
} }
} }

View File

@ -35,7 +35,7 @@ import org.antlr.v4.tool.GrammarAST;
/** */ /** */
public abstract class SrcOp extends OutputModelObject { public abstract class SrcOp extends OutputModelObject {
/** Used to create unique var names etc... */ /** Used to create unique var names etc... */
// public int uniqueID; public int uniqueID; // TODO: do we need?
/** All operations know in which block they live: /** All operations know in which block they live:
* *
@ -49,7 +49,7 @@ public abstract class SrcOp extends OutputModelObject {
public SrcOp(OutputModelFactory factory) { this(factory,null); } public SrcOp(OutputModelFactory factory) { this(factory,null); }
public SrcOp(OutputModelFactory factory, GrammarAST ast) { public SrcOp(OutputModelFactory factory, GrammarAST ast) {
super(factory,ast); super(factory,ast);
//uniqueID = ast.token.getTokenIndex(); if ( ast!=null ) uniqueID = ast.token.getTokenIndex();
enclosingBlock = factory.getCurrentBlock(); enclosingBlock = factory.getCurrentBlock();
} }
} }

View File

@ -69,6 +69,7 @@ tokens {
POSITIVE_CLOSURE; POSITIVE_CLOSURE;
SYNPRED; SYNPRED;
RANGE; RANGE;
SET;
CHAR_RANGE; CHAR_RANGE;
EPSILON; EPSILON;
ALT; ALT;
@ -133,6 +134,10 @@ import org.antlr.v4.tool.*;
@members { @members {
Stack paraphrases = new Stack(); Stack paraphrases = new Stack();
/** Affects tree construction; no SET collapsing if AST (ID|INT) would hide them from rewrite.
* Could use for just AST ops, but we can't see -> until after building sets.
boolean buildAST;
*/
} }
// The main entry point for parsing a V3 grammar from top to toe. This is // The main entry point for parsing a V3 grammar from top to toe. This is
@ -245,6 +250,13 @@ optionsSpec
option option
: id ASSIGN^ optionValue : id ASSIGN^ optionValue
/*
{
if ( $id.text.equals("output") ) {
if ( $optionValue.text.equals("AST") ) buildAST = true;
}
}
*/
; ;
// ------------ // ------------
@ -611,53 +623,24 @@ element
} }
reportError(re); reportError(re);
recover(input,re); recover(input,re);
/*
input.rewind(m);
final List subset = input.get(input.index(), input.range());
System.out.println("failed to match as element: '"+subset);
CommonTokenStream ns = new CommonTokenStream(
new TokenSource() {
int i = 0;
public Token nextToken() {
if ( i>=subset.size() ) return Token.EOF_TOKEN;
return (Token)subset.get(i++);
}
public String getSourceName() { return null; }
});
ANTLRParser errorParser = new ANTLRParser(ns);
errorParser.setTreeAdaptor(this.adaptor);
errorParser.element_errors(re);
retval.tree = (GrammarAST)adaptor.errorNode(input, retval.start, input.LT(-1), re);
*/
} }
labeledElement
: id (ass=ASSIGN|ass=PLUS_ASSIGN)
( atom -> ^($ass id atom)
| block (op=ROOT|op=BANG)? -> {$op!=null}? ^($ass id ^($op block))
-> ^($ass id block)
/* /*
element_errors[RecognitionException origError] | {buildAST}? blockSet
options {backtrack=true;} {
@init { RecognitionException e =
int m = input.mark(); new v4ParserException("can't '"+
//state.backtracking++; input.LT(1).getText()+" "+input.LT(2).getText()+"'", input);
} reportError(missingSemi);
@after {
//state.backtracking--;
}
: ( DOC_COMMENT? ruleModifiers? id ARG_ACTION<ActionAST>? ruleReturns? rulePrequel* COLON
| exceptionGroup
)
{reportError(missingSemi); recover(input,null);}
;
catch [RecognitionException ignore] {
input.rewind(m);
input.consume(); // kill at least one token
reportError(origError);
BitSet followSet = computeErrorRecoverySet();
beginResync();
consumeUntil(input, followSet);
endResync();
} }
*/ */
)
labeledElement : id (ASSIGN^|PLUS_ASSIGN^) (atom|block) ; ;
// Tree specifying alt // Tree specifying alt
// Tree grammars need to have alts that describe a tree structure they // Tree grammars need to have alts that describe a tree structure they
@ -682,20 +665,19 @@ ebnf
: block : block
// And now we see if we have any of the optional suffixs and rewrite // And now we see if we have any of the optional suffixs and rewrite
// the AST for this rule accordingly // the AST for this rule accordingly
// ( blockSuffix -> ^(blockSuffix block)
( blockSuffixe -> ^(blockSuffixe block)
| -> block | -> block
) )
; ;
// The standard EBNF suffixes with additional components that make // The standard EBNF suffixes with additional components that make
// sense only to ANTLR, in the context of a grammar block. // sense only to ANTLR, in the context of a grammar block.
blockSuffixe blockSuffix
: ebnfSuffix // Standard EBNF : ebnfSuffix // Standard EBNF
// ANTLR Specific Suffixes // ANTLR Specific Suffixes
| ROOT | ROOT
| IMPLIES // We will change this to syn/sem pred in the next phase // | IMPLIES // We will change this to syn/sem pred in the next phase
| BANG | BANG
; ;
@ -720,7 +702,7 @@ atom: // Qualified reference delegate.rule. This must be
| ruleref | ruleref
| notSet (ROOT^|BANG^)? | notSet (ROOT^|BANG^)?
| // Wildcard '.' means any character in a lexer, any | // Wildcard '.' means any character in a lexer, any
// token in parser and any token or node in a tree parser // token in parser and any node or subtree in a tree parser
// Because the terminal rule is allowed to be the node // Because the terminal rule is allowed to be the node
// specification for the start of a tree rule, we must // specification for the start of a tree rule, we must
// later check that wildcard was not used for that. // later check that wildcard was not used for that.
@ -731,24 +713,34 @@ atom: // Qualified reference delegate.rule. This must be
// -------------------- // --------------------
// Inverted element set // Inverted element set
// //
// A set of characters (in a lexer) or terminal tokens, if a parser // A set of characters (in a lexer) or terminal tokens, if a parser,
// that are then used to create the inverse set of them. // that are then used to create the inverse set of them.
//
notSet notSet
: NOT terminal -> ^(NOT terminal) : NOT setElement -> ^(NOT ^(SET[$setElement.start,"SET"] setElement))
| NOT blockSet -> ^(NOT blockSet) | NOT blockSet -> ^(NOT blockSet)
; ;
blockSet blockSet
: LPAREN @init {
setElement (OR setElement)* Token t;
RPAREN boolean ebnf = false;
-> ^(BLOCK<BlockAST>[$LPAREN,"BLOCK"] setElement+ ) }
: LPAREN setElement (OR setElement)* RPAREN
/* {
t = input.LT(1);
ebnf = t!=null && (t.getType()==QUESTION || t.getType()==STAR || t.getType()==PLUS);
}
*/
-> ^(BLOCK<BlockAST>[$LPAREN,"BLOCK"] ^(ALT setElement)+ )
/*
-> {ebnf}? ^(BLOCK<BlockAST>[$LPAREN,"BLOCK"] ^(ALT ^(SET[$LPAREN,"SET"] setElement+ )))
-> ^(SET[$LPAREN,"SET"] setElement+ )
*/
; ;
setElement setElement
: range : TOKEN_REF<TerminalAST>
| terminal | STRING_LITERAL<TerminalAST>
; ;
// ------------- // -------------
@ -760,8 +752,6 @@ setElement
// //
block block
: LPAREN : LPAREN
// A new blocked altlist may have a set of options set sepcifically
// for it.
( optionsSpec? ra+=ruleAction* COLON )? ( optionsSpec? ra+=ruleAction* COLON )?
altList altList
RPAREN RPAREN

View File

@ -256,26 +256,34 @@ elements
element element
: labeledElement : labeledElement
| atom | atom
| ebnf | subrule
| ACTION | ACTION
| FORCED_ACTION | FORCED_ACTION
| SEMPRED | SEMPRED
| GATED_SEMPRED | GATED_SEMPRED
| treeSpec | treeSpec
| ^(ROOT astOperand)
| ^(BANG astOperand)
| ^(NOT blockSet)
| ^(NOT block)
;
astOperand
: atom
| ^(NOT blockSet)
| ^(NOT block)
; ;
labeledElement labeledElement
: ^(ASSIGN ID atom) : ^((ASSIGN|PLUS_ASSIGN) ID element)
| ^(ASSIGN ID block)
| ^(PLUS_ASSIGN ID atom)
| ^(PLUS_ASSIGN ID block)
; ;
treeSpec treeSpec
: ^(TREE_BEGIN element+) : ^(TREE_BEGIN element+)
; ;
ebnf: ^(blockSuffix block) subrule
: ^(blockSuffix block)
| block | block
; ;
@ -292,33 +300,23 @@ ebnfSuffix
| POSITIVE_CLOSURE | POSITIVE_CLOSURE
; ;
atom: ^(ROOT notSet) atom: range
| ^(BANG notSet)
| notSet
| ^(ROOT terminal)
| ^(BANG terminal)
| range
| ^(DOT ID terminal) | ^(DOT ID terminal)
| ^(DOT ID ruleref) | ^(DOT ID ruleref)
| ^(WILDCARD elementOptions) | ^(WILDCARD elementOptions)
| WILDCARD | WILDCARD
| terminal | terminal
| blockSet
| ruleref | ruleref
; ;
notSet
: ^(NOT setElement)
| ^(NOT blockSet)
;
blockSet blockSet
: ^(BLOCK setElement+) : ^(SET setElement+)
; ;
setElement setElement
: STRING_LITERAL : STRING_LITERAL
| TOKEN_REF | TOKEN_REF
| ^(RANGE STRING_LITERAL STRING_LITERAL)
; ;
block block
@ -326,9 +324,7 @@ block
; ;
ruleref ruleref
: ^(ROOT ^(RULE_REF ARG_ACTION?)) : ^(RULE_REF ARG_ACTION?)
| ^(BANG ^(RULE_REF ARG_ACTION?))
| ^(RULE_REF ARG_ACTION?)
; ;
range range

View File

@ -92,19 +92,25 @@ alternative returns [ATNFactory.Handle p]
element returns [ATNFactory.Handle p] element returns [ATNFactory.Handle p]
: labeledElement {$p = $labeledElement.p;} : labeledElement {$p = $labeledElement.p;}
| atom {$p = $atom.p;} | atom {$p = $atom.p;}
| ebnf {$p = $ebnf.p;} | subrule {$p = $subrule.p;}
| ACTION {$p = factory.action((ActionAST)$ACTION);} | ACTION {$p = factory.action((ActionAST)$ACTION);}
| FORCED_ACTION {$p = factory.action((ActionAST)$FORCED_ACTION);} | FORCED_ACTION {$p = factory.action((ActionAST)$FORCED_ACTION);}
| SEMPRED {$p = factory.sempred((PredAST)$SEMPRED);} | SEMPRED {$p = factory.sempred((PredAST)$SEMPRED);}
| GATED_SEMPRED {$p = factory.gated_sempred($GATED_SEMPRED);} | GATED_SEMPRED {$p = factory.gated_sempred($GATED_SEMPRED);}
| treeSpec {$p = $treeSpec.p;} | treeSpec {$p = $treeSpec.p;}
| ^(ROOT a=astOperand) {$p = $a.p;}
| ^(BANG a=astOperand) {$p = $a.p;}
| ^(NOT b=blockSet[true]) {$p = $b.p;}
;
astOperand returns [ATNFactory.Handle p]
: atom {$p = $atom.p;}
| ^(NOT blockSet[true]) {$p = $blockSet.p;}
; ;
labeledElement returns [ATNFactory.Handle p] labeledElement returns [ATNFactory.Handle p]
: ^(ASSIGN ID atom) {$p = factory.label($atom.p);} : ^(ASSIGN ID element) {$p = factory.label($element.p);}
| ^(ASSIGN ID block[null]) {$p = factory.label($block.p);} | ^(PLUS_ASSIGN ID element) {$p = factory.listLabel($element.p);}
| ^(PLUS_ASSIGN ID atom) {$p = factory.listLabel($atom.p);}
| ^(PLUS_ASSIGN ID block[null]) {$p = factory.listLabel($block.p);}
; ;
treeSpec returns [ATNFactory.Handle p] treeSpec returns [ATNFactory.Handle p]
@ -112,7 +118,7 @@ treeSpec returns [ATNFactory.Handle p]
: ^(TREE_BEGIN (e=element {els.add($e.p);})+) {$p = factory.tree(els);} : ^(TREE_BEGIN (e=element {els.add($e.p);})+) {$p = factory.tree(els);}
; ;
ebnf returns [ATNFactory.Handle p] subrule returns [ATNFactory.Handle p]
: ^(astBlockSuffix block[null]) {$p = $block.p;} : ^(astBlockSuffix block[null]) {$p = $block.p;}
| ^(OPTIONAL block[$start]) {$p = $block.p;} | ^(OPTIONAL block[$start]) {$p = $block.p;}
| ^(CLOSURE block[$start]) {$p = $block.p;} | ^(CLOSURE block[$start]) {$p = $block.p;}
@ -120,6 +126,11 @@ ebnf returns [ATNFactory.Handle p]
| block[null] {$p = $block.p;} | block[null] {$p = $block.p;}
; ;
blockSet[boolean invert] returns [ATNFactory.Handle p]
@init {List<GrammarAST> alts = new ArrayList<GrammarAST>();}
: ^(SET (atom {alts.add($atom.start);})+) {$p = factory.set($start, alts, $invert);}
;
astBlockSuffix astBlockSuffix
: ROOT : ROOT
| IMPLIES | IMPLIES
@ -127,40 +138,18 @@ astBlockSuffix
; ;
atom returns [ATNFactory.Handle p] atom returns [ATNFactory.Handle p]
: ^(ROOT range) {$p = $range.p;} : range {$p = $range.p;}
| ^(BANG range) {$p = $range.p;}
| ^(ROOT notSet) {$p = $notSet.p;}
| ^(BANG notSet) {$p = $notSet.p;}
| notSet {$p = $notSet.p;}
| range {$p = $range.p;}
| ^(DOT ID terminal) {$p = $terminal.p;} | ^(DOT ID terminal) {$p = $terminal.p;}
| ^(DOT ID ruleref) {$p = $ruleref.p;} | ^(DOT ID ruleref) {$p = $ruleref.p;}
| ^(WILDCARD .) {$p = factory.wildcard($start);} | ^(WILDCARD .) {$p = factory.wildcard($start);}
| WILDCARD {$p = factory.wildcard($start);} | WILDCARD {$p = factory.wildcard($start);}
| blockSet[false] {$p = $blockSet.p;}
| terminal {$p = $terminal.p;} | terminal {$p = $terminal.p;}
| ruleref {$p = $ruleref.p;} | ruleref {$p = $ruleref.p;}
; ;
notSet returns [ATNFactory.Handle p]
: ^(NOT setElement) {$p = factory.not($NOT);}
| ^(NOT blockSet) {$p = factory.notBlock($NOT, $blockSet.alts);}
;
blockSet returns [List<GrammarAST> alts]
@init {$alts = new ArrayList<GrammarAST>();}
: ^(BLOCK (t=setElement {$alts.add($t.start);})+)
;
setElement
: STRING_LITERAL
| TOKEN_REF
| ^(RANGE STRING_LITERAL STRING_LITERAL)
;
ruleref returns [ATNFactory.Handle p] ruleref returns [ATNFactory.Handle p]
: ^(ROOT ^(RULE_REF ARG_ACTION?)) {$p = factory.ruleRef($RULE_REF);} : ^(RULE_REF ARG_ACTION?) {$p = factory.ruleRef($RULE_REF);}
| ^(BANG ^(RULE_REF ARG_ACTION?)) {$p = factory.ruleRef($RULE_REF);}
| ^(RULE_REF ARG_ACTION?) {$p = factory.ruleRef($RULE_REF);}
; ;
range returns [ATNFactory.Handle p] range returns [ATNFactory.Handle p]
@ -173,6 +162,4 @@ terminal returns [ATNFactory.Handle p]
| ^(TOKEN_REF ARG_ACTION .) {$p = factory.tokenRef((TerminalAST)$start);} | ^(TOKEN_REF ARG_ACTION .) {$p = factory.tokenRef((TerminalAST)$start);}
| ^(TOKEN_REF .) {$p = factory.tokenRef((TerminalAST)$start);} | ^(TOKEN_REF .) {$p = factory.tokenRef((TerminalAST)$start);}
| TOKEN_REF {$p = factory.tokenRef((TerminalAST)$start);} | TOKEN_REF {$p = factory.tokenRef((TerminalAST)$start);}
| ^(ROOT t=terminal) {$p = $t.p;}
| ^(BANG t=terminal) {$p = $t.p;}
; ;

View File

@ -0,0 +1,68 @@
tree grammar BlockSetTransformer;
options {
language = Java;
tokenVocab = ANTLRParser;
ASTLabelType = GrammarAST;
output = AST;
filter = true;
}
@header {
package org.antlr.v4.parse;
import org.antlr.v4.misc.Utils;
import org.antlr.v4.tool.*;
import java.util.List;
import java.util.ArrayList;
import org.antlr.v4.runtime.misc.IntervalSet;
}
@members {
public String currentRuleName;
public GrammarAST currentAlt;
}
topdown
: ^(RULE ID {currentRuleName=$ID.text;} .+)
| setAlt
| ebnfBlockSet
| blockSet
;
setAlt
: {inContext("RULE BLOCK")}? ( ALT | ALT_REWRITE )
{currentAlt = (AltAST)$start;}
;
// (BLOCK (ALT (+ (BLOCK (ALT INT) (ALT ID)))))
ebnfBlockSet
: ^(ebnfSuffix blockSet) -> ^(ebnfSuffix ^(BLOCK<BlockAST> ^(ALT blockSet)))
;
ebnfSuffix
@after {$tree = (GrammarAST)adaptor.dupNode($start);}
: OPTIONAL
| CLOSURE
| POSITIVE_CLOSURE
;
blockSet
@init {
if ( currentAlt!=null && currentAlt.getType()==ANTLRParser.ALT_REWRITE ) {
IntervalSet s = new IntervalSet();
s.add(RULE_REF);
s.add(STRING_LITERAL);
s.add(TOKEN_REF);
List<GrammarAST> elems = currentAlt.getNodesWithType(s);
System.out.println("stuff in rewrite: "+elems);
}
}
: {Character.isLowerCase(currentRuleName.charAt(0)) &&
!inContext("ALT_REWRITE ...") && !inContext("RULE")}?
^(BLOCK ( ^(ALT setElement) )+) -> ^(SET[$BLOCK.token, "SET"] setElement+)
;
setElement
@after {$tree = new TerminalAST($start);}
: STRING_LITERAL
| TOKEN_REF
;

View File

@ -71,7 +71,9 @@ public class SemanticPipeline {
ASTVerifier walker = new ASTVerifier(nodes); ASTVerifier walker = new ASTVerifier(nodes);
try {walker.grammarSpec();} try {walker.grammarSpec();}
catch (RecognitionException re) { catch (RecognitionException re) {
ErrorManager.fatalInternalError("bad grammar AST structure", re); ErrorManager.fatalInternalError("bad grammar AST structure: "+
g.ast.toStringTree(),
re);
} }
// DO BASIC / EASY SEMANTIC CHECKS // DO BASIC / EASY SEMANTIC CHECKS

View File

@ -190,6 +190,9 @@ public class Grammar implements AttributeResolver {
this.ast = (GrammarRootAST)r.getTree(); this.ast = (GrammarRootAST)r.getTree();
this.ast.hasErrors = p.getNumberOfSyntaxErrors()>0; this.ast.hasErrors = p.getNumberOfSyntaxErrors()>0;
this.name = ((GrammarAST)ast.getChild(0)).getText(); this.name = ((GrammarAST)ast.getChild(0)).getText();
GrammarTransformPipeline transform = new GrammarTransformPipeline(ast);
transform.process();
} }
initTokenSymbolTables(); initTokenSymbolTables();
} }

View File

@ -56,6 +56,7 @@ public class GrammarAST extends CommonTree {
token.setInputStream(t.getInputStream()); token.setInputStream(t.getInputStream());
token.setLine(t.getLine()); token.setLine(t.getLine());
token.setCharPositionInLine(t.getCharPositionInLine()); token.setCharPositionInLine(t.getCharPositionInLine());
token.setTokenIndex(t.getTokenIndex());
} }
public List<GrammarAST> getNodesWithType(int ttype) { public List<GrammarAST> getNodesWithType(int ttype) {

View File

@ -0,0 +1,54 @@
/*
[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.tool;
import org.antlr.v4.parse.*;
/** Handle left-recursion and block-set transforms */
public class GrammarTransformPipeline {
public GrammarAST ast;
public GrammarTransformPipeline(GrammarAST ast) {
this.ast = ast;
}
public void process() {
if ( ast==null ) return;
org.antlr.runtime.tree.CommonTreeNodeStream nodes =
new org.antlr.runtime.tree.CommonTreeNodeStream(ast);
GrammarASTAdaptor adaptor = new GrammarASTAdaptor();
BlockSetTransformer transformer = new BlockSetTransformer(nodes);
transformer.setTreeAdaptor(adaptor);
System.out.println("before: "+ast.toStringTree());
transformer.downup(ast);
System.out.println("after: "+ast.toStringTree());
}
}

View File

@ -65,7 +65,7 @@ public class TestASTOps extends BaseTest {
String grammar = String grammar =
"grammar foo;\n" + "grammar foo;\n" +
"options {output=AST;}\n" + "options {output=AST;}\n" +
"a : (ID|INT) ;\n" + "a : (ID{;}|INT) ;\n" +
"ID : 'a'..'z'+ ;\n" + "ID : 'a'..'z'+ ;\n" +
"INT : '0'..'9'+;\n" + "INT : '0'..'9'+;\n" +
"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
@ -496,6 +496,7 @@ public class TestASTOps extends BaseTest {
"blort : '+' ;\n" + "blort : '+' ;\n" +
"ID : 'a'..'z'+ ;\n" + "ID : 'a'..'z'+ ;\n" +
"INT : '0'..'9'+;\n" + "INT : '0'..'9'+;\n" +
"PLUS : '+';\n" +
"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
String found = execParser("T.g", grammar, "TParser", "TLexer", String found = execParser("T.g", grammar, "TParser", "TLexer",
"a", "3+4+5", debug); "a", "3+4+5", debug);

View File

@ -123,6 +123,12 @@ rule:
block: block:
"( ^(A B) | ^(b C) )" -> (BLOCK (ALT ("^(" A B)) (ALT ("^(" b C))) "( ^(A B) | ^(b C) )" -> (BLOCK (ALT ("^(" A B)) (ALT ("^(" b C)))
ebnf:
"(A|B)" -> (SET A B)
"(A|B)?" -> ("?" (BLOCK (ALT (SET A B))))
"(A|B)*" -> ("*" (BLOCK (ALT (SET A B))))
"(A|B)+" -> ("+" (BLOCK (ALT (SET A B))))
alternative: alternative:
"x+=ID* -> $x*" -> "x+=ID* -> $x*" ->
(ALT_REWRITE (ALT_REWRITE
@ -189,6 +195,7 @@ alternative:
(-> EPSILON)) (-> EPSILON))
element: element:
"~A" -> (~ (SET A))
"b+" -> (+ (BLOCK (ALT b))) "b+" -> (+ (BLOCK (ALT b)))
"(b)+" -> (+ (BLOCK (ALT b))) "(b)+" -> (+ (BLOCK (ALT b)))
"b?" -> (? (BLOCK (ALT b))) "b?" -> (? (BLOCK (ALT b)))
@ -203,10 +210,11 @@ element:
"x=ID?" -> (? (BLOCK (ALT (= x ID)))) "x=ID?" -> (? (BLOCK (ALT (= x ID))))
"x=ID*" -> (* (BLOCK (ALT (= x ID)))) "x=ID*" -> (* (BLOCK (ALT (= x ID))))
"x=b" -> (= x b) "x=b" -> (= x b)
"x=(A|B)" -> (= x (BLOCK (ALT A) (ALT B))) "x=(A|B)" -> (= x (SET A B))
"x=~(A|B)" -> (= x (~ (BLOCK A B))) "x=(A|B)^" -> (= x (^ (SET A B)))
"x+=~(A|B)" -> (+= x (~ (BLOCK A B))) "x=~(A|B)" -> (= x (~ (SET A B)))
"x+=~(A|B)+"-> (+ (BLOCK (ALT (+= x (~ (BLOCK A B)))))) "x+=~(A|B)" -> (+= x (~ (SET A B)))
"x+=~(A|B)+"-> (+ (BLOCK (ALT (+= x (~ (BLOCK (ALT (SET A B))))))))
"x=b+" -> (+ (BLOCK (ALT (= x b)))) "x=b+" -> (+ (BLOCK (ALT (= x b))))
"x+=ID*" -> (* (BLOCK (ALT (+= x ID)))) "x+=ID*" -> (* (BLOCK (ALT (+= x ID))))
"x+='int'*" -> (* (BLOCK (ALT (+= x 'int')))) "x+='int'*" -> (* (BLOCK (ALT (+= x 'int'))))

View File

@ -99,327 +99,373 @@ public class TestASTStructure extends org.antlr.v4.gunit.gUnitBase {
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(BLOCK (ALT (^( A B)) (ALT (^( b C)))"; Object expecting = "(BLOCK (ALT (^( A B)) (ALT (^( b C)))";
assertEquals("testing rule block", expecting, actual); assertEquals("testing rule block", expecting, actual);
} @Test public void test_alternative1() throws Exception { } @Test public void test_ebnf1() throws Exception {
// gunit test on line 127 // gunit test on line 127
RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "x+=ID* -> $x*", 127); RuleReturnScope rstruct = (RuleReturnScope)execParser("ebnf", "(A|B)", 127);
Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(SET A B)";
assertEquals("testing rule ebnf", expecting, actual);
}
@Test public void test_ebnf2() throws Exception {
// gunit test on line 128
RuleReturnScope rstruct = (RuleReturnScope)execParser("ebnf", "(A|B)?", 128);
Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(? (BLOCK (ALT (SET A B))))";
assertEquals("testing rule ebnf", expecting, actual);
}
@Test public void test_ebnf3() throws Exception {
// gunit test on line 129
RuleReturnScope rstruct = (RuleReturnScope)execParser("ebnf", "(A|B)*", 129);
Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(* (BLOCK (ALT (SET A B))))";
assertEquals("testing rule ebnf", expecting, actual);
}
@Test public void test_ebnf4() throws Exception {
// gunit test on line 130
RuleReturnScope rstruct = (RuleReturnScope)execParser("ebnf", "(A|B)+", 130);
Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(+ (BLOCK (ALT (SET A B))))";
assertEquals("testing rule ebnf", expecting, actual);
} @Test public void test_alternative1() throws Exception {
// gunit test on line 133
RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "x+=ID* -> $x*", 133);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(ALT_REWRITE (ALT (* (BLOCK (ALT (+= x ID))))) (-> (ALT (* (REWRITE_BLOCK (ALT x))))))"; Object expecting = "(ALT_REWRITE (ALT (* (BLOCK (ALT (+= x ID))))) (-> (ALT (* (REWRITE_BLOCK (ALT x))))))";
assertEquals("testing rule alternative", expecting, actual); assertEquals("testing rule alternative", expecting, actual);
} }
@Test public void test_alternative2() throws Exception { @Test public void test_alternative2() throws Exception {
// gunit test on line 132 // gunit test on line 138
RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "A -> ...", 132); RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "A -> ...", 138);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(ALT_REWRITE (ALT A) (-> ...))"; Object expecting = "(ALT_REWRITE (ALT A) (-> ...))";
assertEquals("testing rule alternative", expecting, actual); assertEquals("testing rule alternative", expecting, actual);
} }
@Test public void test_alternative3() throws Exception { @Test public void test_alternative3() throws Exception {
// gunit test on line 133 // gunit test on line 139
RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "A -> ", 133); RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "A -> ", 139);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(ALT_REWRITE (ALT A) (-> EPSILON))"; Object expecting = "(ALT_REWRITE (ALT A) (-> EPSILON))";
assertEquals("testing rule alternative", expecting, actual); assertEquals("testing rule alternative", expecting, actual);
} }
@Test public void test_alternative4() throws Exception { @Test public void test_alternative4() throws Exception {
// gunit test on line 135 // gunit test on line 141
RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "A -> foo(a={x}, b={y})", 135); RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "A -> foo(a={x}, b={y})", 141);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(ALT_REWRITE (ALT A) (-> (TEMPLATE foo (ARGLIST (= a {x}) (= b {y})))))"; Object expecting = "(ALT_REWRITE (ALT A) (-> (TEMPLATE foo (ARGLIST (= a {x}) (= b {y})))))";
assertEquals("testing rule alternative", expecting, actual); assertEquals("testing rule alternative", expecting, actual);
} }
@Test public void test_alternative5() throws Exception { @Test public void test_alternative5() throws Exception {
// gunit test on line 140 // gunit test on line 146
RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "A -> template(a={x}, b={y}) <<ick>>", 140); RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "A -> template(a={x}, b={y}) <<ick>>", 146);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(ALT_REWRITE (ALT A) (-> (TEMPLATE (ARGLIST (= a {x}) (= b {y})) <<ick>>)))"; Object expecting = "(ALT_REWRITE (ALT A) (-> (TEMPLATE (ARGLIST (= a {x}) (= b {y})) <<ick>>)))";
assertEquals("testing rule alternative", expecting, actual); assertEquals("testing rule alternative", expecting, actual);
} }
@Test public void test_alternative6() throws Exception { @Test public void test_alternative6() throws Exception {
// gunit test on line 145 // gunit test on line 151
RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "A -> ({name})()", 145); RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "A -> ({name})()", 151);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(ALT_REWRITE (ALT A) (-> (TEMPLATE {name})))"; Object expecting = "(ALT_REWRITE (ALT A) (-> (TEMPLATE {name})))";
assertEquals("testing rule alternative", expecting, actual); assertEquals("testing rule alternative", expecting, actual);
} }
@Test public void test_alternative7() throws Exception { @Test public void test_alternative7() throws Exception {
// gunit test on line 147 // gunit test on line 153
RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "A -> {expr}", 147); RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "A -> {expr}", 153);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(ALT_REWRITE (ALT A) (-> (ALT {expr})))"; Object expecting = "(ALT_REWRITE (ALT A) (-> (ALT {expr})))";
assertEquals("testing rule alternative", expecting, actual); assertEquals("testing rule alternative", expecting, actual);
} }
@Test public void test_alternative8() throws Exception { @Test public void test_alternative8() throws Exception {
// gunit test on line 149 // gunit test on line 155
RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "\n A -> {p1}? {e1}\n -> {e2}\n ->\n ", 149); RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "\n A -> {p1}? {e1}\n -> {e2}\n ->\n ", 155);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(ALT_REWRITE (ALT A) (-> {p1}? (ALT {e1})) (-> (ALT {e2})))"; Object expecting = "(ALT_REWRITE (ALT A) (-> {p1}? (ALT {e1})) (-> (ALT {e2})))";
assertEquals("testing rule alternative", expecting, actual); assertEquals("testing rule alternative", expecting, actual);
} }
@Test public void test_alternative9() throws Exception { @Test public void test_alternative9() throws Exception {
// gunit test on line 161 // gunit test on line 167
RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "A -> A", 161); RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "A -> A", 167);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(ALT_REWRITE (ALT A) (-> (ALT A)))"; Object expecting = "(ALT_REWRITE (ALT A) (-> (ALT A)))";
assertEquals("testing rule alternative", expecting, actual); assertEquals("testing rule alternative", expecting, actual);
} }
@Test public void test_alternative10() throws Exception { @Test public void test_alternative10() throws Exception {
// gunit test on line 163 // gunit test on line 169
RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "a -> a", 163); RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "a -> a", 169);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(ALT_REWRITE (ALT a) (-> (ALT a)))"; Object expecting = "(ALT_REWRITE (ALT a) (-> (ALT a)))";
assertEquals("testing rule alternative", expecting, actual); assertEquals("testing rule alternative", expecting, actual);
} }
@Test public void test_alternative11() throws Exception { @Test public void test_alternative11() throws Exception {
// gunit test on line 165 // gunit test on line 171
RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "a A X? Y* -> A a ^(TOP X)? Y*", 165); RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "a A X? Y* -> A a ^(TOP X)? Y*", 171);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(ALT_REWRITE (ALT a A (? (BLOCK (ALT X))) (* (BLOCK (ALT Y)))) (-> (ALT A a (? (REWRITE_BLOCK (ALT (^( TOP X)))) (* (REWRITE_BLOCK (ALT Y))))))"; Object expecting = "(ALT_REWRITE (ALT a A (? (BLOCK (ALT X))) (* (BLOCK (ALT Y)))) (-> (ALT A a (? (REWRITE_BLOCK (ALT (^( TOP X)))) (* (REWRITE_BLOCK (ALT Y))))))";
assertEquals("testing rule alternative", expecting, actual); assertEquals("testing rule alternative", expecting, actual);
} }
@Test public void test_alternative12() throws Exception { @Test public void test_alternative12() throws Exception {
// gunit test on line 173 // gunit test on line 179
RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "A -> A[33]", 173); RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "A -> A[33]", 179);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(ALT_REWRITE (ALT A) (-> (ALT (A 33))))"; Object expecting = "(ALT_REWRITE (ALT A) (-> (ALT (A 33))))";
assertEquals("testing rule alternative", expecting, actual); assertEquals("testing rule alternative", expecting, actual);
} }
@Test public void test_alternative13() throws Exception { @Test public void test_alternative13() throws Exception {
// gunit test on line 175 // gunit test on line 181
RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "A -> 'int' ^(A A)*", 175); RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "A -> 'int' ^(A A)*", 181);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(ALT_REWRITE (ALT A) (-> (ALT 'int' (* (REWRITE_BLOCK (ALT (^( A A)))))))"; Object expecting = "(ALT_REWRITE (ALT A) (-> (ALT 'int' (* (REWRITE_BLOCK (ALT (^( A A)))))))";
assertEquals("testing rule alternative", expecting, actual); assertEquals("testing rule alternative", expecting, actual);
} }
@Test public void test_alternative14() throws Exception { @Test public void test_alternative14() throws Exception {
// gunit test on line 180 // gunit test on line 186
RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "\n A -> {p1}? A\n -> {p2}? B\n ->\n ", 180); RuleReturnScope rstruct = (RuleReturnScope)execParser("alternative", "\n A -> {p1}? A\n -> {p2}? B\n ->\n ", 186);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(ALT_REWRITE (ALT A) (-> {p1}? (ALT A)) (-> {p2}? (ALT B)) (-> EPSILON))"; Object expecting = "(ALT_REWRITE (ALT A) (-> {p1}? (ALT A)) (-> {p2}? (ALT B)) (-> EPSILON))";
assertEquals("testing rule alternative", expecting, actual); assertEquals("testing rule alternative", expecting, actual);
} @Test public void test_element1() throws Exception { } @Test public void test_element1() throws Exception {
// gunit test on line 192 // gunit test on line 198
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "b+", 192); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "~A", 198);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(+ (BLOCK (ALT b)))"; Object expecting = "(~ (SET A))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element2() throws Exception { @Test public void test_element2() throws Exception {
// gunit test on line 193 // gunit test on line 199
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "(b)+", 193); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "b+", 199);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(+ (BLOCK (ALT b)))"; Object expecting = "(+ (BLOCK (ALT b)))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element3() throws Exception { @Test public void test_element3() throws Exception {
// gunit test on line 194 // gunit test on line 200
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "b?", 194); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "(b)+", 200);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(? (BLOCK (ALT b)))"; Object expecting = "(+ (BLOCK (ALT b)))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element4() throws Exception { @Test public void test_element4() throws Exception {
// gunit test on line 195 // gunit test on line 201
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "(b)?", 195); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "b?", 201);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(? (BLOCK (ALT b)))"; Object expecting = "(? (BLOCK (ALT b)))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element5() throws Exception { @Test public void test_element5() throws Exception {
// gunit test on line 196 // gunit test on line 202
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "(b)*", 196); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "(b)?", 202);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(* (BLOCK (ALT b)))"; Object expecting = "(? (BLOCK (ALT b)))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element6() throws Exception { @Test public void test_element6() throws Exception {
// gunit test on line 197 // gunit test on line 203
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "b*", 197); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "(b)*", 203);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(* (BLOCK (ALT b)))"; Object expecting = "(* (BLOCK (ALT b)))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element7() throws Exception { @Test public void test_element7() throws Exception {
// gunit test on line 198 // gunit test on line 204
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "'while'*", 198); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "b*", 204);
Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(* (BLOCK (ALT b)))";
assertEquals("testing rule element", expecting, actual);
}
@Test public void test_element8() throws Exception {
// gunit test on line 205
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "'while'*", 205);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(* (BLOCK (ALT 'while')))"; Object expecting = "(* (BLOCK (ALT 'while')))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element8() throws Exception { @Test public void test_element9() throws Exception {
// gunit test on line 199 // gunit test on line 206
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "'a'+", 199); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "'a'+", 206);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(+ (BLOCK (ALT 'a')))"; Object expecting = "(+ (BLOCK (ALT 'a')))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element9() throws Exception { @Test public void test_element10() throws Exception {
// gunit test on line 200 // gunit test on line 207
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "a[3]", 200); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "a[3]", 207);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(a 3)"; Object expecting = "(a 3)";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element10() throws Exception { @Test public void test_element11() throws Exception {
// gunit test on line 201 // gunit test on line 208
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "'a'..'z'+", 201); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "'a'..'z'+", 208);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(+ (BLOCK (ALT (.. 'a' 'z'))))"; Object expecting = "(+ (BLOCK (ALT (.. 'a' 'z'))))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element11() throws Exception { @Test public void test_element12() throws Exception {
// gunit test on line 202 // gunit test on line 209
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x=ID", 202); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x=ID", 209);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(= x ID)"; Object expecting = "(= x ID)";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element12() throws Exception { @Test public void test_element13() throws Exception {
// gunit test on line 203 // gunit test on line 210
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x=ID?", 203); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x=ID?", 210);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(? (BLOCK (ALT (= x ID))))"; Object expecting = "(? (BLOCK (ALT (= x ID))))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element13() throws Exception { @Test public void test_element14() throws Exception {
// gunit test on line 204 // gunit test on line 211
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x=ID*", 204); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x=ID*", 211);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(* (BLOCK (ALT (= x ID))))"; Object expecting = "(* (BLOCK (ALT (= x ID))))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element14() throws Exception { @Test public void test_element15() throws Exception {
// gunit test on line 205 // gunit test on line 212
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x=b", 205); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x=b", 212);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(= x b)"; Object expecting = "(= x b)";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element15() throws Exception {
// gunit test on line 206
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x=(A|B)", 206);
Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(= x (BLOCK (ALT A) (ALT B)))";
assertEquals("testing rule element", expecting, actual);
}
@Test public void test_element16() throws Exception { @Test public void test_element16() throws Exception {
// gunit test on line 207 // gunit test on line 213
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x=~(A|B)", 207); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x=(A|B)", 213);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(= x (~ (BLOCK A B)))"; Object expecting = "(= x (SET A B))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element17() throws Exception { @Test public void test_element17() throws Exception {
// gunit test on line 208 // gunit test on line 214
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x+=~(A|B)", 208); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x=(A|B)^", 214);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(+= x (~ (BLOCK A B)))"; Object expecting = "(= x (^ (SET A B)))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element18() throws Exception { @Test public void test_element18() throws Exception {
// gunit test on line 209 // gunit test on line 215
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x+=~(A|B)+", 209); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x=~(A|B)", 215);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(+ (BLOCK (ALT (+= x (~ (BLOCK A B))))))"; Object expecting = "(= x (~ (SET A B)))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element19() throws Exception { @Test public void test_element19() throws Exception {
// gunit test on line 210 // gunit test on line 216
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x=b+", 210); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x+=~(A|B)", 216);
Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(+= x (~ (SET A B)))";
assertEquals("testing rule element", expecting, actual);
}
@Test public void test_element20() throws Exception {
// gunit test on line 217
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x+=~(A|B)+", 217);
Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(+ (BLOCK (ALT (+= x (~ (BLOCK (ALT (SET A B))))))))";
assertEquals("testing rule element", expecting, actual);
}
@Test public void test_element21() throws Exception {
// gunit test on line 218
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x=b+", 218);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(+ (BLOCK (ALT (= x b))))"; Object expecting = "(+ (BLOCK (ALT (= x b))))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element20() throws Exception { @Test public void test_element22() throws Exception {
// gunit test on line 211 // gunit test on line 219
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x+=ID*", 211); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x+=ID*", 219);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(* (BLOCK (ALT (+= x ID))))"; Object expecting = "(* (BLOCK (ALT (+= x ID))))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element21() throws Exception { @Test public void test_element23() throws Exception {
// gunit test on line 212 // gunit test on line 220
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x+='int'*", 212); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x+='int'*", 220);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(* (BLOCK (ALT (+= x 'int'))))"; Object expecting = "(* (BLOCK (ALT (+= x 'int'))))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element22() throws Exception { @Test public void test_element24() throws Exception {
// gunit test on line 213 // gunit test on line 221
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x+=b+", 213); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x+=b+", 221);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(+ (BLOCK (ALT (+= x b))))"; Object expecting = "(+ (BLOCK (ALT (+= x b))))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element23() throws Exception { @Test public void test_element25() throws Exception {
// gunit test on line 214 // gunit test on line 222
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "('*'^)*", 214); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "('*'^)*", 222);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(* (BLOCK (ALT (^ '*'))))"; Object expecting = "(* (BLOCK (ALT (^ '*'))))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element24() throws Exception { @Test public void test_element26() throws Exception {
// gunit test on line 215 // gunit test on line 223
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "({blort} 'x')*", 215); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "({blort} 'x')*", 223);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(* (BLOCK (ALT {blort} 'x')))"; Object expecting = "(* (BLOCK (ALT {blort} 'x')))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element25() throws Exception { @Test public void test_element27() throws Exception {
// gunit test on line 216 // gunit test on line 224
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "A!", 216); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "A!", 224);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(! A)"; Object expecting = "(! A)";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element26() throws Exception { @Test public void test_element28() throws Exception {
// gunit test on line 217 // gunit test on line 225
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "A^", 217); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "A^", 225);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(^ A)"; Object expecting = "(^ A)";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);
} }
@Test public void test_element27() throws Exception { @Test public void test_element29() throws Exception {
// gunit test on line 218 // gunit test on line 226
RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x=A^", 218); RuleReturnScope rstruct = (RuleReturnScope)execParser("element", "x=A^", 226);
Object actual = ((Tree)rstruct.getTree()).toStringTree(); Object actual = ((Tree)rstruct.getTree()).toStringTree();
Object expecting = "(= x (^ A))"; Object expecting = "(= x (^ A))";
assertEquals("testing rule element", expecting, actual); assertEquals("testing rule element", expecting, actual);

View File

@ -54,6 +54,23 @@ public class TestATNConstruction extends BaseTest {
checkRule(g, "a", expecting); checkRule(g, "a", expecting);
} }
@Test public void testSetAorB() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : A | B ;");
String expecting =
"RuleStart_a_0->BlockStart_6\n" +
"BlockStart_6->s2\n" +
"BlockStart_6->s4\n" +
"s2-A->s3\n" +
"s4-B->s5\n" +
"s3->BlockEnd_7\n" +
"s5->BlockEnd_7\n" +
"BlockEnd_7->RuleStop_a_1\n" +
"RuleStop_a_1-EOF->s8\n";
checkRule(g, "a", expecting);
}
@Test public void testRange() throws Exception { @Test public void testRange() throws Exception {
LexerGrammar g = new LexerGrammar( LexerGrammar g = new LexerGrammar(
"lexer grammar P;\n"+ "lexer grammar P;\n"+
@ -195,20 +212,37 @@ public class TestATNConstruction extends BaseTest {
} }
@Test public void testAorBoptional() throws Exception { @Test public void testAorBoptional() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : (A{;}|B)?;");
String expecting =
"RuleStart_a_0->BlockStart_8\n" +
"BlockStart_8->s2\n" +
"BlockStart_8->s6\n" +
"BlockStart_8->BlockEnd_9\n" +
"s2-A->s3\n" +
"s6-B->s7\n" +
"BlockEnd_9->RuleStop_a_1\n" +
"s3->s4\n" +
"s7->BlockEnd_9\n" +
"RuleStop_a_1-EOF->s10\n" +
"s4-action_0:-1->s5\n" +
"s5->BlockEnd_9\n";
checkRule(g, "a", expecting);
}
@Test public void testSetAorBoptional() throws Exception {
Grammar g = new Grammar( Grammar g = new Grammar(
"parser grammar P;\n"+ "parser grammar P;\n"+
"a : (A|B)?;"); "a : (A|B)?;");
String expecting = String expecting =
"RuleStart_a_0->BlockStart_6\n" + "RuleStart_a_0->BlockStart_8\n" +
"BlockStart_6->s2\n" + "BlockStart_8->s6\n" +
"BlockStart_6->s4\n" + "BlockStart_8->BlockEnd_9\n" +
"BlockStart_6->BlockEnd_7\n" + "s6-{3..4}->s7\n" +
"s2-A->s3\n" + "BlockEnd_9->RuleStop_a_1\n" +
"s4-B->s5\n" + "s7->BlockEnd_9\n" +
"BlockEnd_7->RuleStop_a_1\n" + "RuleStop_a_1-EOF->s10\n";
"s3->BlockEnd_7\n" +
"s5->BlockEnd_7\n" +
"RuleStop_a_1-EOF->s8\n";
checkRule(g, "a", expecting); checkRule(g, "a", expecting);
} }
@ -217,14 +251,9 @@ public class TestATNConstruction extends BaseTest {
"parser grammar P;\n"+ "parser grammar P;\n"+
"a : (A | B) C;"); "a : (A | B) C;");
String expecting = String expecting =
"RuleStart_a_0->BlockStart_6\n" + "RuleStart_a_0->s6\n" +
"BlockStart_6->s2\n" + "s6-{3..4}->s7\n" +
"BlockStart_6->s4\n" + "s7->s8\n" +
"s2-A->s3\n" +
"s4-B->s5\n" +
"s3->BlockEnd_7\n" +
"s5->BlockEnd_7\n" +
"BlockEnd_7->s8\n" +
"s8-C->s9\n" + "s8-C->s9\n" +
"s9->RuleStop_a_1\n" + "s9->RuleStop_a_1\n" +
"RuleStop_a_1-EOF->s10\n"; "RuleStop_a_1-EOF->s10\n";
@ -253,19 +282,15 @@ public class TestATNConstruction extends BaseTest {
"parser grammar P;\n"+ "parser grammar P;\n"+
"a : (A|B)+;"); "a : (A|B)+;");
String expecting = String expecting =
"RuleStart_a_0->PlusBlockStart_6\n" + "RuleStart_a_0->PlusBlockStart_8\n" +
"PlusBlockStart_6->s2\n" + "PlusBlockStart_8->s6\n" +
"PlusBlockStart_6->s4\n" + "s6-{3..4}->s7\n" +
"s2-A->s3\n" + "s7->BlockEnd_9\n" +
"s4-B->s5\n" + "BlockEnd_9->PlusLoopBack_10\n" +
"s3->BlockEnd_7\n" + "PlusLoopBack_10->s6\n" +
"s5->BlockEnd_7\n" + "PlusLoopBack_10->s11\n" +
"BlockEnd_7->PlusLoopBack_8\n" + "s11->RuleStop_a_1\n" +
"PlusLoopBack_8->s2\n" + "RuleStop_a_1-EOF->s12\n";
"PlusLoopBack_8->s4\n" +
"PlusLoopBack_8->s9\n" +
"s9->RuleStop_a_1\n" +
"RuleStop_a_1-EOF->s10\n";
checkRule(g, "a", expecting); checkRule(g, "a", expecting);
} }
@ -340,18 +365,15 @@ public class TestATNConstruction extends BaseTest {
"parser grammar P;\n"+ "parser grammar P;\n"+
"a : (A | B)* ;"); "a : (A | B)* ;");
String expecting = String expecting =
"RuleStart_a_0->StarBlockStart_6\n" + "RuleStart_a_0->StarBlockStart_8\n" +
"StarBlockStart_6->s2\n" + "StarBlockStart_8->s6\n" +
"StarBlockStart_6->s4\n" + "StarBlockStart_8->s11\n" +
"StarBlockStart_6->s9\n" + "s6-{3..4}->s7\n" +
"s2-A->s3\n" + "s11->RuleStop_a_1\n" +
"s4-B->s5\n" + "s7->BlockEnd_9\n" +
"s9->RuleStop_a_1\n" + "RuleStop_a_1-EOF->s12\n" +
"s3->BlockEnd_7\n" + "BlockEnd_9->StarLoopBack_10\n" +
"s5->BlockEnd_7\n" + "StarLoopBack_10->StarBlockStart_8\n";
"RuleStop_a_1-EOF->s10\n" +
"BlockEnd_7->StarLoopBack_8\n" +
"StarLoopBack_8->StarBlockStart_6\n";
checkRule(g, "a", expecting); checkRule(g, "a", expecting);
} }