1 /* 2 * [The "BSD licence"] 3 * Copyright (c) 2005-2008 Terence Parr 4 * All rights reserved. 5 * 6 * Conversion to C#: 7 * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 namespace Antlr.Runtime.Tree { 34 using Console = System.Console; 35 36 public class TreeRewriter<TTree> : TreeParser { 37 protected ITokenStream originalTokenStream; 38 protected ITreeAdaptor originalAdaptor; 39 40 System.Func<IAstRuleReturnScope<TTree>> topdown_func; 41 System.Func<IAstRuleReturnScope<TTree>> bottomup_func; 42 TreeRewriter(ITreeNodeStream input)43 public TreeRewriter(ITreeNodeStream input) 44 : this(input, new RecognizerSharedState()) { 45 } TreeRewriter(ITreeNodeStream input, RecognizerSharedState state)46 public TreeRewriter(ITreeNodeStream input, RecognizerSharedState state) 47 : base(input, state) { 48 originalAdaptor = input.TreeAdaptor; 49 originalTokenStream = input.TokenStream; 50 topdown_func = () => Topdown(); 51 bottomup_func = () => Bottomup(); 52 } 53 ApplyOnce(object t, System.Func<IAstRuleReturnScope<TTree>> whichRule)54 public virtual object ApplyOnce(object t, System.Func<IAstRuleReturnScope<TTree>> whichRule) { 55 if (t == null) 56 return null; 57 58 try { 59 // share TreeParser object but not parsing-related state 60 state = new RecognizerSharedState(); 61 input = new CommonTreeNodeStream(originalAdaptor, t); 62 ((CommonTreeNodeStream)input).TokenStream = originalTokenStream; 63 BacktrackingLevel = 1; 64 IAstRuleReturnScope<TTree> r = whichRule(); 65 BacktrackingLevel = 0; 66 if (Failed) 67 return t; 68 69 if (typeof(CommonTree).IsAssignableFrom(typeof(TTree))) { 70 if (r != null && !t.Equals(r.Tree) && r.Tree != null) { 71 // show any transformations 72 Console.Out.WriteLine(((CommonTree)t).ToStringTree() + " -> " + 73 ((CommonTree)(object)r.Tree).ToStringTree()); 74 } 75 } 76 77 if (r != null && r.Tree != null) 78 return r.Tree; 79 else 80 return t; 81 } catch (RecognitionException) { 82 } 83 return t; 84 } 85 ApplyRepeatedly(object t, System.Func<IAstRuleReturnScope<TTree>> whichRule)86 public virtual object ApplyRepeatedly(object t, System.Func<IAstRuleReturnScope<TTree>> whichRule) { 87 bool treeChanged = true; 88 while (treeChanged) { 89 object u = ApplyOnce(t, whichRule); 90 treeChanged = !t.Equals(u); 91 t = u; 92 } 93 return t; 94 } 95 Downup(object t)96 public virtual object Downup(object t) { 97 TreeVisitor v = new TreeVisitor(new CommonTreeAdaptor()); 98 t = v.Visit(t, (o) => ApplyOnce(o, topdown_func), (o) => ApplyRepeatedly(o, bottomup_func)); 99 return t; 100 } 101 102 // methods the downup strategy uses to do the up and down rules. 103 // to override, just define tree grammar rule topdown and turn on 104 // filter=true. Topdown()105 public virtual IAstRuleReturnScope<TTree> Topdown() { 106 return null; 107 } 108 Bottomup()109 public virtual IAstRuleReturnScope<TTree> Bottomup() { 110 return null; 111 } 112 } 113 } 114