diff --git a/runtime/Java/src/org/antlr/v4/runtime/MismatchedTreeNodeException.java b/runtime/Java/src/org/antlr/v4/runtime/MismatchedASTNodeException.java similarity index 88% rename from runtime/Java/src/org/antlr/v4/runtime/MismatchedTreeNodeException.java rename to runtime/Java/src/org/antlr/v4/runtime/MismatchedASTNodeException.java index 6ff72932a..62e1082f1 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/MismatchedTreeNodeException.java +++ b/runtime/Java/src/org/antlr/v4/runtime/MismatchedASTNodeException.java @@ -30,12 +30,12 @@ package org.antlr.v4.runtime; /** */ -public class MismatchedTreeNodeException extends RecognitionException { - public MismatchedTreeNodeException() { +public class MismatchedASTNodeException extends RecognitionException { + public MismatchedASTNodeException() { } - public MismatchedTreeNodeException(BaseRecognizer recognizer, - IntStream input, int firstSet) + public MismatchedASTNodeException(BaseRecognizer recognizer, + IntStream input, int firstSet) { super(recognizer, input, recognizer._ctx); } diff --git a/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java b/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java index 7620028bf..bda1dfd0b 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java +++ b/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java @@ -173,6 +173,7 @@ public class Recognizer { * so that it creates a new Java type. */ public String getTokenErrorDisplay(Token t) { + if ( t==null ) return ""; String s = t.getText(); if ( s==null ) { if ( t.getType()==Token.EOF ) { diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/ATNState.java b/runtime/Java/src/org/antlr/v4/runtime/atn/ATNState.java index 95a435183..ac9d1967f 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/ATNState.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/ATNState.java @@ -32,6 +32,8 @@ package org.antlr.v4.runtime.atn; import java.util.*; public class ATNState { + public static final int INITIAL_NUM_TRANSITIONS = 4; + // constants for serialization public static final int BASIC = 1; public static final int RULE_START = 2; @@ -79,15 +81,17 @@ public class ATNState { public int stateNumber = INVALID_STATE_NUMBER; -// public Rule rule; public int ruleIndex; // at runtime, we don't have Rule objects /** Which ATN are we in? */ public ATN atn = null; - /** ATN state is associated with which node in AST? */ -// public GrammarAST ast; - public Transition transition; + //public Transition transition; + + /** Track the transitions emanating from this ATN state. */ + protected List transitions = + new ArrayList(INITIAL_NUM_TRANSITIONS); + /** For o-A->o type ATN tranitions, record the label that leads to this * state. Useful for creating rich error messages when we find * insufficiently (with preds) covered states. @@ -109,31 +113,22 @@ public class ATNState { return String.valueOf(stateNumber); } - public int getNumberOfTransitions() { - if ( transition!=null ) return 1; - return 0; - } + public int getNumberOfTransitions() { return transitions.size(); } - public void addTransition(Transition e) { - if ( transition!=null ) throw new IllegalArgumentException("only one transition in state type "+ - getClass().getSimpleName()); - transition = e; - } + public void addTransition(Transition e) { transitions.add(e); } - public Transition transition(int i) { - if ( i>0 ) throw new IllegalArgumentException("only one transition"+ - getClass().getSimpleName()); - return transition; + public Transition transition(int i) { return transitions.get(i); } + + public void setTransition(int i, Transition e) { + transitions.set(i, e); } public boolean onlyHasEpsilonTransitions() { - return transition!=null && transition.isEpsilon(); - } - - public void setTransition(int i, Transition e) { - if ( i>0 ) throw new IllegalArgumentException("only one transition"+ - getClass().getSimpleName()); - transition = e; + if ( transitions==null ) return false; + for (Transition t : transitions) { + if ( !t.isEpsilon() ) return false; + } + return true; } public void setRuleIndex(int ruleIndex) { this.ruleIndex = ruleIndex; } diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/DecisionState.java b/runtime/Java/src/org/antlr/v4/runtime/atn/DecisionState.java index 6a4ba7bec..a7be4531a 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/DecisionState.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/DecisionState.java @@ -29,35 +29,11 @@ package org.antlr.v4.runtime.atn; -import java.util.*; - public class DecisionState extends ATNState { - public static final int INITIAL_NUM_TRANSITIONS = 4; - - /** Track the transitions emanating from this ATN state. */ - public List transitions = new ArrayList(INITIAL_NUM_TRANSITIONS); - public int decision = -1; public boolean isGreedy = true; - @Override - public int getNumberOfTransitions() { return transitions.size(); } - - @Override - public void addTransition(Transition e) { transitions.add(e); } - - public void addTransitionFirst(Transition e) { transitions.add(0, e); } - - @Override - public Transition transition(int i) { return transitions.get(i); } - @Override public boolean onlyHasEpsilonTransitions() { return true; } - - @Override - public void setTransition(int i, Transition e) { - transitions.set(i, e); - } - } diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java b/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java index f42af0f93..fe34c396f 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java @@ -30,9 +30,9 @@ package org.antlr.v4.runtime.atn; import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.dfa.DFAState; +import org.antlr.v4.runtime.dfa.*; import org.antlr.v4.runtime.misc.OrderedHashSet; +import org.antlr.v4.runtime.tree.ASTNodeStream; import org.stringtemplate.v4.misc.MultiMap; import java.util.*; @@ -81,7 +81,7 @@ public class ParserATNSimulator extends ATNSimulator { // System.out.println(dot.getDOT(atn.rules.get(1), parser.getRuleNames())); } - public int adaptivePredict(TokenStream input, int decision, RuleContext outerContext) { + public int adaptivePredict(IntStream input, int decision, RuleContext outerContext) { predict_calls++; DFA dfa = decisionToDFA[decision]; if ( dfa==null || dfa.s0==null ) { @@ -100,14 +100,14 @@ public class ParserATNSimulator extends ATNSimulator { } } - public int predictATN(DFA dfa, TokenStream input, + public int predictATN(DFA dfa, IntStream input, RuleContext outerContext, boolean useContext) { if ( outerContext==null ) outerContext = RuleContext.EMPTY; this.outerContext = outerContext; if ( debug ) System.out.println("ATN decision "+dfa.decision+ - " exec LA(1)=="+input.LT(1)+ + " exec LA(1)=="+ getLookaheadName(input) + ", outerContext="+outerContext.toString(parser)); RuleContext ctx = RuleContext.EMPTY; if ( useContext ) ctx = outerContext; @@ -133,19 +133,19 @@ public class ParserATNSimulator extends ATNSimulator { } // doesn't create DFA when matching - public int matchATN(TokenStream input, ATNState startState) { + public int matchATN(IntStream input, ATNState startState) { DFA dfa = new DFA(startState); RuleContext ctx = RuleContext.EMPTY; OrderedHashSet s0_closure = computeStartState(dfa.decision, startState, ctx); return execATN(input, dfa, input.index(), s0_closure, false); } - public int execDFA(TokenStream input, DFA dfa, DFAState s0, RuleContext outerContext) { + public int execDFA(IntStream input, DFA dfa, DFAState s0, RuleContext outerContext) { // dump(dfa); if ( outerContext==null ) outerContext = RuleContext.EMPTY; this.outerContext = outerContext; if ( dfa_debug ) System.out.println("DFA decision "+dfa.decision+ - " exec LA(1)=="+input.LT(1)+ + " exec LA(1)=="+ getLookaheadName(input) + ", outerContext="+outerContext.toString(parser)); DFAState prevAcceptState = null; DFAState s = s0; @@ -180,8 +180,9 @@ public class ParserATNSimulator extends ATNSimulator { if ( dfa_debug ) System.out.println("no edge for "+t); int alt = -1; if ( dfa_debug ) { + System.out.println("ATN exec upon "+ - input.toString(start,input.index())+ + getInputString(input, start) + " at DFA state "+s.stateNumber); } try { @@ -228,13 +229,23 @@ public class ParserATNSimulator extends ATNSimulator { return prevAcceptState.prediction; } - public int execATN(TokenStream input, + public String getInputString(IntStream input, int start) { + if ( input instanceof TokenStream ) { + return ((TokenStream)input).toString(start,input.index()); + } + else if ( input instanceof ASTNodeStream) { + return ((ASTNodeStream)input).toString(start,input.index()); + } + return "n/a"; + } + + public int execATN(IntStream input, DFA dfa, int startIndex, OrderedHashSet s0, boolean useContext) { - if ( debug ) System.out.println("execATN decision "+dfa.decision+" exec LA(1)=="+input.LT(1)); + if ( debug ) System.out.println("execATN decision "+dfa.decision+" exec LA(1)=="+ getLookaheadName(input)); ATN_failover++; OrderedHashSet closure = new OrderedHashSet(); @@ -281,7 +292,7 @@ public class ParserATNSimulator extends ATNSimulator { String rname = "n/a"; if ( parser !=null ) rname = parser.getRuleNames()[loc.ruleIndex]; System.out.println("AMBIG dec "+dfa.decision+" in "+rname+" for alt "+ambigAlts+" upon "+ - input.toString(startIndex, input.index())); + getInputString(input, startIndex)); System.out.println("REACH="+reach); } dfa.conflict = true; // at least one DFA state is ambiguous @@ -351,7 +362,7 @@ public class ParserATNSimulator extends ATNSimulator { } while ( true ); if ( prevAccept==null ) { - System.out.println("no viable token at input "+input.LT(1)+", index "+input.index()); + System.out.println("no viable token at input "+ getLookaheadName(input) +", index "+input.index()); NoViableAltException nvae = new NoViableAltException(parser, input, closure, outerContext); nvae.startIndex = startIndex; throw nvae; @@ -382,7 +393,7 @@ public class ParserATNSimulator extends ATNSimulator { return exitAlt; } - public int retryWithContext(TokenStream input, + public int retryWithContext(IntStream input, DFA dfa, int startIndex, RuleContext originalContext, @@ -395,7 +406,7 @@ public class ParserATNSimulator extends ATNSimulator { retry_with_context++; int old_k = input.index(); // retry using context, if any; if none, kill all but min as before - if ( debug ) System.out.println("RETRY "+input.toString(startIndex, input.index())+ + if ( debug ) System.out.println("RETRY "+ getInputString(input, startIndex) + " with ctx="+ originalContext); int min = getMinAlt(ambigAlts); if ( originalContext==RuleContext.EMPTY ) { @@ -786,6 +797,11 @@ public class ParserATNSimulator extends ATNSimulator { return String.valueOf(t); } + public String getLookaheadName(IntStream input) { + if ( input.LA(1)==Token.EOF ) return "EOF"; + return parser.getTokenNames()[input.LA(1)]; + } + public void setContextSensitive(boolean ctxSensitive) { this.userWantsCtxSensitive = ctxSensitive; } diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/PlusBlockStartState.java b/runtime/Java/src/org/antlr/v4/runtime/atn/PlusBlockStartState.java index 219ffb6a2..4d8e69fbe 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/PlusBlockStartState.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/PlusBlockStartState.java @@ -36,5 +36,4 @@ package org.antlr.v4.runtime.atn; */ public class PlusBlockStartState extends BlockStartState { public PlusLoopbackState loopBackState; - //public BlockEndState endState; } diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/RuleStopState.java b/runtime/Java/src/org/antlr/v4/runtime/atn/RuleStopState.java index ba10b2131..9032f81f0 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/RuleStopState.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/RuleStopState.java @@ -29,33 +29,10 @@ package org.antlr.v4.runtime.atn; -import java.util.*; - /** The last node in the ATN for a rule, unless that rule is the start symbol. * In that case, there is one transition to EOF. Later, we might encode * references to all calls to this rule to compute FOLLOW sets for * error handling. */ public class RuleStopState extends ATNState { - public static final int INITIAL_NUM_TRANSITIONS = 4; - - //public int actionIndex; // for lexer, this is right edge action in rule - - /** Track the transitions emanating from this ATN state. */ - protected List transitions = - new ArrayList(INITIAL_NUM_TRANSITIONS); - - @Override - public int getNumberOfTransitions() { return transitions.size(); } - - @Override - public void addTransition(Transition e) { transitions.add(e); } - - @Override - public Transition transition(int i) { return transitions.get(i); } - - @Override - public void setTransition(int i, Transition e) { - transitions.set(i, e); - } } diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/StarBlockStartState.java b/runtime/Java/src/org/antlr/v4/runtime/atn/StarBlockStartState.java index a2d6fe541..f6794432e 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/StarBlockStartState.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/StarBlockStartState.java @@ -31,5 +31,4 @@ package org.antlr.v4.runtime.atn; /** The block that begins a closure loop. */ public class StarBlockStartState extends BlockStartState { -// public StarLoopbackState loopBackState; } diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/TreeIterator.java b/runtime/Java/src/org/antlr/v4/runtime/tree/ASTIterator.java similarity index 96% rename from runtime/Java/src/org/antlr/v4/runtime/tree/TreeIterator.java rename to runtime/Java/src/org/antlr/v4/runtime/tree/ASTIterator.java index e43efe2c3..d46d5afe9 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/TreeIterator.java +++ b/runtime/Java/src/org/antlr/v4/runtime/tree/ASTIterator.java @@ -39,7 +39,7 @@ import java.util.Iterator; * * Emit navigation nodes (DOWN, UP, and EOF) to let show tree structure. */ -public class TreeIterator implements Iterator { +public class ASTIterator implements Iterator { protected ASTAdaptor adaptor; protected Object root; protected Object tree; @@ -55,11 +55,11 @@ public class TreeIterator implements Iterator { */ protected FastQueue nodes; - public TreeIterator(Object tree) { + public ASTIterator(Object tree) { this(new CommonASTAdaptor(),tree); } - public TreeIterator(ASTAdaptor adaptor, Object tree) { + public ASTIterator(ASTAdaptor adaptor, Object tree) { this.adaptor = adaptor; this.tree = tree; this.root = tree; diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/CommonASTNodeStream.java b/runtime/Java/src/org/antlr/v4/runtime/tree/CommonASTNodeStream.java index 791b023bc..37419034d 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/CommonASTNodeStream.java +++ b/runtime/Java/src/org/antlr/v4/runtime/tree/CommonASTNodeStream.java @@ -48,7 +48,7 @@ public class CommonASTNodeStream extends LookaheadStream implements ASTN ASTAdaptor adaptor; /** The tree iterator we using */ - protected TreeIterator it; + protected ASTIterator it; /** Stack of indexes used for push/pop calls */ protected Stack calls; @@ -66,7 +66,7 @@ public class CommonASTNodeStream extends LookaheadStream implements ASTN public CommonASTNodeStream(ASTAdaptor adaptor, Object tree) { this.root = tree; this.adaptor = adaptor; - it = new TreeIterator(adaptor,root); + it = new ASTIterator(adaptor,root); } public void reset() { @@ -147,10 +147,19 @@ public class CommonASTNodeStream extends LookaheadStream implements ASTN } } + /** Print the token text between start and stop nodes. If stop is an UP + * node, then we have to walk it back until we see the first non-UP node. + * Then, just get the token indexes and look into the token stream. + */ public String toString(Object start, Object stop) { - // we'll have to walk from start to stop in tree; we're not keeping - // a complete node stream buffer - return "n/a"; + if ( tokens==null ) throw new UnsupportedOperationException("can't print from null token stream in node stream"); + if ( start==null || stop==null ) return ""; + Token startToken = adaptor.getToken(start); + Token stopToken = adaptor.getToken(stop); + while ( stopToken.getType()==Token.UP ) { + stopToken = adaptor.getToken(stop); + } + return tokens.toString(startToken.getTokenIndex(), stopToken.getTokenIndex()); } /** For debugging; destructive: moves tree iterator to end. */ diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg index 9f18d55ca..82672eafa 100644 --- a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg @@ -369,9 +369,22 @@ cases(ttypes) ::= << :}; separator="\n"> >> -MatchTree(t, elems) ::= << +MatchTree(t, root, down, leftActions, kids, rightActions, up) ::= << // match tree - + + + +if ( _input.LA(1)==Token.DOWN ) { + + + +} + + + + + + >> MatchDOWN(m) ::= << @@ -444,7 +457,7 @@ TokenPropertyRef_int(t) ::= "(_localctx.!=null?Integer.valueOf(_localct RulePropertyRef_start(r) ::= "(_localctx.!=null?(()_localctx..start):null)" RulePropertyRef_stop(r) ::= "(_localctx.!=null?(()_localctx..stop):null)" RulePropertyRef_tree(r) ::= "(_localctx.!=null?(()_localctx..tree):null)" -RulePropertyRef_text(r) ::= "(_localctx.!=null?((TokenStream)_input).toString(_localctx..start,_localctx..stop):null)" +RulePropertyRef_text(r) ::= "(_localctx.!=null?_input.toString(_localctx..start,_localctx..stop):null)" RulePropertyRef_st(r) ::= "(_localctx.!=null?_localctx..st:null)" ThisRulePropertyRef_start(r) ::= "_localctx.start" @@ -453,6 +466,15 @@ ThisRulePropertyRef_tree(r) ::= "_localctx.tree" ThisRulePropertyRef_text(r) ::= "((TokenStream)_input).toString(_localctx.start, _input.LT(-1))" ThisRulePropertyRef_st(r) ::= "_localctx.st" +/* +TreeRulePropertyRef_text(r) ::= <% +(_localctx.!=null? + ((ASTNodeStream)_input).toString(_localctx..start,_localctx..stop) + :null +) +%> +*/ + NonLocalAttrRef(s) ::= "((Context)getInvokingContext())." SetNonLocalAttr(s, rhsChunks) ::= "((Context)getInvokingContext()). = ;" diff --git a/tool/src/org/antlr/v4/automata/LexerATNFactory.java b/tool/src/org/antlr/v4/automata/LexerATNFactory.java index 3f67f0713..8908f05ad 100644 --- a/tool/src/org/antlr/v4/automata/LexerATNFactory.java +++ b/tool/src/org/antlr/v4/automata/LexerATNFactory.java @@ -95,7 +95,7 @@ public class LexerATNFactory extends ParserATNFactory { ATNState right = newState(b); int t1 = CharSupport.getCharValueFromGrammarCharLiteral(a.getText()); int t2 = CharSupport.getCharValueFromGrammarCharLiteral(b.getText()); - left.transition = new RangeTransition(t1, t2, right); + left.addTransition(new RangeTransition(t1, t2, right)); a.atnState = left; b.atnState = left; return new Handle(left, right); @@ -119,12 +119,12 @@ public class LexerATNFactory extends ParserATNFactory { } if ( invert ) { IntervalSet notSet = (IntervalSet)set.complement(Token.MIN_TOKEN_TYPE, g.getMaxTokenType()); - left.transition = new NotSetTransition(set, notSet, right); + left.addTransition(new NotSetTransition(set, notSet, right)); } else { - left.transition = new SetTransition(set, right); + left.addTransition(new SetTransition(set, right)); } - right.incidentTransition = left.transition; + right.incidentTransition = left.transition(0); associatedAST.atnState = left; return new Handle(left, right); } @@ -144,7 +144,7 @@ public class LexerATNFactory extends ParserATNFactory { ATNState right = null; for (int i=0; i treePatternRootNodes = new ArrayList(); + List firstChildStates = new ArrayList(); + List downStates = new ArrayList(); + List upTargetStates = new ArrayList(); + public TreeParserATNFactory(Grammar g) { super(g); } - /** x y z from ^(x y z) becomes o-x->o-DOWN->o-y->o-z->o-UP->o */ - public Handle tree(GrammarAST node, List els) { - Handle h = elemList(els); - return h; + public ATN createATN() { + super.createATN(); -// ATNState first = h.left; -// ATNState last = h.right; -// node.atnState = first; -// -// // find root transition first side node -// ATNState p = first; -// while ( p.transition(0) instanceof EpsilonTransition || -// p.transition(0) instanceof PredicateTransition || -// p.transition(0) instanceof RangeTransition || -// p.transition(0) instanceof ActionTransition ) -// { -// p = p.transition(0).target; -// } -// ATNState rootLeftNode = p; -// ATNState rootRightNode = rootLeftNode.transition(0).target; -// ATNState downLeftNode = newState(node); -// downLeftNode.transition = new AtomTransition(Token.DOWN, rootRightNode); -// rootRightNode.incidentTransition = downLeftNode.transition; -// rootLeftNode.transition.target = downLeftNode; -// downLeftNode.incidentTransition = rootLeftNode.transition; -// -// ATNState upRightNode = newState(node); -// last.transition = new AtomTransition(Token.UP, upRightNode); -// upRightNode.incidentTransition = last.transition; -// last = upRightNode; -// -// return new Handle(first, last); + for (int i=0; io-DOWN->o-y->o-z->o-UP->o + * ANTLRParser.g has added DOWN_TOKEN, UP_TOKEN into AST. + * Elems are [root, DOWN_TOKEN, x, y, UP_TOKEN] + */ + public Handle tree(GrammarAST node, List els) { + Handle h = elemList(els); + + treePatternRootNodes.add((TreePatternAST)node); + // find DOWN node then first child + for (Handle elh : els) { + Transition trans = elh.left.transition(0); + if ( !trans.isEpsilon() && trans.label().member(Token.DOWN) ) { + ATNState downState = elh.left; + downStates.add(downState); + firstChildStates.add(downState.transition(0).target); + break; + } + } + // find UP node + for (Handle elh : els) { + Transition trans = elh.left.transition(0); + if ( trans instanceof AtomTransition && trans.label().member(Token.UP) ) { + ATNState upTargetState = elh.right; + upTargetStates.add(upTargetState); + break; + } + } + + return h; + } } diff --git a/tool/src/org/antlr/v4/codegen/ActionTranslator.java b/tool/src/org/antlr/v4/codegen/ActionTranslator.java index 052746f47..a2b485f6d 100644 --- a/tool/src/org/antlr/v4/codegen/ActionTranslator.java +++ b/tool/src/org/antlr/v4/codegen/ActionTranslator.java @@ -56,6 +56,8 @@ public class ActionTranslator implements ActionSplitterListener { put("st", RulePropertyRef_st.class); }}; + public static final Map treeRulePropToModelMap = rulePropToModelMap; + public static final Map tokenPropToModelMap = new HashMap() {{ put("text", TokenPropertyRef_text.class); put("type", TokenPropertyRef_type.class); @@ -135,7 +137,7 @@ public class ActionTranslator implements ActionSplitterListener { case RET: chunks.add(new RetValueRef(x.getText())); break; case LOCAL: chunks.add(new LocalRef(x.getText())); break; case PREDEFINED_RULE: chunks.add(getRulePropertyRef(x)); break; -// case PREDEFINED_TREE_RULE: chunks.add(new RetValueRef(x.getText())); break; + case PREDEFINED_TREE_RULE: chunks.add(getRulePropertyRef(x)); break; } } if ( node.resolver.resolvesToToken(x.getText(), node) ) { @@ -150,16 +152,6 @@ public class ActionTranslator implements ActionSplitterListener { chunks.add(new ListLabelRef(x.getText())); // $ids for ids+=ID etc... return; } -// switch ( a.dict.type ) { -// case ARG: chunks.add(new ArgRef(x.getText())); break; -// case RET: chunks.add(new RetValueRef(x.getText())); break; -// case PREDEFINED_RULE: chunks.add(new RetValueRef(x.getText())); break; -// case PREDEFINED_LEXER_RULE: chunks.add(new RetValueRef(x.getText())); break; -// case PREDEFINED_TREE_RULE: chunks.add(new RetValueRef(x.getText())); break; -// case GLOBAL_SCOPE: chunks.add(new RetValueRef(x.getText())); break; -// case RULE_SCOPE: chunks.add(new RetValueRef(x.getText())); break; -// case TOKEN: chunks.add(new TokenRef(x.getText())); break; -// } } /** $x.y = expr; */ @@ -176,13 +168,16 @@ public class ActionTranslator implements ActionSplitterListener { switch ( a.dict.type ) { case ARG: chunks.add(new ArgRef(y.getText())); break; // has to be current rule case RET: - if ( factory.getCurrentRuleFunction()!=null && factory.getCurrentRuleFunction().name.equals(x.getText()) ) { + if ( factory.getCurrentRuleFunction()!=null && + factory.getCurrentRuleFunction().name.equals(x.getText()) ) + { chunks.add(new RetValueRef(y.getText())); break; } else { chunks.add(new QRetValueRef(getRuleLabel(x.getText()), y.getText())); break; } case PREDEFINED_RULE: + case PREDEFINED_TREE_RULE: if ( factory.getCurrentRuleFunction()!=null && factory.getCurrentRuleFunction().name.equals(x.getText()) ) { @@ -192,9 +187,13 @@ public class ActionTranslator implements ActionSplitterListener { chunks.add(getRulePropertyRef(x, y)); } break; - case TOKEN: chunks.add(getTokenPropertyRef(x, y)); break; + case TOKEN: + chunks.add(getTokenPropertyRef(x, y)); + break; +// case PREDEFINED_TREE_RULE: +// chunks.add(new RetValueRef(x.getText())); +// break; // case PREDEFINED_LEXER_RULE: chunks.add(new RetValueRef(x.getText())); break; -// case PREDEFINED_TREE_RULE: chunks.add(new RetValueRef(x.getText())); break; } } @@ -272,15 +271,18 @@ public class ActionTranslator implements ActionSplitterListener { } RulePropertyRef getRulePropertyRef(Token x, Token prop) { + Grammar g = factory.getGrammar(); try { - Class c = rulePropToModelMap.get(prop.getText()); + Class c = g.isTreeGrammar() ? + treeRulePropToModelMap.get(prop.getText()) : + rulePropToModelMap.get(prop.getText()); Constructor ctor = c.getConstructor(new Class[] {String.class}); RulePropertyRef ref = (RulePropertyRef)ctor.newInstance(getRuleLabel(x.getText())); return ref; } catch (Exception e) { - factory.getGrammar().tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, e); + g.tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, e); } return null; } diff --git a/tool/src/org/antlr/v4/codegen/SourceGenTriggers.g b/tool/src/org/antlr/v4/codegen/SourceGenTriggers.g index 3f3d84686..cefe9e6f6 100644 --- a/tool/src/org/antlr/v4/codegen/SourceGenTriggers.g +++ b/tool/src/org/antlr/v4/codegen/SourceGenTriggers.g @@ -131,18 +131,18 @@ treeSpec returns [MatchTree treeMatch] subrule returns [List omos] : ^(astBlockSuffix block[null,null,$astBlockSuffix.start]) {$omos = $block.omos;} | ^(OPTIONAL block[null,$OPTIONAL,null]) {$omos = $block.omos;} - | ^(CLOSURE block[null,null,null]) + | ( ^(op=CLOSURE b=block[null,$CLOSURE,null]) + | ^(op=POSITIVE_CLOSURE b=block[null,$POSITIVE_CLOSURE,null]) + ) { List alts = new ArrayList(); - SrcOp blk = $block.omos.get(0); + SrcOp blk = $b.omos.get(0); CodeBlockForAlt alt = new CodeBlockForAlt(controller.delegate); alt.addOp(blk); alts.add(alt); - SrcOp loop = controller.getEBNFBlock($CLOSURE, alts); // "star it" + SrcOp loop = controller.getEBNFBlock($op, alts); // "star it" $omos = DefaultOutputModelFactory.list(loop); } - | ^(POSITIVE_CLOSURE block[null,$POSITIVE_CLOSURE,null]) - {$omos = $block.omos;} | block[null, null,null] {$omos = $block.omos;} ; @@ -266,7 +266,7 @@ rewriteTreeAtom[boolean isRoot] returns [List omos] ; rewriteTreeEbnf returns [CodeBlock op] - : ^( (a=OPTIONAL|a=CLOSURE) + : ^( (a=OPTIONAL|a=CLOSURE|a=POSITIVE_CLOSURE) ^( REWRITE_BLOCK { controller.codeBlockLevel++; diff --git a/tool/src/org/antlr/v4/codegen/model/MatchSet.java b/tool/src/org/antlr/v4/codegen/model/MatchSet.java index 5b75d9b71..79a571c70 100644 --- a/tool/src/org/antlr/v4/codegen/model/MatchSet.java +++ b/tool/src/org/antlr/v4/codegen/model/MatchSet.java @@ -40,7 +40,7 @@ public class MatchSet extends MatchToken { public MatchSet(OutputModelFactory factory, GrammarAST ast) { super(factory, ast); - SetTransition st = (SetTransition)ast.atnState.transition; + SetTransition st = (SetTransition)ast.atnState.transition(0); expr = new TestSetInline(factory, null, st.set); Decl d = new TokenTypeDecl(factory, expr.varName); factory.getCurrentRuleFunction().addLocalDecl(d); diff --git a/tool/src/org/antlr/v4/codegen/model/MatchToken.java b/tool/src/org/antlr/v4/codegen/model/MatchToken.java index 93c019fe8..80ab012d3 100644 --- a/tool/src/org/antlr/v4/codegen/model/MatchToken.java +++ b/tool/src/org/antlr/v4/codegen/model/MatchToken.java @@ -38,13 +38,14 @@ import java.util.*; /** */ public class MatchToken extends RuleElement implements LabeledOp { public String name; + public int ttype; public List labels = new ArrayList(); public MatchToken(OutputModelFactory factory, TerminalAST ast) { super(factory, ast); Grammar g = factory.getGrammar(); CodeGenerator gen = factory.getGenerator(); - int ttype = g.getTokenType(ast.getText()); + ttype = g.getTokenType(ast.getText()); name = gen.target.getTokenTypeAsTargetLabel(g, ttype); } diff --git a/tool/src/org/antlr/v4/codegen/model/MatchTree.java b/tool/src/org/antlr/v4/codegen/model/MatchTree.java index 4fdfc0ae5..742e262a4 100644 --- a/tool/src/org/antlr/v4/codegen/model/MatchTree.java +++ b/tool/src/org/antlr/v4/codegen/model/MatchTree.java @@ -30,16 +30,46 @@ package org.antlr.v4.codegen.model; import org.antlr.v4.codegen.OutputModelFactory; -import org.antlr.v4.tool.GrammarAST; +import org.antlr.v4.misc.Utils; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.tool.*; import java.util.List; public class MatchTree extends RuleElement { - @ModelElement public List elems; + public boolean isNullable; + + @ModelElement public SrcOp root; + @ModelElement public List leftActions; + @ModelElement public SrcOp down; + @ModelElement public List kids; + @ModelElement public SrcOp up; + @ModelElement public List rightActions; public MatchTree(OutputModelFactory factory, GrammarAST ast, List elems) { super(factory, ast); - this.elems = elems; + TreePatternAST rootNode = (TreePatternAST)ast; + this.isNullable = rootNode.isNullable; + List afterRoot = elems.subList(1, elems.size()); + int downIndex = + Utils.indexOf(afterRoot, new Utils.Filter() { + public boolean select(SrcOp op) { + return op instanceof MatchToken && ((MatchToken)op).ttype==Token.DOWN; + } + }); + downIndex++; // we skipped root + down = elems.get(downIndex); + int upIndex = + Utils.lastIndexOf(elems, new Utils.Filter() { + public boolean select(SrcOp op) { + return op instanceof MatchToken && ((MatchToken) op).ttype == Token.UP; + } + }); + up = elems.get(upIndex); + root = elems.get(0); + leftActions = elems.subList(1, downIndex); + rightActions = elems.subList(upIndex+1, elems.size()); + this.kids = elems.subList(downIndex+1, upIndex); } } diff --git a/tool/src/org/antlr/v4/misc/Utils.java b/tool/src/org/antlr/v4/misc/Utils.java index 5522ea672..c99857a93 100644 --- a/tool/src/org/antlr/v4/misc/Utils.java +++ b/tool/src/org/antlr/v4/misc/Utils.java @@ -37,6 +37,11 @@ import java.util.*; /** */ public class Utils { public static final int INTEGER_POOL_MAX_VALUE = 1000; + + public interface Filter { + boolean select(T t); + } + static Integer[] ints = new Integer[INTEGER_POOL_MAX_VALUE+1]; /** Integer objects are immutable so share all Integers with the @@ -179,4 +184,19 @@ public class Utils { } return null; } + + public static int indexOf(List elems, Filter filter) { + for (int i=0; i int lastIndexOf(List elems, Filter filter) { + for (int i=elems.size()-1; i>=0; i--) { + if ( filter.select(elems.get(i)) ) return i; + } + return -1; + } + } diff --git a/tool/src/org/antlr/v4/parse/ANTLRParser.g b/tool/src/org/antlr/v4/parse/ANTLRParser.g index abc88d07c..e9efd827a 100644 --- a/tool/src/org/antlr/v4/parse/ANTLRParser.g +++ b/tool/src/org/antlr/v4/parse/ANTLRParser.g @@ -649,21 +649,34 @@ labeledElement // will walk of course. Alts for trees therefore start with ^( XXX, which // says we will see a root node of XXX then DOWN etc treeSpec - : TREE_BEGIN +@after { + GrammarAST down = new DownAST(DOWN_TOKEN, $begin); + GrammarAST up = new UpAST(UP_TOKEN, $begin); + int i = 1; // skip root element + GrammarAST p = (GrammarAST)$tree.getChild(i); + while ( p.getType()==ACTION || p.getType()==SEMPRED ) { + i++; + p = (GrammarAST)$tree.getChild(i); + } + $tree.insertChild(i, down); // ADD DOWN + i = $tree.getChildCount()-1; + p = (GrammarAST)$tree.getChild(i); + while ( p.getType()==ACTION || p.getType()==SEMPRED ) { + i--; + p = (GrammarAST)$tree.getChild(i); + } + $tree.insertChild(i+1, up); // ADD UP +} + : begin=TREE_BEGIN // Only a subset of elements are allowed to be a root node. However // we allow any element to appear here and reject silly ones later // when we walk the AST. root=element // After the tree root we get the usual suspects, - // all members of the element set + // all members of the element set. (kids+=element)+ RPAREN - -> ^(TREE_BEGIN - $root - DOWN_TOKEN[$TREE_BEGIN] - $kids+ - UP_TOKEN[$TREE_BEGIN] - ) + -> ^( TREE_BEGIN $root $kids+ ) ; // A block of gramamr structure optionally followed by standard EBNF diff --git a/tool/src/org/antlr/v4/parse/GrammarTreeVisitor.g b/tool/src/org/antlr/v4/parse/GrammarTreeVisitor.g index 0c1623fe4..afab47511 100644 --- a/tool/src/org/antlr/v4/parse/GrammarTreeVisitor.g +++ b/tool/src/org/antlr/v4/parse/GrammarTreeVisitor.g @@ -358,6 +358,8 @@ element | ^(BANG astOperand) {bangOp($BANG, $astOperand.start);} | ^(NOT blockSet) | ^(NOT block) + | DOWN_TOKEN + | UP_TOKEN ; astOperand @@ -371,7 +373,7 @@ labeledElement ; treeSpec - : ^(TREE_BEGIN element DOWN_TOKEN element+ UP_TOKEN ) + : ^(TREE_BEGIN element element+ ) // UP_TOKEN and DOWN_TOKEN in there somewhere ; subrule diff --git a/tool/src/org/antlr/v4/semantics/BasicSemanticChecks.java b/tool/src/org/antlr/v4/semantics/BasicSemanticChecks.java index 6889e28a3..a3080c4e6 100644 --- a/tool/src/org/antlr/v4/semantics/BasicSemanticChecks.java +++ b/tool/src/org/antlr/v4/semantics/BasicSemanticChecks.java @@ -31,8 +31,7 @@ package org.antlr.v4.semantics; import org.antlr.runtime.Token; import org.antlr.v4.misc.Utils; -import org.antlr.v4.parse.ANTLRParser; -import org.antlr.v4.parse.GrammarTreeVisitor; +import org.antlr.v4.parse.*; import org.antlr.v4.tool.*; import org.stringtemplate.v4.misc.MultiMap; @@ -534,7 +533,7 @@ public class BasicSemanticChecks extends GrammarTreeVisitor { } void checkWildcardRoot(GrammarAST wild) { - if ( wild.getParent().getType()==ANTLRParser.TREE_BEGIN ) { + if ( wild.getChildIndex()==0 && wild.getParent().getType()==ANTLRParser.TREE_BEGIN ) { String fileName = wild.token.getInputStream().getSourceName(); g.tool.errMgr.grammarError(ErrorType.WILDCARD_AS_ROOT, fileName, diff --git a/tool/src/org/antlr/v4/tool/ActionAST.java b/tool/src/org/antlr/v4/tool/ActionAST.java index 9d39e3a76..98fd55b91 100644 --- a/tool/src/org/antlr/v4/tool/ActionAST.java +++ b/tool/src/org/antlr/v4/tool/ActionAST.java @@ -38,9 +38,6 @@ public class ActionAST extends GrammarAST { // Alt, rule, grammar space public AttributeResolver resolver; public List chunks; // useful for ANTLR IDE developers - /** In which alt does this node live? */ -// public Alternative alt; - public ActionAST(GrammarAST node) { super(node); diff --git a/tool/src/org/antlr/v4/tool/TreePatternAST.java b/tool/src/org/antlr/v4/tool/TreePatternAST.java new file mode 100644 index 000000000..54cbdf98c --- /dev/null +++ b/tool/src/org/antlr/v4/tool/TreePatternAST.java @@ -0,0 +1,40 @@ +/* + [The "BSD license"] + Copyright (c) 2011 Terence Parr + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.antlr.v4.tool; + +import org.antlr.runtime.Token; + +public class TreePatternAST extends GrammarAST { + public boolean isNullable; + + public TreePatternAST(Token t) { + super(t); + } +} diff --git a/tool/test/org/antlr/v4/test/BaseTest.java b/tool/test/org/antlr/v4/test/BaseTest.java index 842a7afcc..cf38e569c 100644 --- a/tool/test/org/antlr/v4/test/BaseTest.java +++ b/tool/test/org/antlr/v4/test/BaseTest.java @@ -325,6 +325,7 @@ public abstract class BaseTest { /** Return true if all is ok, no errors */ protected boolean antlr(String fileName, String grammarFileName, String grammarStr, boolean debug) { boolean allIsWell = true; + System.out.println("dir "+tmpdir); mkdir(tmpdir); writeFile(tmpdir, fileName, grammarStr); try { diff --git a/tool/test/org/antlr/v4/test/TestRewriteAST.java b/tool/test/org/antlr/v4/test/TestRewriteAST.java index 0045a6a5e..b26d5aa03 100644 --- a/tool/test/org/antlr/v4/test/TestRewriteAST.java +++ b/tool/test/org/antlr/v4/test/TestRewriteAST.java @@ -233,6 +233,19 @@ public class TestRewriteAST extends BaseTest { assertEquals("a b\n", found); } + @Test public void testPositiveClosureSingleToken() throws Exception { + String grammar = + "grammar T;\n" + + "options {output=AST;}\n" + + "a : ID ID -> ID+ ;\n" + + "ID : 'a'..'z'+ ;\n" + + "INT : '0'..'9'+;\n" + + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; + String found = execParser("T.g", grammar, "TParser", "TLexer", + "a", "a b", debug); + assertEquals("a b\n", found); + } + @Test public void testOptionalSingleRule() throws Exception { String grammar = "grammar T;\n" + diff --git a/tool/test/org/antlr/v4/test/TestTreeIterator.java b/tool/test/org/antlr/v4/test/TestTreeIterator.java index d77fd3f44..2b1b8a0a4 100644 --- a/tool/test/org/antlr/v4/test/TestTreeIterator.java +++ b/tool/test/org/antlr/v4/test/TestTreeIterator.java @@ -42,7 +42,7 @@ public class TestTreeIterator { ASTAdaptor adaptor = new CommonASTAdaptor(); TreeWizard wiz = new TreeWizard(adaptor, tokens); CommonAST t = (CommonAST)wiz.create("A"); - TreeIterator it = new TreeIterator(t); + ASTIterator it = new ASTIterator(t); StringBuffer buf = toString(it); String expecting = "A EOF"; String found = buf.toString(); @@ -53,7 +53,7 @@ public class TestTreeIterator { ASTAdaptor adaptor = new CommonASTAdaptor(); TreeWizard wiz = new TreeWizard(adaptor, tokens); CommonAST t = (CommonAST)wiz.create("(nil A B)"); - TreeIterator it = new TreeIterator(t); + ASTIterator it = new ASTIterator(t); StringBuffer buf = toString(it); String expecting = "nil DOWN A B UP EOF"; String found = buf.toString(); @@ -64,7 +64,7 @@ public class TestTreeIterator { ASTAdaptor adaptor = new CommonASTAdaptor(); TreeWizard wiz = new TreeWizard(adaptor, tokens); CommonAST t = (CommonAST)wiz.create("(A B)"); - TreeIterator it = new TreeIterator(t); + ASTIterator it = new ASTIterator(t); StringBuffer buf = toString(it); String expecting = "A DOWN B UP EOF"; String found = buf.toString(); @@ -75,7 +75,7 @@ public class TestTreeIterator { ASTAdaptor adaptor = new CommonASTAdaptor(); TreeWizard wiz = new TreeWizard(adaptor, tokens); CommonAST t = (CommonAST)wiz.create("(A B C)"); - TreeIterator it = new TreeIterator(t); + ASTIterator it = new ASTIterator(t); StringBuffer buf = toString(it); String expecting = "A DOWN B C UP EOF"; String found = buf.toString(); @@ -86,7 +86,7 @@ public class TestTreeIterator { ASTAdaptor adaptor = new CommonASTAdaptor(); TreeWizard wiz = new TreeWizard(adaptor, tokens); CommonAST t = (CommonAST)wiz.create("(A (B C))"); - TreeIterator it = new TreeIterator(t); + ASTIterator it = new ASTIterator(t); StringBuffer buf = toString(it); String expecting = "A DOWN B DOWN C UP UP EOF"; String found = buf.toString(); @@ -97,7 +97,7 @@ public class TestTreeIterator { ASTAdaptor adaptor = new CommonASTAdaptor(); TreeWizard wiz = new TreeWizard(adaptor, tokens); CommonAST t = (CommonAST)wiz.create("(A (B (C D E) F) G)"); - TreeIterator it = new TreeIterator(t); + ASTIterator it = new ASTIterator(t); StringBuffer buf = toString(it); String expecting = "A DOWN B DOWN C DOWN D E UP F UP G UP EOF"; String found = buf.toString(); @@ -108,7 +108,7 @@ public class TestTreeIterator { ASTAdaptor adaptor = new CommonASTAdaptor(); TreeWizard wiz = new TreeWizard(adaptor, tokens); CommonAST t = (CommonAST)wiz.create("(A (B (C D E) F) G)"); - TreeIterator it = new TreeIterator(t); + ASTIterator it = new ASTIterator(t); StringBuffer buf = toString(it); String expecting = "A DOWN B DOWN C DOWN D E UP F UP G UP EOF"; String found = buf.toString(); @@ -121,7 +121,7 @@ public class TestTreeIterator { assertEquals(expecting, found); } - protected static StringBuffer toString(TreeIterator it) { + protected static StringBuffer toString(ASTIterator it) { StringBuffer buf = new StringBuffer(); while ( it.hasNext() ) { CommonAST n = (CommonAST)it.next(); diff --git a/tool/test/org/antlr/v4/test/TestTreeParsing.java b/tool/test/org/antlr/v4/test/TestTreeParsing.java index 9664dcbe0..6cf5d9b0b 100644 --- a/tool/test/org/antlr/v4/test/TestTreeParsing.java +++ b/tool/test/org/antlr/v4/test/TestTreeParsing.java @@ -1,33 +1,34 @@ /* - * [The "BSD license"] - * Copyright (c) 2010 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.test; + [The "BSD license"] + Copyright (c) 2011 Terence Parr + All rights reserved. -import org.junit.Test; + 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.test; + +import org.junit.*; public class TestTreeParsing extends BaseTest { @Test public void testFlatList() throws Exception { @@ -40,7 +41,7 @@ public class TestTreeParsing extends BaseTest { "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = - "tree grammar TP; options {ASTLabelType=CommonTree;}\n" + + "tree grammar TP; options {ASTLabelType=CommonAST;}\n" + "a : ID INT\n" + " {System.out.println($ID+\", \"+$INT);}\n" + " ;\n"; @@ -60,7 +61,7 @@ public class TestTreeParsing extends BaseTest { "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = - "tree grammar TP; options {ASTLabelType=CommonTree;}\n" + + "tree grammar TP; options {ASTLabelType=CommonAST;}\n" + "a : ^(ID INT)\n" + " {System.out.println($ID+\", \"+$INT);}\n" + " ;\n"; @@ -82,7 +83,7 @@ public class TestTreeParsing extends BaseTest { "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = - "tree grammar TP; options {ASTLabelType=CommonTree;}\n" + + "tree grammar TP; options {ASTLabelType=CommonAST;}\n" + "a : b b ;\n" + "b : ID INT {System.out.print($ID+\" \"+$INT);}\n" + " | ^(ID INT) {System.out.print(\"^(\"+$ID+\" \"+$INT+')');}\n" + @@ -105,7 +106,7 @@ public class TestTreeParsing extends BaseTest { "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = - "tree grammar TP; options {ASTLabelType=CommonTree;}\n" + + "tree grammar TP; options {ASTLabelType=CommonAST;}\n" + "a : b b ;\n" + "b : ID INT+ {System.out.print($ID+\" \"+$INT);}\n" + " | ^(x=ID (y=INT)+) {System.out.print(\"^(\"+$x+' '+$y+')');}\n" + @@ -129,7 +130,7 @@ public class TestTreeParsing extends BaseTest { "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = - "tree grammar TP; options {ASTLabelType=CommonTree;}\n" + + "tree grammar TP; options {ASTLabelType=CommonAST;}\n" + "a : ID INT+ PERIOD {System.out.print(\"alt 1\");}"+ " | ID INT+ SEMI {System.out.print(\"alt 2\");}\n" + " ;\n"; @@ -139,7 +140,8 @@ public class TestTreeParsing extends BaseTest { assertEquals("alt 1\n", found); } - @Test public void testTemplateOutput() throws Exception { + @Ignore + public void testTemplateOutput() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + @@ -150,9 +152,9 @@ public class TestTreeParsing extends BaseTest { String treeGrammar = "tree grammar TP;\n" + - "options {output=template; ASTLabelType=CommonTree;}\n" + + "options {output=template; ASTLabelType=CommonAST;}\n" + "s : a {System.out.println($a.st);};\n" + - "a : ID INT -> {new StringTemplate($INT.text)}\n" + + "a : ID INT -> {new ST($INT.text)}\n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", @@ -170,7 +172,7 @@ public class TestTreeParsing extends BaseTest { "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = - "tree grammar TP; options {ASTLabelType=CommonTree;}\n" + + "tree grammar TP; options {ASTLabelType=CommonAST;}\n" + "a : ^(ID INT?)\n" + " {System.out.println($ID);}\n" + " ;\n"; @@ -191,7 +193,7 @@ public class TestTreeParsing extends BaseTest { "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = - "tree grammar TP; options {ASTLabelType=CommonTree;}\n" + + "tree grammar TP; options {ASTLabelType=CommonAST;}\n" + "a : ^(ID INT?) SEMI\n" + " {System.out.println($ID);}\n" + " ;\n"; @@ -212,7 +214,7 @@ public class TestTreeParsing extends BaseTest { "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = - "tree grammar TP; options {ASTLabelType=CommonTree;}\n" + + "tree grammar TP; options {ASTLabelType=CommonAST;}\n" + "a : ^(ID INT? b) SEMI\n" + " {System.out.println($ID+\", \"+$b.text);}\n" + " ;\n"+ @@ -234,7 +236,7 @@ public class TestTreeParsing extends BaseTest { "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = - "tree grammar TP; options {ASTLabelType=CommonTree;}\n" + + "tree grammar TP; options {ASTLabelType=CommonAST;}\n" + "a @init {int x=0;} : ^(ID {x=1;} {x=2;} INT?)\n" + " {System.out.println($ID+\", \"+x);}\n" + " ;\n"; @@ -256,7 +258,7 @@ public class TestTreeParsing extends BaseTest { "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = - "tree grammar TP; options {tokenVocab=T; ASTLabelType=CommonTree;}\n" + + "tree grammar TP; options {tokenVocab=T; ASTLabelType=CommonAST;}\n" + "a : ^('+' . INT) {System.out.print(\"alt 1\");}"+ " ;\n"; @@ -277,7 +279,7 @@ public class TestTreeParsing extends BaseTest { "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = - "tree grammar TP; options {tokenVocab=T; ASTLabelType=CommonTree;}\n" + + "tree grammar TP; options {tokenVocab=T; ASTLabelType=CommonAST;}\n" + "a : ^('+' . INT) {System.out.print(\"alt 1\");}"+ " | ^('+' . .) {System.out.print(\"alt 2\");}\n" + " ;\n"; @@ -301,7 +303,7 @@ public class TestTreeParsing extends BaseTest { "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = - "tree grammar TP; options {tokenVocab=T; ASTLabelType=CommonTree;}\n" + + "tree grammar TP; options {tokenVocab=T; ASTLabelType=CommonAST;}\n" + "a : ^('+' ID INT) {System.out.print(\"alt 1\");}"+ " | ^('+' . .) {System.out.print(\"alt 2\");}\n" + " ;\n"; @@ -325,7 +327,7 @@ public class TestTreeParsing extends BaseTest { "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = - "tree grammar TP; options {tokenVocab=T; ASTLabelType=CommonTree;}\n" + + "tree grammar TP; options {tokenVocab=T; ASTLabelType=CommonAST;}\n" + "a : ^('+' INT INT ) {System.out.print(\"alt 1\");}"+ " | ^('+' .+) {System.out.print(\"alt 2\");}\n" + " ;\n";