|
1 /* |
|
2 * (c) 2009 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 * This is the main stage 3a file. |
|
28 * |
|
29 * In stage 3a some helpful symbol tables are instanciated and populated. |
|
30 * These symbol tables wll then be used by stage3b and atage4 code generators. |
|
31 */ |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 // #include <stdio.h> /* required for NULL */ |
|
39 #include <string> |
|
40 #include <iostream> |
|
41 #include <sstream> |
|
42 #include <typeinfo> |
|
43 #include <list> |
|
44 #include <strings.h> |
|
45 |
|
46 #include "../util/symtable.hh" |
|
47 #include "../util/dsymtable.hh" |
|
48 #include "../absyntax/visitor.hh" |
|
49 |
|
50 |
|
51 |
|
52 //#define DEBUG |
|
53 #ifdef DEBUG |
|
54 #define TRACE(classname) printf("\n____%s____\n",classname); |
|
55 #else |
|
56 #define TRACE(classname) |
|
57 #endif |
|
58 |
|
59 #define ERROR error_exit(__FILE__,__LINE__) |
|
60 /* function defined in main.cc */ |
|
61 extern void error_exit(const char *file_name, int line_no); |
|
62 |
|
63 |
|
64 /***********************************************************************/ |
|
65 /***********************************************************************/ |
|
66 /***********************************************************************/ |
|
67 /***********************************************************************/ |
|
68 |
|
69 |
|
70 /* returns 0 if the names are equal!! */ |
|
71 /* NOTE: it must ignore case!! */ |
|
72 int compare_identifiers(symbol_c *ident1, symbol_c *ident2) { |
|
73 |
|
74 token_c *name1 = dynamic_cast<token_c *>(ident1); |
|
75 token_c *name2 = dynamic_cast<token_c *>(ident2); |
|
76 |
|
77 if ((name1 == NULL) || (name2 == NULL)) |
|
78 /* invalid identifiers... */ |
|
79 return -1; |
|
80 |
|
81 if (strcasecmp(name1->value, name2->value) == 0) |
|
82 return 0; |
|
83 |
|
84 /* identifiers do not match! */ |
|
85 return 1; |
|
86 } |
|
87 |
|
88 |
|
89 |
|
90 /***********************************************************************/ |
|
91 /***********************************************************************/ |
|
92 /***********************************************************************/ |
|
93 /***********************************************************************/ |
|
94 |
|
95 |
|
96 |
|
97 /* A symbol table with all globally declared functions... */ |
|
98 function_declaration_c null_symbol1(NULL,NULL,NULL,NULL); |
|
99 dsymtable_c<function_declaration_c *, &null_symbol1> function_symtable; |
|
100 |
|
101 /* A symbol table with all globally declared functions block types... */ |
|
102 function_block_declaration_c null_symbol2(NULL,NULL,NULL); |
|
103 symtable_c<function_block_declaration_c *, &null_symbol2> function_block_type_symtable; |
|
104 |
|
105 /* A symbol table with all globally declared program types... */ |
|
106 program_declaration_c null_symbol3(NULL,NULL,NULL); |
|
107 symtable_c<program_declaration_c *, &null_symbol3> program_type_symtable; |
|
108 |
|
109 /* A symbol table with all user declared type definitions... */ |
|
110 /* Note that function block types and program types have their |
|
111 * own symbol tables, so do not get placed in this symbol table! |
|
112 */ |
|
113 symbol_c null_symbol4; |
|
114 symtable_c<symbol_c *, &null_symbol4> type_symtable; |
|
115 |
|
116 |
|
117 |
|
118 /***********************************************************************/ |
|
119 /***********************************************************************/ |
|
120 /***********************************************************************/ |
|
121 /***********************************************************************/ |
|
122 |
|
123 |
|
124 class populate_symtables_c: public iterator_visitor_c { |
|
125 |
|
126 public: |
|
127 populate_symtables_c(void) {}; |
|
128 virtual ~populate_symtables_c(void) {} |
|
129 |
|
130 |
|
131 public: |
|
132 |
|
133 /*************************/ |
|
134 /* B.1 - Common elements */ |
|
135 /*************************/ |
|
136 /*******************************************/ |
|
137 /* B 1.1 - Letters, digits and identifiers */ |
|
138 /*******************************************/ |
|
139 /*********************/ |
|
140 /* B 1.2 - Constants */ |
|
141 /*********************/ |
|
142 /******************************/ |
|
143 /* B 1.2.1 - Numeric Literals */ |
|
144 /******************************/ |
|
145 /*******************************/ |
|
146 /* B.1.2.2 Character Strings */ |
|
147 /*******************************/ |
|
148 /***************************/ |
|
149 /* B 1.2.3 - Time Literals */ |
|
150 /***************************/ |
|
151 /************************/ |
|
152 /* B 1.2.3.1 - Duration */ |
|
153 /************************/ |
|
154 /************************************/ |
|
155 /* B 1.2.3.2 - Time of day and Date */ |
|
156 /************************************/ |
|
157 /**********************/ |
|
158 /* B.1.3 - Data types */ |
|
159 /**********************/ |
|
160 /***********************************/ |
|
161 /* B 1.3.1 - Elementary Data Types */ |
|
162 /***********************************/ |
|
163 /********************************/ |
|
164 /* B.1.3.2 - Generic data types */ |
|
165 /********************************/ |
|
166 /********************************/ |
|
167 /* B 1.3.3 - Derived data types */ |
|
168 /********************************/ |
|
169 |
|
170 /* subrange_type_name ':' subrange_spec_init */ |
|
171 void *visit(subrange_type_declaration_c *symbol) { |
|
172 TRACE("subrange_type_declaration_c"); |
|
173 type_symtable.insert(symbol->subrange_type_name, symbol->subrange_spec_init); |
|
174 return NULL; |
|
175 } |
|
176 |
|
177 |
|
178 /* enumerated_type_name ':' enumerated_spec_init */ |
|
179 void *visit(enumerated_type_declaration_c *symbol) { |
|
180 TRACE("enumerated_type_declaration_c"); |
|
181 type_symtable.insert(symbol->enumerated_type_name, symbol->enumerated_spec_init); |
|
182 return NULL; |
|
183 } |
|
184 |
|
185 |
|
186 /* identifier ':' array_spec_init */ |
|
187 void *visit(array_type_declaration_c *symbol) { |
|
188 TRACE("array_type_declaration_c"); |
|
189 type_symtable.insert(symbol->identifier, symbol->array_spec_init); |
|
190 return NULL; |
|
191 } |
|
192 |
|
193 |
|
194 /* simple_type_name ':' simple_spec_init */ |
|
195 void *visit(simple_type_declaration_c *symbol) { |
|
196 TRACE("simple_type_declaration_c"); |
|
197 type_symtable.insert(symbol->simple_type_name, symbol->simple_spec_init); |
|
198 return NULL; |
|
199 } |
|
200 |
|
201 |
|
202 /* structure_type_name ':' structure_specification */ |
|
203 void *visit(structure_type_declaration_c *symbol) { |
|
204 TRACE("structure_type_declaration_c"); |
|
205 type_symtable.insert(symbol->structure_type_name, symbol->structure_specification); |
|
206 return NULL; |
|
207 } |
|
208 |
|
209 |
|
210 |
|
211 /*********************/ |
|
212 /* B 1.4 - Variables */ |
|
213 /*********************/ |
|
214 /********************************************/ |
|
215 /* B.1.4.1 Directly Represented Variables */ |
|
216 /********************************************/ |
|
217 /*************************************/ |
|
218 /* B.1.4.2 Multi-element Variables */ |
|
219 /*************************************/ |
|
220 /******************************************/ |
|
221 /* B 1.4.3 - Declaration & Initialisation */ |
|
222 /******************************************/ |
|
223 /**************************************/ |
|
224 /* B.1.5 - Program organization units */ |
|
225 /**************************************/ |
|
226 /***********************/ |
|
227 /* B 1.5.1 - Functions */ |
|
228 /***********************/ |
|
229 public: |
|
230 /* FUNCTION derived_function_name ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */ |
|
231 /* | FUNCTION derived_function_name ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */ |
|
232 void *visit(function_declaration_c *symbol) { |
|
233 TRACE("function_declaration_c"); |
|
234 function_symtable.insert(symbol->derived_function_name, symbol); |
|
235 |
|
236 /* symbol->derived_function_name->accept(*this); */ /* Function name */ |
|
237 /* symbol->type_name->accept(*this); */ /* return data type */ |
|
238 /* symbol->var_declarations_list->accept(*this); */ /* Function parameters and variables */ |
|
239 /* symbol->function_body->accept(*this); */ /* Function body */ |
|
240 return NULL; |
|
241 } |
|
242 |
|
243 |
|
244 /*****************************/ |
|
245 /* B 1.5.2 - Function Blocks */ |
|
246 /*****************************/ |
|
247 public: |
|
248 /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ |
|
249 //SYM_REF4(function_block_declaration_c, fblock_name, var_declarations, fblock_body, unused) |
|
250 void *visit(function_block_declaration_c *symbol) { |
|
251 TRACE("function_block_declaration_c"); |
|
252 function_block_type_symtable.insert(symbol->fblock_name, symbol); |
|
253 /* |
|
254 symbol->fblock_name->accept(*this); |
|
255 symbol->var_declarations->accept(*this); |
|
256 symbol->fblock_body->accept(*this); |
|
257 */ |
|
258 return NULL; |
|
259 } |
|
260 |
|
261 |
|
262 /**********************/ |
|
263 /* B 1.5.3 - Programs */ |
|
264 /**********************/ |
|
265 public: |
|
266 /* PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */ |
|
267 //SYM_REF4(program_declaration_c, program_type_name, var_declarations, function_block_body, unused) |
|
268 void *visit(program_declaration_c *symbol) { |
|
269 TRACE("program_declaration_c"); |
|
270 program_type_symtable.insert(symbol->program_type_name, symbol); |
|
271 /* |
|
272 symbol->program_type_name->accept(*this); |
|
273 symbol->var_declarations->accept(*this); |
|
274 symbol->function_block_body->accept(*this); |
|
275 */ |
|
276 return NULL; |
|
277 } |
|
278 |
|
279 }; /* populate_symtables_c */ |
|
280 |
|
281 |
|
282 |
|
283 |
|
284 |
|
285 void absyntax_utils_init(symbol_c *tree_root) { |
|
286 populate_symtables_c populate_symbols; |
|
287 |
|
288 tree_root->accept(populate_symbols); |
|
289 } |
|
290 |