forked from jasder/antlr
180 lines
6.7 KiB
C#
180 lines
6.7 KiB
C#
/*
|
|
* [The "BSD license"]
|
|
* Copyright (c) 2013 Terence Parr
|
|
* Copyright (c) 2013 Sam Harwell
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. The name of the author may not be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using Antlr4.Runtime;
|
|
using Antlr4.Runtime.Misc;
|
|
using Antlr4.Runtime.Tree;
|
|
using Sharpen;
|
|
|
|
namespace Antlr4.Runtime.Tree
|
|
{
|
|
/// <summary>A set of utility routines useful for all kinds of ANTLR trees.</summary>
|
|
/// <remarks>A set of utility routines useful for all kinds of ANTLR trees.</remarks>
|
|
public class Trees
|
|
{
|
|
/// <summary>Print out a whole tree in LISP form.</summary>
|
|
/// <remarks>
|
|
/// Print out a whole tree in LISP form.
|
|
/// <see cref="GetNodeText(ITree, Antlr4.Runtime.Parser)">GetNodeText(ITree, Antlr4.Runtime.Parser)
|
|
/// </see>
|
|
/// is used on the
|
|
/// node payloads to get the text for the nodes. Detect
|
|
/// parse trees and extract data appropriately.
|
|
/// </remarks>
|
|
public static string ToStringTree(ITree t)
|
|
{
|
|
return ToStringTree(t, (IList<string>)null);
|
|
}
|
|
|
|
/// <summary>Print out a whole tree in LISP form.</summary>
|
|
/// <remarks>
|
|
/// Print out a whole tree in LISP form.
|
|
/// <see cref="GetNodeText(ITree, Antlr4.Runtime.Parser)">GetNodeText(ITree, Antlr4.Runtime.Parser)
|
|
/// </see>
|
|
/// is used on the
|
|
/// node payloads to get the text for the nodes. Detect
|
|
/// parse trees and extract data appropriately.
|
|
/// </remarks>
|
|
public static string ToStringTree(ITree t, Parser recog)
|
|
{
|
|
string[] ruleNames = recog != null ? recog.RuleNames : null;
|
|
IList<string> ruleNamesList = ruleNames != null ? Arrays.AsList(ruleNames) : null;
|
|
return ToStringTree(t, ruleNamesList);
|
|
}
|
|
|
|
/// <summary>Print out a whole tree in LISP form.</summary>
|
|
/// <remarks>
|
|
/// Print out a whole tree in LISP form.
|
|
/// <see cref="GetNodeText(ITree, Antlr4.Runtime.Parser)">GetNodeText(ITree, Antlr4.Runtime.Parser)
|
|
/// </see>
|
|
/// is used on the
|
|
/// node payloads to get the text for the nodes. Detect
|
|
/// parse trees and extract data appropriately.
|
|
/// </remarks>
|
|
public static string ToStringTree(ITree t, IList<string> ruleNames)
|
|
{
|
|
string s = Utils.EscapeWhitespace(GetNodeText(t, ruleNames), false);
|
|
if (t.ChildCount == 0)
|
|
{
|
|
return s;
|
|
}
|
|
StringBuilder buf = new StringBuilder();
|
|
buf.Append("(");
|
|
s = Utils.EscapeWhitespace(GetNodeText(t, ruleNames), false);
|
|
buf.Append(s);
|
|
buf.Append(' ');
|
|
for (int i = 0; i < t.ChildCount; i++)
|
|
{
|
|
if (i > 0)
|
|
{
|
|
buf.Append(' ');
|
|
}
|
|
buf.Append(ToStringTree(t.GetChild(i), ruleNames));
|
|
}
|
|
buf.Append(")");
|
|
return buf.ToString();
|
|
}
|
|
|
|
public static string GetNodeText(ITree t, Parser recog)
|
|
{
|
|
string[] ruleNames = recog != null ? recog.RuleNames : null;
|
|
IList<string> ruleNamesList = ruleNames != null ? Arrays.AsList(ruleNames) : null;
|
|
return GetNodeText(t, ruleNamesList);
|
|
}
|
|
|
|
public static string GetNodeText(ITree t, IList<string> ruleNames)
|
|
{
|
|
if (ruleNames != null)
|
|
{
|
|
if (t is IRuleNode)
|
|
{
|
|
int ruleIndex = ((IRuleNode)t).RuleContext.GetRuleIndex();
|
|
string ruleName = ruleNames[ruleIndex];
|
|
return ruleName;
|
|
}
|
|
else
|
|
{
|
|
if (t is IErrorNode)
|
|
{
|
|
return t.ToString();
|
|
}
|
|
else
|
|
{
|
|
if (t is ITerminalNode)
|
|
{
|
|
IToken symbol = ((ITerminalNode)t).Symbol;
|
|
if (symbol != null)
|
|
{
|
|
string s = symbol.Text;
|
|
return s;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// no recog for rule names
|
|
object payload = t.Payload;
|
|
if (payload is IToken)
|
|
{
|
|
return ((IToken)payload).Text;
|
|
}
|
|
return t.Payload.ToString();
|
|
}
|
|
|
|
/// <summary>Return a list of all ancestors of this node.</summary>
|
|
/// <remarks>
|
|
/// Return a list of all ancestors of this node. The first node of
|
|
/// list is the root and the last is the parent of this node.
|
|
/// </remarks>
|
|
[return: NotNull]
|
|
public static IList<ITree> GetAncestors(ITree t)
|
|
{
|
|
if (t.Parent == null)
|
|
{
|
|
return Collections.EmptyList<ITree>();
|
|
}
|
|
IList<ITree> ancestors = new List<ITree>();
|
|
t = t.Parent;
|
|
while (t != null)
|
|
{
|
|
ancestors.Insert(0, t);
|
|
// insert at start
|
|
t = t.Parent;
|
|
}
|
|
return ancestors;
|
|
}
|
|
|
|
private Trees()
|
|
{
|
|
}
|
|
}
|
|
}
|