Skip to content

Commit 1ef5bbc

Browse files
committed
Added Code Grapher project to handle parse tree graphing logic.
1 parent 5ce5e29 commit 1ef5bbc

File tree

6 files changed

+360
-0
lines changed

6 files changed

+360
-0
lines changed

Code Grapher/Code Grapher.csproj

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{EC6F674C-4D48-40C4-B28B-85627C1EA3CE}</ProjectGuid>
8+
<OutputType>Library</OutputType>
9+
<AppDesignerFolder>Properties</AppDesignerFolder>
10+
<RootNamespace>Org.Edgerunner.ANTLR4.Tools.Graphing</RootNamespace>
11+
<AssemblyName>Edgerunner.ANTLR4.Tools.Graphing</AssemblyName>
12+
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
13+
<FileAlignment>512</FileAlignment>
14+
<Deterministic>true</Deterministic>
15+
</PropertyGroup>
16+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17+
<DebugSymbols>true</DebugSymbols>
18+
<DebugType>full</DebugType>
19+
<Optimize>false</Optimize>
20+
<OutputPath>bin\Debug\</OutputPath>
21+
<DefineConstants>DEBUG;TRACE</DefineConstants>
22+
<ErrorReport>prompt</ErrorReport>
23+
<WarningLevel>4</WarningLevel>
24+
</PropertyGroup>
25+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
26+
<DebugType>pdbonly</DebugType>
27+
<Optimize>true</Optimize>
28+
<OutputPath>bin\Release\</OutputPath>
29+
<DefineConstants>TRACE</DefineConstants>
30+
<ErrorReport>prompt</ErrorReport>
31+
<WarningLevel>4</WarningLevel>
32+
</PropertyGroup>
33+
<ItemGroup>
34+
<Reference Include="Antlr4.Runtime, Version=4.6.0.0, Culture=neutral, PublicKeyToken=09abb75b9ed49849, processorArchitecture=MSIL">
35+
<HintPath>..\packages\Antlr4.Runtime.4.6.6\lib\net45\Antlr4.Runtime.dll</HintPath>
36+
</Reference>
37+
<Reference Include="Microsoft.Msagl, Version=3.0.0.0, Culture=neutral, PublicKeyToken=640c57aa40e7ae7d, processorArchitecture=MSIL">
38+
<HintPath>..\packages\Microsoft.Msagl.1.1.3\lib\net40\Microsoft.Msagl.dll</HintPath>
39+
</Reference>
40+
<Reference Include="Microsoft.Msagl.Drawing, Version=3.0.0.0, Culture=neutral, PublicKeyToken=8a3d7c21d5fa1306, processorArchitecture=MSIL">
41+
<HintPath>..\packages\Microsoft.Msagl.Drawing.1.1.3\lib\net40\Microsoft.Msagl.Drawing.dll</HintPath>
42+
</Reference>
43+
<Reference Include="System" />
44+
<Reference Include="System.Core" />
45+
<Reference Include="System.Xml.Linq" />
46+
<Reference Include="System.Data.DataSetExtensions" />
47+
<Reference Include="Microsoft.CSharp" />
48+
<Reference Include="System.Data" />
49+
<Reference Include="System.Net.Http" />
50+
<Reference Include="System.Xml" />
51+
</ItemGroup>
52+
<ItemGroup>
53+
<Compile Include="IParseTreeGrapher.cs" />
54+
<Compile Include="ParseTreeGrapher.cs" />
55+
<Compile Include="Properties\AssemblyInfo.cs" />
56+
</ItemGroup>
57+
<ItemGroup>
58+
<None Include="packages.config" />
59+
</ItemGroup>
60+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
61+
</Project>

Code Grapher/IParseTreeGrapher.cs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#region BSD 3-Clause License
2+
3+
// <copyright file="IParseTreeGrapher.cs" company="Edgerunner.org">
4+
// Copyright Thaddeus Ryker
5+
// </copyright>
6+
//
7+
// BSD 3-Clause License
8+
//
9+
// Copyright (c) , Thaddeus Ryker
10+
// All rights reserved.
11+
//
12+
// Redistribution and use in source and binary forms, with or without
13+
// modification, are permitted provided that the following conditions are met:
14+
//
15+
// 1. Redistributions of source code must retain the above copyright notice, this
16+
// list of conditions and the following disclaimer.
17+
//
18+
// 2. Redistributions in binary form must reproduce the above copyright notice,
19+
// this list of conditions and the following disclaimer in the documentation
20+
// and/or other materials provided with the distribution.
21+
//
22+
// 3. Neither the name of the copyright holder nor the names of its
23+
// contributors may be used to endorse or promote products derived from
24+
// this software without specific prior written permission.
25+
//
26+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29+
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
30+
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31+
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32+
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33+
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
34+
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36+
37+
#endregion
38+
39+
using System.Collections.Generic;
40+
41+
using Antlr4.Runtime.Tree;
42+
43+
using Microsoft.Msagl.Drawing;
44+
45+
namespace Org.Edgerunner.ANTLR4.Tools.Graphing
46+
{
47+
/// <summary>
48+
/// Interface that represents a parse tree graphing tool
49+
/// </summary>
50+
public interface IParseTreeGrapher
51+
{
52+
/// <summary>
53+
/// Gets the subject parse tree to graph.
54+
/// </summary>
55+
/// <value>The subject tree.</value>
56+
ITree Subject { get; }
57+
58+
/// <summary>
59+
/// Gets the parser rules.
60+
/// </summary>
61+
/// <value>The parser rules.</value>
62+
IList<string> ParserRules { get; }
63+
64+
/// <summary>
65+
/// Gets or sets the color of the background.
66+
/// </summary>
67+
/// <value>The color of the background.</value>
68+
Color? BackgroundColor { get; set; }
69+
70+
/// <summary>
71+
/// Gets or sets the color of the text.
72+
/// </summary>
73+
/// <value>The color of the text.</value>
74+
Color? TextColor { get; set; }
75+
76+
/// <summary>
77+
/// Gets or sets the color of the border.
78+
/// </summary>
79+
/// <value>The color of the border.</value>
80+
Color? BorderColor { get; set; }
81+
82+
/// <summary>
83+
/// Creates the parse tree graph.
84+
/// </summary>
85+
/// <returns>A new <see cref="Graph"/>.</returns>
86+
Graph CreateGraph();
87+
}
88+
}

Code Grapher/ParseTreeGrapher.cs

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
#region BSD 3-Clause License
2+
3+
// <copyright file="ParseTreeGrapher.cs" company="Edgerunner.org">
4+
// Copyright 2020 Thaddeus Ryker
5+
// </copyright>
6+
//
7+
// BSD 3-Clause License
8+
//
9+
// Copyright (c) 2020, Thaddeus Ryker
10+
// All rights reserved.
11+
//
12+
// Redistribution and use in source and binary forms, with or without
13+
// modification, are permitted provided that the following conditions are met:
14+
//
15+
// 1. Redistributions of source code must retain the above copyright notice, this
16+
// list of conditions and the following disclaimer.
17+
//
18+
// 2. Redistributions in binary form must reproduce the above copyright notice,
19+
// this list of conditions and the following disclaimer in the documentation
20+
// and/or other materials provided with the distribution.
21+
//
22+
// 3. Neither the name of the copyright holder nor the names of its
23+
// contributors may be used to endorse or promote products derived from
24+
// this software without specific prior written permission.
25+
//
26+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29+
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
30+
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31+
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32+
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33+
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
34+
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36+
37+
#endregion
38+
39+
using System;
40+
using System.Collections.Generic;
41+
42+
using Antlr4.Runtime;
43+
using Antlr4.Runtime.Tree;
44+
45+
using Microsoft.Msagl.Drawing;
46+
47+
namespace Org.Edgerunner.ANTLR4.Tools.Graphing
48+
{
49+
/// <summary>
50+
/// Class used to graph ANTLR4 parse trees.
51+
/// </summary>
52+
/// <remarks>This class uses Microsoft's Automatic Graph Layout Library to do the actual dirty work.</remarks>
53+
public class ParseTreeGrapher : IParseTreeGrapher
54+
{
55+
#region Constructors And Finalizers
56+
57+
/// <summary>
58+
/// Initializes a new instance of the <see cref="ParseTreeGrapher" /> class.
59+
/// </summary>
60+
/// <param name="tree">The tree to graph.</param>
61+
/// <param name="rules">The parser rules.</param>
62+
/// <seealso cref="Antlr4.Runtime.Tree.ITree" />
63+
public ParseTreeGrapher(ITree tree, IList<string> rules)
64+
{
65+
Subject = tree;
66+
ParserRules = rules ?? new List<string>();
67+
}
68+
69+
#endregion
70+
71+
/// <summary>
72+
/// Gets the subject parse tree to graph.
73+
/// </summary>
74+
/// <value>The subject tree.</value>
75+
public ITree Subject { get; }
76+
77+
/// <summary>
78+
/// Gets the parser rules.
79+
/// </summary>
80+
/// <value>The parser rules.</value>
81+
public IList<string> ParserRules { get; }
82+
83+
/// <summary>
84+
/// Gets or sets the color of the background.
85+
/// </summary>
86+
/// <value>The color of the background.</value>
87+
public Color? BackgroundColor { get; set; }
88+
89+
/// <summary>
90+
/// Gets or sets the color of the text.
91+
/// </summary>
92+
/// <value>The color of the text.</value>
93+
public Color? TextColor { get; set; }
94+
95+
/// <summary>
96+
/// Gets or sets the color of the border.
97+
/// </summary>
98+
/// <value>The color of the border.</value>
99+
public Color? BorderColor { get; set; }
100+
101+
/// <summary>
102+
/// Creates the parse tree graph.
103+
/// </summary>
104+
/// <returns>A new <see cref="Graph"/>.</returns>
105+
public Graph CreateGraph()
106+
{
107+
var graph = new Graph();
108+
if (Subject != null)
109+
{
110+
GraphEdges(graph, Subject);
111+
FormatNodes(graph, Subject);
112+
}
113+
114+
return graph;
115+
}
116+
117+
private void GraphEdges(Graph graph, ITree tree)
118+
{
119+
for (var i = tree.ChildCount - 1; i > -1; i--)
120+
{
121+
var child = tree.GetChild(i);
122+
graph.AddEdge(tree.GetHashCode().ToString(), child.GetHashCode().ToString());
123+
124+
GraphEdges(graph, child);
125+
}
126+
}
127+
128+
private void FormatNodes(Graph graph, ITree tree)
129+
{
130+
var node = graph.FindNode(tree.GetHashCode().ToString());
131+
if (node != null)
132+
{
133+
node.LabelText = Trees.GetNodeText(tree, ParserRules);
134+
135+
var ruleFailedAndMatchedNothing = false;
136+
137+
if (tree is ParserRuleContext context)
138+
ruleFailedAndMatchedNothing =
139+
// ReSharper disable once ComplexConditionExpression
140+
context.exception != null &&
141+
context.stop != null
142+
&& context.stop.TokenIndex < context.start.TokenIndex;
143+
144+
if (TextColor.HasValue || tree is IErrorNode || ruleFailedAndMatchedNothing)
145+
if (tree is IErrorNode || ruleFailedAndMatchedNothing)
146+
node.Label.FontColor = Color.Red;
147+
else
148+
node.Label.FontColor = TextColor.Value;
149+
150+
if (BackgroundColor.HasValue)
151+
node.Attr.FillColor = BackgroundColor.Value;
152+
153+
if (BorderColor.HasValue)
154+
node.Attr.Color = BorderColor.Value;
155+
156+
node.UserData = tree;
157+
}
158+
159+
for (int i = 0; i < tree.ChildCount; i++)
160+
FormatNodes(graph, tree.GetChild(i));
161+
}
162+
}
163+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
// General Information about an assembly is controlled through the following
6+
// set of attributes. Change these attribute values to modify the information
7+
// associated with an assembly.
8+
[assembly: AssemblyTitle("Code Grapher")]
9+
[assembly: AssemblyDescription("")]
10+
[assembly: AssemblyConfiguration("")]
11+
[assembly: AssemblyCompany("")]
12+
[assembly: AssemblyProduct("Code Grapher")]
13+
[assembly: AssemblyCopyright("Copyright © 2020")]
14+
[assembly: AssemblyTrademark("")]
15+
[assembly: AssemblyCulture("")]
16+
17+
// Setting ComVisible to false makes the types in this assembly not visible
18+
// to COM components. If you need to access a type in this assembly from
19+
// COM, set the ComVisible attribute to true on that type.
20+
[assembly: ComVisible(false)]
21+
22+
// The following GUID is for the ID of the typelib if this project is exposed to COM
23+
[assembly: Guid("ec6f674c-4d48-40c4-b28b-85627c1ea3ce")]
24+
25+
// Version information for an assembly consists of the following four values:
26+
//
27+
// Major Version
28+
// Minor Version
29+
// Build Number
30+
// Revision
31+
//
32+
// You can specify all the values or you can default the Build and Revision Numbers
33+
// by using the '*' as shown below:
34+
// [assembly: AssemblyVersion("1.0.*")]
35+
[assembly: AssemblyVersion("1.0.20065.5")]
36+
[assembly: AssemblyFileVersion("1.0.20065.5")]

Code Grapher/packages.config

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<packages>
3+
<package id="Antlr4.Runtime" version="4.6.6" targetFramework="net461" />
4+
<package id="Microsoft.Msagl" version="1.1.3" targetFramework="net461" />
5+
<package id="Microsoft.Msagl.Drawing" version="1.1.3" targetFramework="net461" />
6+
</packages>

Grun.Net.sln

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
1717
Settings.StyleCop = Settings.StyleCop
1818
EndProjectSection
1919
EndProject
20+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Code Grapher", "Code Grapher\Code Grapher.csproj", "{EC6F674C-4D48-40C4-B28B-85627C1EA3CE}"
21+
EndProject
2022
Global
2123
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2224
Debug|Any CPU = Debug|Any CPU
@@ -35,6 +37,10 @@ Global
3537
{4E020F1D-27BF-4853-8573-474D7EDB4E72}.Debug|Any CPU.Build.0 = Debug|Any CPU
3638
{4E020F1D-27BF-4853-8573-474D7EDB4E72}.Release|Any CPU.ActiveCfg = Release|Any CPU
3739
{4E020F1D-27BF-4853-8573-474D7EDB4E72}.Release|Any CPU.Build.0 = Release|Any CPU
40+
{EC6F674C-4D48-40C4-B28B-85627C1EA3CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
41+
{EC6F674C-4D48-40C4-B28B-85627C1EA3CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
42+
{EC6F674C-4D48-40C4-B28B-85627C1EA3CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
43+
{EC6F674C-4D48-40C4-B28B-85627C1EA3CE}.Release|Any CPU.Build.0 = Release|Any CPU
3844
EndGlobalSection
3945
GlobalSection(SolutionProperties) = preSolution
4046
HideSolutionNode = FALSE

0 commit comments

Comments
 (0)