1 /*
2  * Copyright (c) 2012-2020 The ANTLR Project. All rights reserved.
3  * Use of this file is governed by the BSD 3-clause license that
4  * can be found in the LICENSE.txt file in the project root.
5  */
6 
7 module antlr.v4.runtime.dfa.DFASerializer;
8 
9 import std.array;
10 import std.conv;
11 import antlr.v4.runtime.dfa.DFA;
12 import antlr.v4.runtime.dfa.DFAState;
13 import antlr.v4.runtime.Vocabulary;
14 import antlr.v4.runtime.VocabularyImpl;
15 
16 /**
17  * @uml
18  * A DFA walker that knows how to dump them to serialized strings.
19  */
20 class DFASerializer
21 {
22 
23     public DFA dfa;
24 
25     public Vocabulary vocabulary;
26 
27     public this(DFA dfa, string[] tokenNames)
28     {
29         this(dfa, VocabularyImpl.fromTokenNames(tokenNames));
30     }
31 
32     public this(DFA dfa, Vocabulary vocabulary)
33     {
34         this.dfa = dfa;
35         this.vocabulary = vocabulary;
36     }
37 
38     /**
39      * @uml
40      * @override
41      */
42     public override string toString()
43     {
44         if (dfa.s0 is null)
45             return null;
46         auto buf = appender!string;
47         DFAState[] states = dfa.getStates;
48         foreach (DFAState s; states) {
49             uint n = 0;
50             if (s.edges !is null)
51                 n = to!uint(s.edges.length);
52             for (uint i = 0; i < n; i++) {
53                 DFAState t = s.edges[i];
54                 if (t && t.stateNumber != int.max) {
55                     buf.put(getStateString(s));
56                     string label = getEdgeLabel(i);
57                     buf.put("-");
58                     buf.put(label);
59                     buf.put("->");
60                     buf.put(getStateString(t));
61                     buf.put('\n');
62                 }
63             }
64         }
65 
66         string output = buf.data;
67         if (output.length == 0) return null;
68         //return Utils.sortLinesInString(output);
69         return output;
70     }
71 
72     public string getEdgeLabel(int i)
73     {
74         return vocabulary.getDisplayName(i - 1);
75     }
76 
77     public string getStateString(DFAState s)
78     {
79         int n = s.stateNumber;
80         string baseStateStr = (s.isAcceptState ? ":" : "") ~ "s" ~ to!string(n) ~
81             (s.requiresFullContext ? "^" : "");
82         if (s.isAcceptState) {
83             if (s.predicates !is null) {
84                 return baseStateStr ~ "=>" ~ to!string(s.predicates);
85             }
86             else {
87                 return baseStateStr ~ "=>" ~ to!string(s.prediction);
88             }
89         }
90         else {
91             return baseStateStr;
92         }
93 
94     }
95 
96 }