|
1 "{ Package: 'stx:goodies/petitparser/compiler' }" |
|
2 |
|
3 "{ NameSpace: Smalltalk }" |
|
4 |
|
5 PPCNodeVisitor subclass:#PEGFsaGenerator |
|
6 instanceVariableNames:'' |
|
7 classVariableNames:'' |
|
8 poolDictionaries:'' |
|
9 category:'PetitCompiler-FSA' |
|
10 ! |
|
11 |
|
12 !PEGFsaGenerator methodsFor:'as yet unclassified'! |
|
13 |
|
14 visitCharSetPredicateNode: node |
|
15 | stop start fsa | |
|
16 start := PEGFsaState new. |
|
17 stop := PEGFsaState new. |
|
18 |
|
19 fsa := PEGFsa new |
|
20 addState: start; |
|
21 addState: stop; |
|
22 |
|
23 startState: start; |
|
24 finalState: stop; |
|
25 yourself. |
|
26 |
|
27 fsa addTransitionFrom: start to: stop onCharacterSet: (node predicate classification). |
|
28 |
|
29 ^ fsa |
|
30 ! |
|
31 |
|
32 visitCharacterNode: node |
|
33 | stop start | |
|
34 start := PEGFsaState new. |
|
35 stop := PEGFsaState new. |
|
36 stop name: node character storeString. |
|
37 |
|
38 ^ PEGFsa new |
|
39 addState: start; |
|
40 addState: stop; |
|
41 |
|
42 startState: start; |
|
43 finalState: stop; |
|
44 |
|
45 addTransitionFrom: start to: stop on: node character; |
|
46 yourself |
|
47 ! |
|
48 |
|
49 visitChoiceNode: node |
|
50 | priority childrenFsa fsa start | |
|
51 |
|
52 childrenFsa := node children collect: [ :child | child accept: self ]. |
|
53 fsa := PEGFsa new. |
|
54 start := PEGFsaState new. |
|
55 |
|
56 fsa addState: start. |
|
57 fsa startState: start. |
|
58 |
|
59 priority := 0. |
|
60 childrenFsa do: [ :childFsa | |
|
61 fsa adopt: childFsa. |
|
62 fsa addTransitionFrom: start to: childFsa startState priority: priority. |
|
63 priority := priority + childFsa minPriority. |
|
64 ]. |
|
65 |
|
66 ^ fsa |
|
67 ! |
|
68 |
|
69 visitLiteralNode: node |
|
70 | states fsa | |
|
71 |
|
72 states := OrderedCollection new. |
|
73 (node literal size + 1) timesRepeat: [ |
|
74 states add: PEGFsaState new |
|
75 ]. |
|
76 |
|
77 fsa := PEGFsa new. |
|
78 states do: [ :state | fsa addState: state ]. |
|
79 fsa startState: states first; |
|
80 finalState: states last; |
|
81 yourself. |
|
82 |
|
83 (1 to: (states size - 1)) do: [ :index | |
|
84 fsa addTransitionFrom: (states at: index) |
|
85 to: (states at: index + 1) |
|
86 on: (node literal at: index). |
|
87 "set the name" |
|
88 (states at: (index + 1)) name: (node literal at: index). |
|
89 ]. |
|
90 |
|
91 fsa name: node literal. |
|
92 ^ fsa |
|
93 ! |
|
94 |
|
95 visitNode: node |
|
96 self error: 'node not supported' |
|
97 ! |
|
98 |
|
99 visitNotNode: node |
|
100 | fsa finalState | |
|
101 fsa := node child accept: self. |
|
102 finalState := PEGFsaState new |
|
103 name: '!!', fsa name asString; |
|
104 yourself. |
|
105 |
|
106 fsa finalStates do: [ :fs | |
|
107 fs retval: PEGFsaFailure new. |
|
108 ]. |
|
109 |
|
110 fsa addState: finalState. |
|
111 fsa finalState: finalState. |
|
112 |
|
113 fsa addTransitionFrom: fsa startState to: finalState priority: -1. |
|
114 ^ fsa |
|
115 ! |
|
116 |
|
117 visitOptionalNode: node |
|
118 | fsa startState finalState | |
|
119 |
|
120 fsa := node child accept: self. |
|
121 startState := PEGFsaState new |
|
122 yourself. |
|
123 |
|
124 finalState := PEGFsaState new |
|
125 final: true; |
|
126 yourself. |
|
127 |
|
128 fsa addState: startState. |
|
129 fsa addState: finalState. |
|
130 |
|
131 fsa addTransitionFrom: startState to: fsa startState priority: 0. |
|
132 fsa addTransitionFrom: startState to: finalState priority: fsa minPriority. |
|
133 |
|
134 fsa startState: startState. |
|
135 |
|
136 ^ fsa |
|
137 ! |
|
138 |
|
139 visitPlusNode: node |
|
140 | fsa finalState | |
|
141 |
|
142 finalState := PEGFsaState new. |
|
143 fsa := node child accept: self. |
|
144 fsa addState: finalState. |
|
145 |
|
146 fsa finalStates do: [ :state | |
|
147 fsa addTransitionFrom: state to: (fsa startState). |
|
148 fsa addTransitionFrom: state to: finalState priority: -1. |
|
149 self assert: (state hasPriority not). |
|
150 state priority: 0. |
|
151 state final: false. |
|
152 ]. |
|
153 |
|
154 fsa finalState: finalState. |
|
155 |
|
156 ^ fsa |
|
157 ! |
|
158 |
|
159 visitPredicateNode: node |
|
160 | stop start fsa | |
|
161 start := PEGFsaState new. |
|
162 stop := PEGFsaState new. |
|
163 |
|
164 fsa := PEGFsa new |
|
165 addState: start; |
|
166 addState: stop; |
|
167 |
|
168 startState: start; |
|
169 finalState: stop; |
|
170 yourself. |
|
171 |
|
172 fsa addTransitionFrom: start to: stop onCharacterSet: (node predicate classification). |
|
173 |
|
174 ^ fsa |
|
175 ! |
|
176 |
|
177 visitSequenceNode: node |
|
178 | childrenFsa fsa start previousFinalStates | |
|
179 |
|
180 childrenFsa := node children collect: [ :child | child accept: self ]. |
|
181 |
|
182 fsa := PEGFsa new. |
|
183 start := PEGFsaState new name: 'start'; yourself. |
|
184 fsa addState: start. |
|
185 fsa startState: start. |
|
186 |
|
187 fsa adopt: childrenFsa first. |
|
188 fsa addTransitionFrom: start to: childrenFsa first startState. |
|
189 |
|
190 previousFinalStates := childrenFsa first finalStates. |
|
191 childrenFsa allButFirst do: [ :childFsa | |
|
192 | newFinalStates | |
|
193 newFinalStates := IdentitySet new. |
|
194 previousFinalStates do: [ :state | |
|
195 | copy | |
|
196 copy := childFsa copy. |
|
197 fsa adopt: copy. |
|
198 |
|
199 state isFailure ifFalse: [ |
|
200 state final: false. |
|
201 fsa addTransitionFrom: state to: copy startState. |
|
202 ]. |
|
203 newFinalStates addAll: copy finalStates. |
|
204 ]. |
|
205 previousFinalStates := newFinalStates. |
|
206 ]. |
|
207 ^ fsa |
|
208 ! |
|
209 |
|
210 visitStarNode: node |
|
211 | fsa finalState | |
|
212 |
|
213 finalState := PEGFsaState new. |
|
214 fsa := node child accept: self. |
|
215 fsa addState: finalState. |
|
216 |
|
217 fsa finalStates do: [ :state | |
|
218 fsa addTransitionFrom: state to: (fsa startState). |
|
219 self assert: (state hasPriority not). |
|
220 state priority: 0. |
|
221 state final: false. |
|
222 ]. |
|
223 |
|
224 fsa addTransitionFrom: fsa startState to: finalState priority: -1. |
|
225 fsa finalState: finalState. |
|
226 |
|
227 ^ fsa |
|
228 ! ! |
|
229 |