75 |
75 |
76 /* file with declaration of absyntax classes... */ |
76 /* file with declaration of absyntax classes... */ |
77 #include "../absyntax/absyntax.hh" |
77 #include "../absyntax/absyntax.hh" |
78 |
78 |
79 /* file with declaration of token constants. Generated by bison! */ |
79 /* file with declaration of token constants. Generated by bison! */ |
80 #include "iec.y.hh" |
80 // #include "iec.y.hh" |
81 |
81 |
82 /* file with the declarations of symbol tables... */ |
82 #include "stage1_2_priv.hh" |
83 #include "../util/symtable.hh" |
|
84 |
83 |
85 |
84 |
86 /* an ugly hack!! |
85 /* an ugly hack!! |
87 * We will probably not need it when we decide |
86 * We will probably not need it when we decide |
88 * to cut down the abstract syntax down to size. |
87 * to cut down the abstract syntax down to size. |
108 #define ERROR error_exit(__FILE__,__LINE__) |
107 #define ERROR error_exit(__FILE__,__LINE__) |
109 /* function defined in main.cc */ |
108 /* function defined in main.cc */ |
110 extern void error_exit(const char *file_name, int line_no); |
109 extern void error_exit(const char *file_name, int line_no); |
111 |
110 |
112 |
111 |
113 /*********************************/ |
|
114 /* The global symbol tables... */ |
|
115 /*********************************/ |
|
116 /* NOTE: declared static because they are not accessed |
|
117 * directly by the lexical parser (flex), but rather |
|
118 * through the function get_identifier_token() |
|
119 */ |
|
120 /* A symbol table to store all the library elements */ |
|
121 /* e.g.: <function_name , function_decl> |
|
122 * <fb_name , fb_decl> |
|
123 * <type_name , type_decl> |
|
124 * <program_name , program_decl> |
|
125 * <configuration_name , configuration_decl> |
|
126 */ |
|
127 static symtable_c<int, BOGUS_TOKEN_ID> library_element_symtable; |
|
128 |
|
129 /* A symbol table to store the declared variables of |
|
130 * the function currently being parsed... |
|
131 */ |
|
132 static symtable_c<int, BOGUS_TOKEN_ID> variable_name_symtable; |
|
133 |
|
134 |
112 |
135 /*************************/ |
113 /*************************/ |
136 /* global variables... */ |
114 /* global variables... */ |
137 /*************************/ |
115 /*************************/ |
138 static symbol_c *tree_root = NULL; |
116 /* NOTE: For some strange reason bison ver 2.3 is including these declarations |
139 |
117 * in the iec.y.hh file, which is in turn included by flex. |
140 /* The name of the file currently being parsed... |
118 * We cannot therefore define any variables over here, but merely declare |
141 * Note that flex accesses and updates this global variable |
119 * their existance (otherwise we get errors when linking the code, since we |
142 * apropriately whenever it comes across an (*#include <filename> *) |
120 * would get a new variable defined each time iec.y.hh is included!). |
143 * directive... |
121 * Even though the variables are declared 'extern' over here, they will in |
144 */ |
122 * fact be defined towards the end of this same file (i.e. in the prologue) |
145 const char *current_filename = NULL; |
123 */ |
146 |
124 |
147 /* A global flag used to tell the parser if overloaded funtions should be allowed. |
125 /* A global flag used to tell the parser if overloaded funtions should be allowed. |
148 * The IEC 61131-3 standard allows overloaded funtions in the standard library, |
126 * The IEC 61131-3 standard allows overloaded funtions in the standard library, |
149 * but disallows them in user code... |
127 * but disallows them in user code... |
150 */ |
128 */ |
151 bool allow_function_overloading = false; |
129 extern bool allow_function_overloading; |
|
130 |
|
131 /* A pointer to the root of the parsing tree that will be generated |
|
132 * by bison. |
|
133 */ |
|
134 extern symbol_c *tree_root; |
|
135 |
152 |
136 |
153 |
137 |
154 /************************/ |
138 /************************/ |
155 /* forward declarations */ |
139 /* forward declarations */ |
156 /************************/ |
140 /************************/ |
160 symbol_c *il_operator_c_2_identifier_c(symbol_c *il_operator); |
144 symbol_c *il_operator_c_2_identifier_c(symbol_c *il_operator); |
161 |
145 |
162 /* print an error message */ |
146 /* print an error message */ |
163 void print_err_msg(const char *filename, int lineno, const char *additional_error_msg); |
147 void print_err_msg(const char *filename, int lineno, const char *additional_error_msg); |
164 |
148 |
165 |
|
166 /************************/ |
|
167 /* forward declarations */ |
|
168 /************************/ |
|
169 /* The functions declared here are defined in iec.flex... */ |
|
170 void print_include_stack(void); |
|
171 void cmd_goto_body_state(void); |
|
172 int get_goto_body_state(void); |
|
173 void rst_goto_body_state(void); |
|
174 |
|
175 %} |
149 %} |
|
150 |
176 |
151 |
177 |
152 |
178 |
153 |
179 %glr-parser |
154 %glr-parser |
180 // %expect-rr 1 |
155 // %expect-rr 1 |
204 |
179 |
205 |
180 |
206 /*****************************/ |
181 /*****************************/ |
207 /* Prelimenary constructs... */ |
182 /* Prelimenary constructs... */ |
208 /*****************************/ |
183 /*****************************/ |
209 %type <leaf> start |
|
210 |
|
211 %type <leaf> any_identifier |
|
212 |
|
213 %token <ID> prev_declared_variable_name_token |
|
214 %token <ID> prev_declared_fb_name_token |
|
215 %type <leaf> prev_declared_variable_name |
|
216 %type <leaf> prev_declared_fb_name |
|
217 |
|
218 %token <ID> prev_declared_simple_type_name_token |
|
219 %token <ID> prev_declared_subrange_type_name_token |
|
220 %token <ID> prev_declared_enumerated_type_name_token |
|
221 %token <ID> prev_declared_array_type_name_token |
|
222 %token <ID> prev_declared_structure_type_name_token |
|
223 %token <ID> prev_declared_string_type_name_token |
|
224 |
|
225 %type <leaf> prev_declared_simple_type_name |
|
226 %type <leaf> prev_declared_subrange_type_name |
|
227 %type <leaf> prev_declared_enumerated_type_name |
|
228 %type <leaf> prev_declared_array_type_name |
|
229 %type <leaf> prev_declared_structure_type_name |
|
230 %type <leaf> prev_declared_string_type_name |
|
231 |
|
232 %token <ID> prev_declared_derived_function_name_token |
|
233 %token <ID> prev_declared_derived_function_block_name_token |
|
234 %token <ID> prev_declared_program_type_name_token |
|
235 %type <leaf> prev_declared_derived_function_name |
|
236 %type <leaf> prev_declared_derived_function_block_name |
|
237 %type <leaf> prev_declared_program_type_name |
|
238 |
|
239 |
|
240 /* A bogus token that, in principle, flex MUST NEVER generate */ |
184 /* A bogus token that, in principle, flex MUST NEVER generate */ |
241 /* USE 1: |
185 /* USE 1: |
242 * ====== |
186 * ====== |
243 * This token is currently also being used as the default |
187 * This token is currently also being used as the default |
244 * initialisation value of the token_id member in |
188 * initialisation value of the token_id member in |
252 * This means that bison cannot handle it without some |
196 * This means that bison cannot handle it without some |
253 * caoxing from ourselves. We will then need this token |
197 * caoxing from ourselves. We will then need this token |
254 * to do the coaxing... |
198 * to do the coaxing... |
255 */ |
199 */ |
256 %token BOGUS_TOKEN_ID |
200 %token BOGUS_TOKEN_ID |
|
201 |
|
202 |
|
203 |
|
204 %{ |
|
205 /* The interface through which bison and flex interact. */ |
|
206 /* May only be included after the definition of BOGUS_TOKEN_ID */ |
|
207 #include "stage1_2_priv.hh" |
|
208 %} |
|
209 |
|
210 |
|
211 %type <leaf> start |
|
212 |
|
213 %type <leaf> any_identifier |
|
214 |
|
215 %token <ID> prev_declared_variable_name_token |
|
216 %token <ID> prev_declared_fb_name_token |
|
217 %type <leaf> prev_declared_variable_name |
|
218 %type <leaf> prev_declared_fb_name |
|
219 |
|
220 %token <ID> prev_declared_simple_type_name_token |
|
221 %token <ID> prev_declared_subrange_type_name_token |
|
222 %token <ID> prev_declared_enumerated_type_name_token |
|
223 %token <ID> prev_declared_array_type_name_token |
|
224 %token <ID> prev_declared_structure_type_name_token |
|
225 %token <ID> prev_declared_string_type_name_token |
|
226 |
|
227 %type <leaf> prev_declared_simple_type_name |
|
228 %type <leaf> prev_declared_subrange_type_name |
|
229 %type <leaf> prev_declared_enumerated_type_name |
|
230 %type <leaf> prev_declared_array_type_name |
|
231 %type <leaf> prev_declared_structure_type_name |
|
232 %type <leaf> prev_declared_string_type_name |
|
233 |
|
234 %token <ID> prev_declared_derived_function_name_token |
|
235 %token <ID> prev_declared_derived_function_block_name_token |
|
236 %token <ID> prev_declared_program_type_name_token |
|
237 %type <leaf> prev_declared_derived_function_name |
|
238 %type <leaf> prev_declared_derived_function_block_name |
|
239 %type <leaf> prev_declared_program_type_name |
|
240 |
|
241 |
257 |
242 |
258 |
243 |
259 /* The pragmas... */ |
244 /* The pragmas... */ |
260 %token <ID> pragma_token |
245 %token <ID> pragma_token |
261 %type <leaf> pragma |
246 %type <leaf> pragma |
1146 |
1131 |
1147 /*********************************/ |
1132 /*********************************/ |
1148 /* B 3.2.1 Assignment Statements */ |
1133 /* B 3.2.1 Assignment Statements */ |
1149 /*********************************/ |
1134 /*********************************/ |
1150 %type <leaf> assignment_statement |
1135 %type <leaf> assignment_statement |
1151 %token ASSIGN /* ":=" */ |
1136 // %token ASSIGN /* ":=" */ |
1152 |
1137 |
1153 |
1138 |
1154 /*****************************************/ |
1139 /*****************************************/ |
1155 /* B 3.2.2 Subprogram Control Statements */ |
1140 /* B 3.2.2 Subprogram Control Statements */ |
1156 /*****************************************/ |
1141 /*****************************************/ |
5176 |
5161 |
5177 /* variables defined in code generated by flex... */ |
5162 /* variables defined in code generated by flex... */ |
5178 extern FILE *yyin; |
5163 extern FILE *yyin; |
5179 extern int yylineno; |
5164 extern int yylineno; |
5180 |
5165 |
|
5166 |
|
5167 |
|
5168 /* A global flag used to tell the parser if overloaded funtions should be allowed. |
|
5169 * The IEC 61131-3 standard allows overloaded funtions in the standard library, |
|
5170 * but disallows them in user code... |
|
5171 */ |
|
5172 bool allow_function_overloading = false; |
|
5173 |
|
5174 /* A pointer to the root of the parsing tree that will be generated |
|
5175 * by bison. |
|
5176 */ |
|
5177 symbol_c *tree_root; |
|
5178 |
|
5179 |
|
5180 |
5181 /* The following function is called automatically by bison whenever it comes across |
5181 /* The following function is called automatically by bison whenever it comes across |
5182 * an error. Unfortunately it calls this function before executing the code that handles |
5182 * an error. Unfortunately it calls this function before executing the code that handles |
5183 * the error itself, so we cannot print out the correct line numbers of the error location |
5183 * the error itself, so we cannot print out the correct line numbers of the error location |
5184 * over here. |
5184 * over here. |
5185 * Our solution is to store the current error message in a global variable, and have all |
5185 * Our solution is to store the current error message in a global variable, and have all |
5196 |
5196 |
5197 void print_err_msg(const char *filename, int lineno, const char *additional_error_msg) { |
5197 void print_err_msg(const char *filename, int lineno, const char *additional_error_msg) { |
5198 fprintf(stderr, "error %d: %s\n", yynerrs, additional_error_msg); |
5198 fprintf(stderr, "error %d: %s\n", yynerrs, additional_error_msg); |
5199 print_include_stack(); |
5199 print_include_stack(); |
5200 fprintf(stderr, "%s:%d: %s\n", filename, lineno, current_error_msg); |
5200 fprintf(stderr, "%s:%d: %s\n", filename, lineno, current_error_msg); |
5201 } |
|
5202 |
|
5203 /* Function only called from within flex! |
|
5204 * |
|
5205 * search for a symbol in either of the two symbol tables |
|
5206 * declared above, and return the token id of the first |
|
5207 * symbol found. |
|
5208 * Searches first in the variables, and only if not found |
|
5209 * does it continue searching in the library elements |
|
5210 */ |
|
5211 int get_identifier_token(const char *identifier_str) { |
|
5212 // std::cout << "get_identifier_token(" << identifier_str << "): \n"; |
|
5213 int token_id; |
|
5214 |
|
5215 if ((token_id = variable_name_symtable.find_value(identifier_str)) == variable_name_symtable.end_value()) |
|
5216 if ((token_id = library_element_symtable.find_value(identifier_str)) == library_element_symtable.end_value()) |
|
5217 return identifier_token; |
|
5218 return token_id; |
|
5219 } |
5201 } |
5220 |
5202 |
5221 |
5203 |
5222 |
5204 |
5223 /* convert between an il_operator to a function name */ |
5205 /* convert between an il_operator to a function name */ |
5299 if (name == NULL) |
5281 if (name == NULL) |
5300 ERROR; |
5282 ERROR; |
5301 |
5283 |
5302 free(il_operator); |
5284 free(il_operator); |
5303 return new identifier_c(strdup(name)); |
5285 return new identifier_c(strdup(name)); |
5304 } |
|
5305 |
|
5306 |
|
5307 |
|
5308 |
|
5309 /* |
|
5310 * Join two strings together. Allocate space with malloc(3). |
|
5311 */ |
|
5312 static char *strdup2(const char *a, const char *b) { |
|
5313 char *res = (char *)malloc(strlen(a) + strlen(b) + 1); |
|
5314 |
|
5315 if (!res) |
|
5316 return NULL; |
|
5317 return strcat(strcpy(res, a), b); /* safe, actually */ |
|
5318 } |
|
5319 |
|
5320 /* |
|
5321 * Join three strings together. Allocate space with malloc(3). |
|
5322 */ |
|
5323 static char *strdup3(const char *a, const char *b, const char *c) { |
|
5324 char *res = (char *)malloc(strlen(a) + strlen(b) + strlen(c) + 1); |
|
5325 |
|
5326 if (!res) |
|
5327 return NULL; |
|
5328 return strcat(strcat(strcpy(res, a), b), c); /* safe, actually */ |
|
5329 } |
5286 } |
5330 |
5287 |
5331 |
5288 |
5332 |
5289 |
5333 |
5290 |
5408 |
5365 |
5409 |
5366 |
5410 #define LIBFILE "ieclib.txt" |
5367 #define LIBFILE "ieclib.txt" |
5411 #define DEF_LIBFILENAME LIBDIRECTORY "/" LIBFILE |
5368 #define DEF_LIBFILENAME LIBDIRECTORY "/" LIBFILE |
5412 |
5369 |
5413 int stage1_2(const char *filename, const char *includedir, symbol_c **tree_root_ref) { |
5370 int stage1_2__(const char *filename, const char *includedir, symbol_c **tree_root_ref) { |
5414 FILE *in_file = NULL, *lib_file = NULL; |
5371 FILE *in_file = NULL, *lib_file = NULL; |
5415 char *libfilename = NULL; |
5372 char *libfilename = NULL; |
5416 |
5373 |
5417 if((in_file = fopen(filename, "r")) == NULL) { |
5374 if((in_file = fopen(filename, "r")) == NULL) { |
5418 char *errmsg = strdup2("Error opening main file ", filename); |
5375 char *errmsg = strdup2("Error opening main file ", filename); |