1 /*
2  * [The "BSD license"]
3  *  Copyright (c) 2012 Terence Parr
4  *  Copyright (c) 2012 Sam Harwell
5  *  All rights reserved.
6  *
7  *  Redistribution and use in source and binary forms, with or without
8  *  modification, are permitted provided that the following conditions
9  *  are met:
10  *
11  *  1. Redistributions of source code must retain the above copyright
12  *     notice, this list of conditions and the following disclaimer.
13  *  2. Redistributions in binary form must reproduce the above copyright
14  *     notice, this list of conditions and the following disclaimer in the
15  *     documentation and/or other materials provided with the distribution.
16  *  3. The name of the author may not be used to endorse or promote products
17  *     derived from this software without specific prior written permission.
18  *
19  *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 module antlr.v4.runtime.dfa.DFASerializer;
32 
33 import std.array;
34 import std.conv;
35 import antlr.v4.runtime.dfa.DFA;
36 import antlr.v4.runtime.dfa.DFAState;
37 import antlr.v4.runtime.Vocabulary;
38 import antlr.v4.runtime.VocabularyImpl;
39 
40 /**
41  * @uml
42  * A DFA walker that knows how to dump them to serialized strings.
43  */
44 class DFASerializer
45 {
46 
47     public DFA dfa;
48 
49     public Vocabulary vocabulary;
50 
51     public this(DFA dfa, string[] tokenNames)
52     {
53         this(dfa, VocabularyImpl.fromTokenNames(tokenNames));
54     }
55 
56     public this(DFA dfa, Vocabulary vocabulary)
57     {
58         this.dfa = dfa;
59         this.vocabulary = vocabulary;
60     }
61 
62     /**
63      * @uml
64      * @override
65      */
66     public override string toString()
67     {
68 	if (dfa.s0 is null) return null;
69         auto buf = appender!string;
70         DFAState[] states = dfa.getStates;
71         foreach (DFAState s; states) {
72             size_t n = 0;
73             if (s.edges !is null) n = s.edges.length;
74             for (int i=0; i<n; i++) {
75                 DFAState t = s.edges[i];
76                 if (t !is null && t.stateNumber != int.max) {
77                     buf.put(getStateString(s));
78                     string label = getEdgeLabel(i);
79                     buf.put("-");
80                     buf.put(label);
81                     buf.put("->");
82                     buf.put(getStateString(t));
83                     buf.put('\n');
84                 }
85             }
86         }
87 
88         string output = buf.data;
89         if (output.length == 0) return null;
90         //return Utils.sortLinesInString(output);
91         return output;
92     }
93 
94     public string getEdgeLabel(int i)
95     {
96 	return vocabulary.getDisplayName(i - 1);
97     }
98 
99     public string getStateString(DFAState s)
100     {
101 	int n = s.stateNumber;
102         string baseStateStr = (s.isAcceptState ? ":" : "") ~ "s" ~ to!string(n) ~
103             (s.requiresFullContext ? "^" : "");
104         if (s.isAcceptState) {
105             if (s.predicates !is null) {
106                 return baseStateStr ~ "=>" ~ to!string(s.predicates);
107             }
108             else {
109                 return baseStateStr ~ "=>" ~ to!string(s.prediction);
110             }
111         }
112         else {
113             return baseStateStr;
114         }
115 
116     }
117 
118 }