| /* |
| [The "BSD licence"] |
| Copyright (c) 2005-2008 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.eclipse.persistence.internal.libraries.antlr.runtime.tree; |
| |
| import org.eclipse.persistence.internal.libraries.antlr.runtime.RecognizerSharedState; |
| import org.eclipse.persistence.internal.libraries.antlr.runtime.RecognitionException; |
| import org.eclipse.persistence.internal.libraries.antlr.runtime.TokenStream; |
| |
| /** |
| Cut-n-paste from material I'm not using in the book anymore (edit later |
| to make sense): |
| |
| Now, how are we going to test these tree patterns against every |
| subtree in our original tree? In what order should we visit nodes? |
| For this application, it turns out we need a simple ``apply once'' |
| rule application strategy and a ``down then up'' tree traversal |
| strategy. Let's look at rule application first. |
| |
| As we visit each node, we need to see if any of our patterns match. If |
| a pattern matches, we execute the associated tree rewrite and move on |
| to the next node. In other words, we only look for a single rule |
| application opportunity (we'll see below that we sometimes need to |
| repeatedly apply rules). The following method applies a rule in a @cl |
| TreeParser (derived from a tree grammar) to a tree: |
| |
| here is where weReferenced code/walking/patterns/TreePatternMatcher.java |
| |
| It uses reflection to lookup the appropriate rule within the generated |
| tree parser class (@cl Simplify in this case). Most of the time, the |
| rule will not match the tree. To avoid issuing syntax errors and |
| attempting error recovery, it bumps up the backtracking level. Upon |
| failure, the invoked rule immediately returns. If you don't plan on |
| using this technique in your own ANTLR-based application, don't sweat |
| the details. This method boils down to ``call a rule to match a tree, |
| executing any embedded actions and rewrite rules.'' |
| |
| At this point, we know how to define tree grammar rules and how to |
| apply them to a particular subtree. The final piece of the tree |
| pattern matcher is the actual tree traversal. We have to get the |
| correct node visitation order. In particular, we need to perform the |
| scalar-vector multiply transformation on the way down (preorder) and |
| we need to reduce multiply-by-zero subtrees on the way up (postorder). |
| |
| To implement a top-down visitor, we do a depth first walk of the tree, |
| executing an action in the preorder position. To get a bottom-up |
| visitor, we execute an action in the postorder position. ANTLR |
| provides a standard @cl TreeVisitor class with a depth first search @v |
| visit method. That method executes either a @m pre or @m post method |
| or both. In our case, we need to call @m applyOnce in both. On the way |
| down, we'll look for @r vmult patterns. On the way up, |
| we'll look for @r mult0 patterns. |
| */ |
| public class TreeFilter extends TreeParser { |
| public interface fptr { |
| public void rule() throws RecognitionException; |
| } |
| |
| protected TokenStream originalTokenStream; |
| protected TreeAdaptor originalAdaptor; |
| |
| public TreeFilter(TreeNodeStream input) { |
| this(input, new RecognizerSharedState()); |
| } |
| public TreeFilter(TreeNodeStream input, RecognizerSharedState state) { |
| super(input, state); |
| originalAdaptor = input.getTreeAdaptor(); |
| originalTokenStream = input.getTokenStream(); |
| } |
| |
| public void applyOnce(Object t, fptr whichRule) { |
| if ( t==null ) return; |
| try { |
| // share TreeParser object but not parsing-related state |
| state = new RecognizerSharedState(); |
| input = new CommonTreeNodeStream(originalAdaptor, t); |
| ((CommonTreeNodeStream)input).setTokenStream(originalTokenStream); |
| setBacktrackingLevel(1); |
| whichRule.rule(); |
| setBacktrackingLevel(0); |
| } |
| catch (RecognitionException e) { ; } |
| } |
| |
| public void downup(Object t) { |
| TreeVisitor v = new TreeVisitor(new CommonTreeAdaptor()); |
| TreeVisitorAction actions = new TreeVisitorAction() { |
| public Object pre(Object t) { applyOnce(t, topdown_fptr); return t; } |
| public Object post(Object t) { applyOnce(t, bottomup_fptr); return t; } |
| }; |
| v.visit(t, actions); |
| } |
| |
| fptr topdown_fptr = new fptr() { |
| public void rule() throws RecognitionException { |
| topdown(); |
| } |
| }; |
| |
| fptr bottomup_fptr = new fptr() { |
| public void rule() throws RecognitionException { |
| bottomup(); |
| } |
| }; |
| |
| // methods the downup strategy uses to do the up and down rules. |
| // to override, just define tree grammar rule topdown and turn on |
| // filter=true. |
| public void topdown() throws RecognitionException {;} |
| public void bottomup() throws RecognitionException {;} |
| } |