PageRenderTime 33ms CodeModel.GetById 27ms app.highlight 5ms RepoModel.GetById 0ms app.codeStats 0ms

/external/antlr/antlr-3.4/runtime/CSharp3/Sources/Antlr3.Runtime/Tree/DotTreeGenerator.cs

https://gitlab.com/brian0218/rk3188_r-box_android4.2.2_sdk
C# | 216 lines | 118 code | 24 blank | 74 comment | 14 complexity | 36699cf6cf275e7a073504a8f677c699 MD5 | raw file
  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 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
 33namespace Antlr.Runtime.Tree
 34{
 35    using System.Collections.Generic;
 36    using StringBuilder = System.Text.StringBuilder;
 37
 38    /** A utility class to generate DOT diagrams (graphviz) from
 39     *  arbitrary trees.  You can pass in your own templates and
 40     *  can pass in any kind of tree or use Tree interface method.
 41     *  I wanted this separator so that you don't have to include
 42     *  ST just to use the org.antlr.runtime.tree.* package.
 43     *  This is a set of non-static methods so you can subclass
 44     *  to override.  For example, here is an invocation:
 45     *
 46     *      CharStream input = new ANTLRInputStream(System.in);
 47     *      TLexer lex = new TLexer(input);
 48     *      CommonTokenStream tokens = new CommonTokenStream(lex);
 49     *      TParser parser = new TParser(tokens);
 50     *      TParser.e_return r = parser.e();
 51     *      Tree t = (Tree)r.tree;
 52     *      System.out.println(t.toStringTree());
 53     *      DOTTreeGenerator gen = new DOTTreeGenerator();
 54     *      StringTemplate st = gen.toDOT(t);
 55     *      System.out.println(st);
 56     */
 57    public class DotTreeGenerator
 58    {
 59        readonly string[] HeaderLines =
 60            {
 61                "digraph {",
 62                "",
 63                "\tordering=out;",
 64                "\tranksep=.4;",
 65                "\tbgcolor=\"lightgrey\"; node [shape=box, fixedsize=false, fontsize=12, fontname=\"Helvetica-bold\", fontcolor=\"blue\"",
 66                "\t\twidth=.25, height=.25, color=\"black\", fillcolor=\"white\", style=\"filled, solid, bold\"];",
 67                "\tedge [arrowsize=.5, color=\"black\", style=\"bold\"]",
 68                ""
 69            };
 70        const string Footer = "}";
 71        const string NodeFormat = "  {0} [label=\"{1}\"];";
 72        const string EdgeFormat = "  {0} -> {1} // \"{2}\" -> \"{3}\"";
 73
 74        /** Track node to number mapping so we can get proper node name back */
 75        Dictionary<object, int> nodeToNumberMap = new Dictionary<object, int>();
 76
 77        /** Track node number so we can get unique node names */
 78        int nodeNumber = 0;
 79
 80        /** Generate DOT (graphviz) for a whole tree not just a node.
 81         *  For example, 3+4*5 should generate:
 82         *
 83         * digraph {
 84         *   node [shape=plaintext, fixedsize=true, fontsize=11, fontname="Courier",
 85         *         width=.4, height=.2];
 86         *   edge [arrowsize=.7]
 87         *   "+"->3
 88         *   "+"->"*"
 89         *   "*"->4
 90         *   "*"->5
 91         * }
 92         *
 93         * Takes a Tree interface object.
 94         */
 95        public virtual string ToDot( object tree, ITreeAdaptor adaptor )
 96        {
 97            StringBuilder builder = new StringBuilder();
 98            foreach ( string line in HeaderLines )
 99                builder.AppendLine( line );
100
101            nodeNumber = 0;
102            var nodes = DefineNodes( tree, adaptor );
103            nodeNumber = 0;
104            var edges = DefineEdges( tree, adaptor );
105
106            foreach ( var s in nodes )
107                builder.AppendLine( s );
108
109            builder.AppendLine();
110
111            foreach ( var s in edges )
112                builder.AppendLine( s );
113
114            builder.AppendLine();
115
116            builder.AppendLine( Footer );
117            return builder.ToString();
118        }
119
120        public virtual string ToDot( ITree tree )
121        {
122            return ToDot( tree, new CommonTreeAdaptor() );
123        }
124        protected virtual IEnumerable<string> DefineNodes( object tree, ITreeAdaptor adaptor )
125        {
126            if ( tree == null )
127                yield break;
128
129            int n = adaptor.GetChildCount( tree );
130            if ( n == 0 )
131            {
132                // must have already dumped as child from previous
133                // invocation; do nothing
134                yield break;
135            }
136
137            // define parent node
138            yield return GetNodeText( adaptor, tree );
139
140            // for each child, do a "<unique-name> [label=text]" node def
141            for ( int i = 0; i < n; i++ )
142            {
143                object child = adaptor.GetChild( tree, i );
144                yield return GetNodeText( adaptor, child );
145                foreach ( var t in DefineNodes( child, adaptor ) )
146                    yield return t;
147            }
148        }
149
150        protected virtual IEnumerable<string> DefineEdges( object tree, ITreeAdaptor adaptor )
151        {
152            if ( tree == null )
153                yield break;
154
155            int n = adaptor.GetChildCount( tree );
156            if ( n == 0 )
157            {
158                // must have already dumped as child from previous
159                // invocation; do nothing
160                yield break;
161            }
162
163            string parentName = "n" + GetNodeNumber( tree );
164
165            // for each child, do a parent -> child edge using unique node names
166            string parentText = adaptor.GetText( tree );
167            for ( int i = 0; i < n; i++ )
168            {
169                object child = adaptor.GetChild( tree, i );
170                string childText = adaptor.GetText( child );
171                string childName = "n" + GetNodeNumber( child );
172                yield return string.Format( EdgeFormat, parentName, childName, FixString( parentText ), FixString( childText ) );
173                foreach ( var t in DefineEdges( child, adaptor ) )
174                    yield return t;
175            }
176        }
177
178        protected virtual string GetNodeText( ITreeAdaptor adaptor, object t )
179        {
180            string text = adaptor.GetText( t );
181            string uniqueName = "n" + GetNodeNumber( t );
182            return string.Format( NodeFormat, uniqueName, FixString( text ) );
183        }
184
185        protected virtual int GetNodeNumber( object t )
186        {
187            int i;
188            if ( nodeToNumberMap.TryGetValue( t, out i ) )
189            {
190                return i;
191            }
192            else
193            {
194                nodeToNumberMap[t] = nodeNumber;
195                nodeNumber++;
196                return nodeNumber - 1;
197            }
198        }
199
200        protected virtual string FixString( string text )
201        {
202            if ( text != null )
203            {
204                text = System.Text.RegularExpressions.Regex.Replace( text, "\"", "\\\\\"" );
205                text = System.Text.RegularExpressions.Regex.Replace( text, "\\t", "    " );
206                text = System.Text.RegularExpressions.Regex.Replace( text, "\\n", "\\\\n" );
207                text = System.Text.RegularExpressions.Regex.Replace( text, "\\r", "\\\\r" );
208
209                if ( text.Length > 20 )
210                    text = text.Substring( 0, 8 ) + "..." + text.Substring( text.Length - 8 );
211            }
212
213            return text;
214        }
215    }
216}