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 { 35 using Antlr.Runtime.Misc; 36 37 using Console = System.Console; 38 39 public class TreeRewriter : TreeParser 40 { 41 protected bool showTransformations; 42 43 protected ITokenStream originalTokenStream; 44 protected ITreeAdaptor originalAdaptor; 45 46 Func<IAstRuleReturnScope> topdown_func; 47 Func<IAstRuleReturnScope> bottomup_func; 48 TreeRewriter( ITreeNodeStream input )49 public TreeRewriter( ITreeNodeStream input ) 50 : this( input, new RecognizerSharedState() ) 51 { 52 } TreeRewriter( ITreeNodeStream input, RecognizerSharedState state )53 public TreeRewriter( ITreeNodeStream input, RecognizerSharedState state ) 54 : base( input, state ) 55 { 56 originalAdaptor = input.TreeAdaptor; 57 originalTokenStream = input.TokenStream; 58 topdown_func = () => Topdown(); 59 bottomup_func = () => Bottomup(); 60 } 61 ApplyOnce( object t, Func<IAstRuleReturnScope> whichRule )62 public virtual object ApplyOnce( object t, Func<IAstRuleReturnScope> whichRule ) 63 { 64 if ( t == null ) 65 return null; 66 67 try 68 { 69 // share TreeParser object but not parsing-related state 70 SetState(new RecognizerSharedState()); 71 SetTreeNodeStream(new CommonTreeNodeStream(originalAdaptor, t)); 72 ( (CommonTreeNodeStream)input ).TokenStream = originalTokenStream; 73 BacktrackingLevel = 1; 74 IAstRuleReturnScope r = whichRule(); 75 BacktrackingLevel = 0; 76 if ( Failed ) 77 return t; 78 79 if (showTransformations && r != null && !t.Equals(r.Tree) && r.Tree != null) 80 ReportTransformation(t, r.Tree); 81 82 if ( r != null && r.Tree != null ) 83 return r.Tree; 84 else 85 return t; 86 } 87 catch ( RecognitionException ) 88 { 89 } 90 91 return t; 92 } 93 ApplyRepeatedly( object t, Func<IAstRuleReturnScope> whichRule )94 public virtual object ApplyRepeatedly( object t, Func<IAstRuleReturnScope> whichRule ) 95 { 96 bool treeChanged = true; 97 while ( treeChanged ) 98 { 99 object u = ApplyOnce( t, whichRule ); 100 treeChanged = !t.Equals( u ); 101 t = u; 102 } 103 return t; 104 } 105 Downup( object t )106 public virtual object Downup( object t ) 107 { 108 return Downup( t, false ); 109 } 110 Downup( object t, bool showTransformations )111 public virtual object Downup( object t, bool showTransformations ) 112 { 113 this.showTransformations = showTransformations; 114 TreeVisitor v = new TreeVisitor( new CommonTreeAdaptor() ); 115 t = v.Visit( t, ( o ) => ApplyOnce( o, topdown_func ), ( o ) => ApplyRepeatedly( o, bottomup_func ) ); 116 return t; 117 } 118 119 // methods the downup strategy uses to do the up and down rules. 120 // to override, just define tree grammar rule topdown and turn on 121 // filter=true. Topdown()122 protected virtual IAstRuleReturnScope Topdown() 123 { 124 return null; 125 } 126 Bottomup()127 protected virtual IAstRuleReturnScope Bottomup() 128 { 129 return null; 130 } 131 132 /** Override this if you need transformation tracing to go somewhere 133 * other than stdout or if you're not using ITree-derived trees. 134 */ ReportTransformation(object oldTree, object newTree)135 protected virtual void ReportTransformation(object oldTree, object newTree) 136 { 137 ITree old = oldTree as ITree; 138 ITree @new = newTree as ITree; 139 string oldMessage = old != null ? old.ToStringTree() : "??"; 140 string newMessage = @new != null ? @new.ToStringTree() : "??"; 141 Console.WriteLine("{0} -> {1}", oldMessage, newMessage); 142 } 143 } 144 } 145