-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updates to trtree with various tree output styles.
- Loading branch information
Showing
4 changed files
with
224 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,122 +1,224 @@ | ||
using Antlr4.Runtime; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Reflection.Emit; | ||
using System.Text; | ||
|
||
namespace ParseTreeEditing.UnvParseTreeDOM | ||
namespace ParseTreeEditing.UnvParseTreeDOM; | ||
|
||
public class TreeOutput | ||
{ | ||
public class TreeOutput | ||
private static int changed = 0; | ||
private static bool first_time = true; | ||
|
||
public static StringBuilder OutputTree(UnvParseTreeNode tree, Lexer lexer, Parser parser) | ||
{ | ||
private static int changed = 0; | ||
private static bool first_time = true; | ||
changed = 0; | ||
first_time = true; | ||
var sb = new StringBuilder(); | ||
ParenthesizedAST(tree, sb, lexer, parser); | ||
return sb; | ||
} | ||
|
||
public static StringBuilder OutputTree(UnvParseTreeNode tree, Lexer lexer, Parser parser) | ||
private static void ParenthesizedAST(UnvParseTreeNode tree, StringBuilder sb, Lexer lexer, Parser parser, int level = 0) | ||
{ | ||
// Antlr always names a non-terminal with first letter lowercase, | ||
// but renames it when creating the type in C#. So, remove the prefix, | ||
// lowercase the first letter, and remove the trailing "Context" part of | ||
// the name. Saves big time on output! | ||
if (tree is UnvParseTreeText t) | ||
{ | ||
changed = 0; | ||
first_time = true; | ||
var sb = new StringBuilder(); | ||
ParenthesizedAST(tree, sb, lexer, parser); | ||
return sb; | ||
StartLine(sb, level); | ||
sb.Append( | ||
"( " | ||
+ " text:'" + PerformEscapes(t.Data) + "'" | ||
+ " tt:" + t.TokenType | ||
+ " chnl:" + lexer.ChannelNames[t.Channel] | ||
//+ " l:" + t.Line | ||
//+ " c:" + t.Column | ||
//+ " si:" + t.StartIndex | ||
//+ " ei:" + t.StopIndex | ||
//+ " ti:" + t.TokenIndex | ||
); | ||
sb.AppendLine(); | ||
} | ||
|
||
private static void ParenthesizedAST(UnvParseTreeNode tree, StringBuilder sb, Lexer lexer, Parser parser, int level = 0) | ||
else if (tree is UnvParseTreeAttr a) | ||
{ | ||
// Antlr always names a non-terminal with first letter lowercase, | ||
// but renames it when creating the type in C#. So, remove the prefix, | ||
// lowercase the first letter, and remove the trailing "Context" part of | ||
// the name. Saves big time on output! | ||
if (tree is UnvParseTreeText t) | ||
StartLine(sb, level); | ||
sb.Append("( Attribute " + a.Name as string); | ||
sb.Append(" Value '"); | ||
sb.Append(PerformEscapes(a.StringValue)); | ||
sb.Append("'"); | ||
if (a.Channel >= 0 && a.Channel < lexer.ChannelNames.Length) | ||
{ | ||
StartLine(sb, level); | ||
sb.Append( | ||
"( " | ||
+ " text:'" + PerformEscapes(t.Data) + "'" | ||
+ " tt:" + t.TokenType | ||
+ " chnl:" + lexer.ChannelNames[t.Channel] | ||
//+ " l:" + t.Line | ||
//+ " c:" + t.Column | ||
//+ " si:" + t.StartIndex | ||
//+ " ei:" + t.StopIndex | ||
//+ " ti:" + t.TokenIndex | ||
); | ||
sb.AppendLine(); | ||
sb.Append(" chnl:"); | ||
sb.Append(lexer.ChannelNames[a.Channel].ToString()); | ||
} | ||
else if (tree is UnvParseTreeAttr a) | ||
{ | ||
StartLine(sb, level); | ||
sb.Append("( Attribute " + a.Name as string); | ||
sb.Append(" Value '"); | ||
sb.Append(PerformEscapes(a.StringValue)); | ||
sb.Append("'"); | ||
if (a.Channel >= 0 && a.Channel < lexer.ChannelNames.Length) | ||
{ | ||
sb.Append(" chnl:"); | ||
sb.Append(lexer.ChannelNames[a.Channel].ToString()); | ||
} | ||
sb.AppendLine(); | ||
} | ||
else if (tree is UnvParseTreeElement e) | ||
{ | ||
var x = e; | ||
var name = e.LocalName; | ||
StartLine(sb, level); | ||
sb.Append( | ||
"( " + name | ||
); | ||
sb.AppendLine(); | ||
} | ||
for (int i = 0; tree.ChildNodes != null && i < tree.ChildNodes.Length; ++i) | ||
{ | ||
var c = tree.ChildNodes.item(i); | ||
ParenthesizedAST(c as UnvParseTreeNode, sb, lexer, parser, level + 1); | ||
} | ||
if (level == 0) | ||
sb.AppendLine(); | ||
} | ||
else if (tree is UnvParseTreeElement e) | ||
{ | ||
var x = e; | ||
var name = e.LocalName; | ||
StartLine(sb, level); | ||
sb.Append( | ||
"( " + name | ||
); | ||
sb.AppendLine(); | ||
} | ||
for (int i = 0; tree.ChildNodes != null && i < tree.ChildNodes.Length; ++i) | ||
{ | ||
var c = tree.ChildNodes.item(i); | ||
ParenthesizedAST(c as UnvParseTreeNode, sb, lexer, parser, level + 1); | ||
} | ||
if (level == 0) | ||
{ | ||
for (int k = 0; k < 1 + changed - level; ++k) sb.Append(") "); | ||
sb.AppendLine(); | ||
changed = 0; | ||
} | ||
} | ||
|
||
private static void StartLine(StringBuilder sb, int level = 0) | ||
{ | ||
if (changed - level >= 0) | ||
{ | ||
if (!first_time) | ||
{ | ||
for (int j = 0; j < level; ++j) sb.Append(" "); | ||
for (int k = 0; k < 1 + changed - level; ++k) sb.Append(") "); | ||
sb.AppendLine(); | ||
changed = 0; | ||
} | ||
changed = 0; | ||
first_time = false; | ||
} | ||
changed = level; | ||
for (int j = 0; j < level; ++j) sb.Append(" "); | ||
} | ||
|
||
private static void StartLine(StringBuilder sb, int level = 0) | ||
private static string ToLiteral(string input) | ||
{ | ||
using (var writer = new StringWriter()) | ||
{ | ||
if (changed - level >= 0) | ||
{ | ||
if (!first_time) | ||
{ | ||
for (int j = 0; j < level; ++j) sb.Append(" "); | ||
for (int k = 0; k < 1 + changed - level; ++k) sb.Append(") "); | ||
sb.AppendLine(); | ||
} | ||
changed = 0; | ||
first_time = false; | ||
} | ||
changed = level; | ||
for (int j = 0; j < level; ++j) sb.Append(" "); | ||
var literal = input; | ||
literal = literal.Replace("\\", "\\\\"); | ||
literal = literal.Replace("\b", "\\b"); | ||
literal = literal.Replace("\n", "\\n"); | ||
literal = literal.Replace("\t", "\\t"); | ||
literal = literal.Replace("\r", "\\r"); | ||
literal = literal.Replace("\f", "\\f"); | ||
literal = literal.Replace("\"", "\\\""); | ||
literal = literal.Replace(string.Format("\" +{0}\t\"", Environment.NewLine), ""); | ||
return literal; | ||
} | ||
} | ||
|
||
private static string ToLiteral(string input) | ||
public static string PerformEscapes(string s) | ||
{ | ||
StringBuilder new_s = new StringBuilder(); | ||
new_s.Append(ToLiteral(s)); | ||
return new_s.ToString(); | ||
} | ||
|
||
public static StringBuilder OutputTreeAntlrStyle(UnvParseTreeNode tree, Lexer lexer, Parser parser) | ||
{ | ||
changed = 0; | ||
first_time = true; | ||
var sb = new StringBuilder(); | ||
AntlrParenthesizedAST(tree, sb, lexer, parser); | ||
return sb; | ||
} | ||
|
||
private static void AntlrParenthesizedAST(UnvParseTreeNode tree, StringBuilder sb, Lexer lexer, Parser parser, int level = 0) | ||
{ | ||
if (tree is UnvParseTreeText t) | ||
{ | ||
sb.Append(" " + PerformEscapes(t.Data)); | ||
return; | ||
} | ||
else if (tree is UnvParseTreeAttr a) | ||
{ | ||
using (var writer = new StringWriter()) | ||
return; | ||
} | ||
else if (tree is UnvParseTreeElement e) | ||
{ | ||
var x = e; | ||
var name = e.LocalName; | ||
sb.Append(" (" + name); | ||
} | ||
for (int i = 0; tree.ChildNodes != null && i < tree.ChildNodes.Length; ++i) | ||
{ | ||
var c = tree.ChildNodes.item(i); | ||
AntlrParenthesizedAST(c as UnvParseTreeNode, sb, lexer, parser, level + 1); | ||
} | ||
sb.Append(")"); | ||
} | ||
|
||
public static StringBuilder OutputTreeIndentStyle(UnvParseTreeNode tree, Lexer lexer, Parser parser) | ||
{ | ||
changed = 0; | ||
first_time = true; | ||
var sb = new StringBuilder(); | ||
IndentAST(tree, sb, lexer, parser); | ||
return sb; | ||
} | ||
|
||
public static void IndentAST(UnvParseTreeNode tree, StringBuilder sb, Lexer lexer, Parser parser, int level = 0) | ||
{ | ||
if (tree is UnvParseTreeText t) | ||
{ | ||
IndentStartLine(sb, level); | ||
sb.Append( | ||
"" | ||
+ "'" + PerformEscapes(t.Data) + "'" | ||
); | ||
sb.AppendLine(); | ||
} | ||
else if (tree is UnvParseTreeAttr a) | ||
{ | ||
IndentStartLine(sb, level); | ||
sb.Append("Attribute " + a.Name as string); | ||
sb.Append(" Value '"); | ||
sb.Append(PerformEscapes(a.StringValue)); | ||
sb.Append("'"); | ||
if (a.Channel >= 0 && a.Channel < lexer.ChannelNames.Length) | ||
{ | ||
var literal = input; | ||
literal = literal.Replace("\\", "\\\\"); | ||
literal = literal.Replace("\b", "\\b"); | ||
literal = literal.Replace("\n", "\\n"); | ||
literal = literal.Replace("\t", "\\t"); | ||
literal = literal.Replace("\r", "\\r"); | ||
literal = literal.Replace("\f", "\\f"); | ||
literal = literal.Replace("\"", "\\\""); | ||
literal = literal.Replace(string.Format("\" +{0}\t\"", Environment.NewLine), ""); | ||
return literal; | ||
sb.Append(" chnl:"); | ||
sb.Append(lexer.ChannelNames[a.Channel].ToString()); | ||
} | ||
sb.AppendLine(); | ||
} | ||
else if (tree is UnvParseTreeElement e) | ||
{ | ||
var x = e; | ||
var name = e.LocalName; | ||
IndentStartLine(sb, level); | ||
sb.Append(name); | ||
sb.AppendLine(); | ||
} | ||
for (int i = 0; tree.ChildNodes != null && i < tree.ChildNodes.Length; ++i) | ||
{ | ||
var c = tree.ChildNodes.item(i); | ||
IndentAST(c as UnvParseTreeNode, sb, lexer, parser, level + 1); | ||
} | ||
if (level == 0) | ||
{ | ||
sb.AppendLine(); | ||
changed = 0; | ||
} | ||
} | ||
|
||
public static string PerformEscapes(string s) | ||
private static void IndentStartLine(StringBuilder sb, int level = 0) | ||
{ | ||
if (changed - level >= 0) | ||
{ | ||
StringBuilder new_s = new StringBuilder(); | ||
new_s.Append(ToLiteral(s)); | ||
return new_s.ToString(); | ||
changed = 0; | ||
first_time = false; | ||
} | ||
changed = level; | ||
for (int j = 0; j < level; ++j) sb.Append(" "); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters