|
1 /* |
|
2 * (c) 2003 Mario de Sousa |
|
3 * |
|
4 * Offered to the public under the terms of the GNU General Public License |
|
5 * as published by the Free Software Foundation; either version 2 of the |
|
6 * License, or (at your option) any later version. |
|
7 * |
|
8 * This program is distributed in the hope that it will be useful, but |
|
9 * WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General |
|
11 * Public License for more details. |
|
12 * |
|
13 * This code is made available on the understanding that it will not be |
|
14 * used in safety-critical situations without a full and competent review. |
|
15 */ |
|
16 |
|
17 /* |
|
18 * An IEC 61131-3 IL and ST compiler. |
|
19 * |
|
20 * Based on the |
|
21 * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) |
|
22 * |
|
23 */ |
|
24 |
|
25 |
|
26 /* |
|
27 * VISITOR.CC |
|
28 * |
|
29 * Three base implementations of the visitor interface, |
|
30 * that may be later extended to execute a particular algorithm. |
|
31 * |
|
32 * The null (class null_visitor_c) does nothing. |
|
33 * |
|
34 * The iterator (class iterator_visitor_c) iterates through |
|
35 * every object in the syntax tree. |
|
36 * |
|
37 * The search class (class search_visitor_c) iterates through |
|
38 * every object, until one returns a value != NULL. |
|
39 */ |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 #include <unistd.h> |
|
46 |
|
47 #include <stdio.h> /* required for NULL */ |
|
48 #include "visitor.hh" |
|
49 |
|
50 #include <iostream> |
|
51 |
|
52 |
|
53 /******************/ |
|
54 /* visitor_c */ |
|
55 /******************/ |
|
56 |
|
57 visitor_c::~visitor_c(void) {return;} |
|
58 |
|
59 |
|
60 /******************/ |
|
61 /* null_visitor_c */ |
|
62 /******************/ |
|
63 |
|
64 null_visitor_c::~null_visitor_c(void) {return;} |
|
65 |
|
66 #define SYM_LIST(class_name_c) \ |
|
67 void *null_visitor_c::visit(class_name_c *symbol) {return NULL;} |
|
68 |
|
69 #define SYM_TOKEN(class_name_c) \ |
|
70 void *null_visitor_c::visit(class_name_c *symbol) {return NULL;} |
|
71 |
|
72 #define SYM_REF0(class_name_c) \ |
|
73 void *null_visitor_c::visit(class_name_c *symbol) {return NULL;} |
|
74 |
|
75 #define SYM_REF2(class_name_c, ref1, ref2) \ |
|
76 void *null_visitor_c::visit(class_name_c *symbol) {return NULL;} |
|
77 |
|
78 #define SYM_REF4(class_name_c, ref1, ref2, ref3, ref4) \ |
|
79 void *null_visitor_c::visit(class_name_c *symbol) {return NULL;} |
|
80 |
|
81 #define SYM_REF6(class_name_c, ref1, ref2, ref3, ref4, ref5, ref6) \ |
|
82 void *null_visitor_c::visit(class_name_c *symbol) {return NULL;} |
|
83 |
|
84 |
|
85 #include "absyntax.def" |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 #undef SYM_LIST |
|
91 #undef SYM_TOKEN |
|
92 #undef SYM_REF0 |
|
93 #undef SYM_REF2 |
|
94 #undef SYM_REF4 |
|
95 #undef SYM_REF6 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 /**********************/ |
|
103 /* iterator_visitor_c */ |
|
104 /**********************/ |
|
105 |
|
106 iterator_visitor_c::~iterator_visitor_c(void) {return;} |
|
107 |
|
108 |
|
109 void *iterator_visitor_c::visit_list(list_c *list) { |
|
110 for(int i = 0; i < list->n; i++) { |
|
111 list->elements[i]->accept(*this); |
|
112 } |
|
113 return NULL; |
|
114 } |
|
115 |
|
116 |
|
117 #define SYM_LIST(class_name_c) \ |
|
118 void *iterator_visitor_c::visit(class_name_c *symbol) {return visit_list(symbol);} |
|
119 |
|
120 #define SYM_TOKEN(class_name_c) \ |
|
121 void *iterator_visitor_c::visit(class_name_c *symbol) {return NULL;} |
|
122 |
|
123 #define SYM_REF0(class_name_c) \ |
|
124 void *iterator_visitor_c::visit(class_name_c *symbol) {return NULL;} |
|
125 |
|
126 #define SYM_REF2(class_name_c, ref1, ref2) \ |
|
127 void *iterator_visitor_c::visit(class_name_c *symbol) { \ |
|
128 if (symbol->ref1!=NULL) symbol->ref1->accept(*this); \ |
|
129 if (symbol->ref2!=NULL) symbol->ref2->accept(*this); \ |
|
130 return NULL; \ |
|
131 } |
|
132 |
|
133 #define SYM_REF4(class_name_c, ref1, ref2, ref3, ref4) \ |
|
134 void *iterator_visitor_c::visit(class_name_c *symbol) { \ |
|
135 if (symbol->ref1) symbol->ref1->accept(*this); \ |
|
136 if (symbol->ref2) symbol->ref2->accept(*this); \ |
|
137 if (symbol->ref3) symbol->ref3->accept(*this); \ |
|
138 if (symbol->ref4) symbol->ref4->accept(*this); \ |
|
139 return NULL; \ |
|
140 } |
|
141 |
|
142 |
|
143 #define SYM_REF6(class_name_c, ref1, ref2, ref3, ref4, ref5, ref6) \ |
|
144 void *iterator_visitor_c::visit(class_name_c *symbol) { \ |
|
145 if (symbol->ref1) symbol->ref1->accept(*this); \ |
|
146 if (symbol->ref2) symbol->ref2->accept(*this); \ |
|
147 if (symbol->ref3) symbol->ref3->accept(*this); \ |
|
148 if (symbol->ref4) symbol->ref4->accept(*this); \ |
|
149 if (symbol->ref5) symbol->ref5->accept(*this); \ |
|
150 if (symbol->ref6) symbol->ref6->accept(*this); \ |
|
151 return NULL; \ |
|
152 } |
|
153 |
|
154 |
|
155 |
|
156 #include "absyntax.def" |
|
157 |
|
158 |
|
159 |
|
160 #undef SYM_LIST |
|
161 #undef SYM_TOKEN |
|
162 #undef SYM_REF0 |
|
163 #undef SYM_REF2 |
|
164 #undef SYM_REF4 |
|
165 #undef SYM_REF6 |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 |
|
175 |
|
176 /********************/ |
|
177 /* search_visitor_c */ |
|
178 /********************/ |
|
179 |
|
180 search_visitor_c::~search_visitor_c(void) {return;} |
|
181 |
|
182 |
|
183 void *search_visitor_c::visit_list(list_c *list) { |
|
184 for(int i = 0; i < list->n; i++) { |
|
185 void *res = list->elements[i]->accept(*this); |
|
186 if (res != NULL) |
|
187 return res; |
|
188 } |
|
189 return NULL; |
|
190 } |
|
191 |
|
192 |
|
193 #define SYM_LIST(class_name_c) \ |
|
194 void *search_visitor_c::visit(class_name_c *symbol) {return visit_list(symbol);} |
|
195 |
|
196 #define SYM_TOKEN(class_name_c) \ |
|
197 void *search_visitor_c::visit(class_name_c *symbol) {return NULL;} |
|
198 |
|
199 #define SYM_REF0(class_name_c) \ |
|
200 void *search_visitor_c::visit(class_name_c *symbol) {return NULL;} |
|
201 |
|
202 #define SYM_REF2(class_name_c, ref1, ref2) \ |
|
203 void *search_visitor_c::visit(class_name_c *symbol) { \ |
|
204 void *res = NULL; \ |
|
205 if (symbol->ref1) res = symbol->ref1->accept(*this); \ |
|
206 if (res != NULL) return res; \ |
|
207 if (symbol->ref2) return symbol->ref2->accept(*this); \ |
|
208 return NULL; \ |
|
209 } |
|
210 |
|
211 #define SYM_REF4(class_name_c, ref1, ref2, ref3, ref4) \ |
|
212 void *search_visitor_c::visit(class_name_c *symbol) { \ |
|
213 void *res = NULL; \ |
|
214 if (symbol->ref1) res = symbol->ref1->accept(*this); \ |
|
215 if (res != NULL) return res; \ |
|
216 if (symbol->ref2) res = symbol->ref2->accept(*this); \ |
|
217 if (res != NULL) return res; \ |
|
218 if (symbol->ref3) res = symbol->ref3->accept(*this); \ |
|
219 if (res != NULL) return res; \ |
|
220 if (symbol->ref4) return symbol->ref4->accept(*this); \ |
|
221 return NULL; \ |
|
222 } |
|
223 |
|
224 |
|
225 #define SYM_REF6(class_name_c, ref1, ref2, ref3, ref4, ref5, ref6) \ |
|
226 void *search_visitor_c::visit(class_name_c *symbol) { \ |
|
227 void *res = NULL; \ |
|
228 if (symbol->ref1) res = symbol->ref1->accept(*this); \ |
|
229 if (res != NULL) return res; \ |
|
230 if (symbol->ref2) res = symbol->ref2->accept(*this); \ |
|
231 if (res != NULL) return res; \ |
|
232 if (symbol->ref3) res = symbol->ref3->accept(*this); \ |
|
233 if (res != NULL) return res; \ |
|
234 if (symbol->ref4) res = symbol->ref4->accept(*this); \ |
|
235 if (res != NULL) return res; \ |
|
236 if (symbol->ref5) res = symbol->ref5->accept(*this); \ |
|
237 if (res != NULL) return res; \ |
|
238 if (symbol->ref6) return symbol->ref6->accept(*this); \ |
|
239 return NULL; \ |
|
240 } |
|
241 |
|
242 |
|
243 |
|
244 #include "absyntax.def" |
|
245 |
|
246 |
|
247 |
|
248 #undef SYM_LIST |
|
249 #undef SYM_TOKEN |
|
250 #undef SYM_REF0 |
|
251 #undef SYM_REF2 |
|
252 #undef SYM_REF4 |
|
253 #undef SYM_REF6 |
|
254 |
|
255 |
|
256 |
|
257 |
|
258 |
|
259 |
|
260 |
|
261 |
|
262 |
|
263 |
|
264 |
|
265 |