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 // Class DFASerializer
41 /**
42  * @uml
43  * A DFA walker that knows how to dump them to serialized strings.
44  */
45 class DFASerializer
46 {
47 
48     public DFA dfa;
49 
50     public Vocabulary vocabulary;
51 
52     public this(DFA dfa, string[] tokenNames)
53     {
54         this(dfa, VocabularyImpl.fromTokenNames(tokenNames));
55     }
56 
57     public this(DFA dfa, Vocabulary vocabulary)
58     {
59         this.dfa = dfa;
60         this.vocabulary = vocabulary;
61     }
62 
63     /**
64      * @uml
65      * @override
66      */
67     public override string toString()
68     {
69 	if (dfa.s0 is null) return null;
70         auto buf = appender!string;
71         DFAState[] states = dfa.getStates;
72         foreach (DFAState s; states) {
73             size_t n = 0;
74             if (s.edges !is null) n = s.edges.length;
75             for (int i=0; i<n; i++) {
76                 DFAState t = s.edges[i];
77                 if (t !is null && t.stateNumber != int.max) {
78                     buf.put(getStateString(s));
79                     string label = getEdgeLabel(i);
80                     buf.put("-");
81                     buf.put(label);
82                     buf.put("->");
83                     buf.put(getStateString(t));
84                     buf.put('\n');
85                 }
86             }
87         }
88 
89         string output = buf.data;
90         if (output.length == 0) return null;
91         //return Utils.sortLinesInString(output);
92         return output;
93     }
94 
95     public string getEdgeLabel(int i)
96     {
97 	return vocabulary.getDisplayName(i - 1);
98     }
99 
100     public string getStateString(DFAState s)
101     {
102 	int n = s.stateNumber;
103         string baseStateStr = (s.isAcceptState ? ":" : "") ~ "s" ~ to!string(n) ~
104             (s.requiresFullContext ? "^" : "");
105         if (s.isAcceptState) {
106             if (s.predicates !is null) {
107                 return baseStateStr ~ "=>" ~ to!string(s.predicates);
108             }
109             else {
110                 return baseStateStr ~ "=>" ~ to!string(s.prediction);
111             }
112         }
113         else {
114             return baseStateStr;
115         }
116 
117     }
118 
119 }