antlr/Antlr4.Runtime/Dfa/DFASerializer.cs

223 lines
7.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.Atn;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Dfa
{
/// <summary>A DFA walker that knows how to dump them to serialized strings.</summary>
/// <remarks>A DFA walker that knows how to dump them to serialized strings.</remarks>
public class DFASerializer
{
[NotNull]
internal readonly DFA dfa;
[Nullable]
internal readonly string[] tokenNames;
[Nullable]
internal readonly string[] ruleNames;
[Nullable]
internal readonly ATN atn;
public DFASerializer(DFA dfa, string[] tokenNames) : this(dfa, tokenNames, null,
null)
{
}
public DFASerializer(DFA dfa, Recognizer<object, object> parser) : this(dfa, parser
!= null ? parser.GetTokenNames() : null, parser != null ? parser.GetRuleNames
() : null, parser != null ? parser.GetATN() : null)
{
}
public DFASerializer(DFA dfa, string[] tokenNames, string[] ruleNames, ATN atn)
{
this.dfa = dfa;
this.tokenNames = tokenNames;
this.ruleNames = ruleNames;
this.atn = atn;
}
public override string ToString()
{
if (dfa.s0.Get() == null)
{
return null;
}
StringBuilder buf = new StringBuilder();
if (dfa.states != null)
{
IList<DFAState> states = new List<DFAState>(dfa.states.Values);
states.Sort(new _IComparer_85());
foreach (DFAState s in states)
{
IDictionary<int, DFAState> edges = s.EdgeMap;
IDictionary<int, DFAState> contextEdges = s.ContextEdgeMap;
foreach (KeyValuePair<int, DFAState> entry in edges.EntrySet())
{
if ((entry.Value == null || entry.Value == ATNSimulator.Error) && !s.IsContextSymbol
(entry.Key))
{
continue;
}
bool contextSymbol = false;
buf.Append(GetStateString(s)).Append("-").Append(GetEdgeLabel(entry.Key)).Append(
"->");
if (s.IsContextSymbol(entry.Key))
{
buf.Append("!");
contextSymbol = true;
}
DFAState t = entry.Value;
if (t != null && t.stateNumber != int.MaxValue)
{
buf.Append(GetStateString(t)).Append('\n');
}
else
{
if (contextSymbol)
{
buf.Append("ctx\n");
}
}
}
if (s.IsContextSensitive)
{
foreach (KeyValuePair<int, DFAState> entry_1 in contextEdges.EntrySet())
{
buf.Append(GetStateString(s)).Append("-").Append(GetContextLabel(entry_1.Key)).Append
("->").Append(GetStateString(entry_1.Value)).Append("\n");
}
}
}
}
string output = buf.ToString();
//return Utils.sortLinesInString(output);
return output;
}
private sealed class _IComparer_85 : IComparer<DFAState>
{
public _IComparer_85()
{
}
public int Compare(DFAState o1, DFAState o2)
{
return o1.stateNumber - o2.stateNumber;
}
}
protected internal virtual string GetContextLabel(int i)
{
if (i == PredictionContext.EmptyFullStateKey)
{
return "ctx:EMPTY_FULL";
}
else
{
if (i == PredictionContext.EmptyLocalStateKey)
{
return "ctx:EMPTY_LOCAL";
}
}
if (atn != null && i > 0 && i <= atn.states.Count)
{
ATNState state = atn.states[i];
int ruleIndex = state.ruleIndex;
if (ruleNames != null && ruleIndex >= 0 && ruleIndex < ruleNames.Length)
{
return "ctx:" + i.ToString() + "(" + ruleNames[ruleIndex] + ")";
}
}
return "ctx:" + i.ToString();
}
protected internal virtual string GetEdgeLabel(int i)
{
string label;
if (i == -1)
{
return "EOF";
}
if (tokenNames != null)
{
label = tokenNames[i];
}
else
{
label = i.ToString();
}
return label;
}
internal virtual string GetStateString(DFAState s)
{
if (s == ATNSimulator.Error)
{
return "ERROR";
}
int n = s.stateNumber;
string stateStr = "s" + n;
if (s.isAcceptState)
{
if (s.predicates != null)
{
stateStr = ":s" + n + "=>" + Arrays.ToString(s.predicates);
}
else
{
stateStr = ":s" + n + "=>" + s.prediction;
}
}
if (s.IsContextSensitive)
{
stateStr += "*";
foreach (ATNConfig config in s.configs)
{
if (config.GetReachesIntoOuterContext())
{
stateStr += "*";
break;
}
}
}
return stateStr;
}
}
}