114 |
114 |
115 |
115 |
116 /* Macros used to pass the line and column locations when |
116 /* Macros used to pass the line and column locations when |
117 * creating a new object for the abstract syntax tree. |
117 * creating a new object for the abstract syntax tree. |
118 */ |
118 */ |
119 #define locloc(foo) foo.first_line, foo.first_column, foo.last_line, foo.last_column |
119 #define locloc(foo) foo.first_line, foo.first_column, foo.first_file, foo.first_order, foo.last_line, foo.last_column, foo.last_file, foo.last_order |
120 #define locf(foo) foo.first_line, foo.first_column |
120 #define locf(foo) foo.first_line, foo.first_column, foo.first_file, foo.first_order |
121 #define locl(foo) foo.last_line, foo.last_column |
121 #define locl(foo) foo.last_line, foo.last_column, foo.last_file, foo.last_order |
122 |
122 |
|
123 /* Redefine the default action to take for each rule, so that the filenames are correctly processed... */ |
|
124 # define YYLLOC_DEFAULT(Current, Rhs, N) \ |
|
125 do \ |
|
126 if (N) \ |
|
127 { \ |
|
128 (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \ |
|
129 (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \ |
|
130 (Current).first_file = YYRHSLOC(Rhs, 1).first_file; \ |
|
131 (Current).first_order = YYRHSLOC(Rhs, 1).first_order; \ |
|
132 (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ |
|
133 (Current).last_column = YYRHSLOC(Rhs, N).last_column; \ |
|
134 (Current).last_file = YYRHSLOC(Rhs, 1).last_file; \ |
|
135 (Current).last_order = YYRHSLOC(Rhs, 1).last_order; \ |
|
136 } \ |
|
137 else \ |
|
138 { \ |
|
139 (Current).first_line = (Current).last_line = \ |
|
140 YYRHSLOC(Rhs, 0).last_line; \ |
|
141 (Current).first_column = (Current).last_column = \ |
|
142 YYRHSLOC(Rhs, 0).last_column; \ |
|
143 (Current).first_file = (Current).last_file = \ |
|
144 YYRHSLOC(Rhs, 0).last_file; \ |
|
145 (Current).first_order = (Current).last_order = \ |
|
146 YYRHSLOC(Rhs, 0).last_order; \ |
|
147 } \ |
|
148 while (0) |
123 |
149 |
124 |
150 |
125 /* A macro for printing out internal parser errors... */ |
151 /* A macro for printing out internal parser errors... */ |
126 #define ERROR error_exit(__FILE__,__LINE__) |
152 #define ERROR error_exit(__FILE__,__LINE__) |
127 /* function defined in main.cc */ |
153 /* function defined in main.cc */ |
180 /* ERROR_CHECK_END */ |
206 /* ERROR_CHECK_END */ |
181 |
207 |
182 /* print an error message */ |
208 /* print an error message */ |
183 void print_err_msg(int first_line, |
209 void print_err_msg(int first_line, |
184 int first_column, |
210 int first_column, |
|
211 const char *first_filename, |
|
212 long int first_order, |
185 int last_line, |
213 int last_line, |
186 int last_column, |
214 int last_column, |
|
215 const char *last_filename, |
|
216 long int last_order, |
187 const char *additional_error_msg); |
217 const char *additional_error_msg); |
188 %} |
218 %} |
189 |
219 |
190 |
220 |
191 |
221 |
192 |
222 |
193 // %glr-parser |
223 // %glr-parser |
194 // %expect-rr 1 |
224 // %expect-rr 1 |
195 |
225 |
|
226 |
|
227 /* The following definitions need to be inside a '%code requires' |
|
228 * so that they are also included in the header files. If this were not the case, |
|
229 * YYLTYPE would be delcared as something in the iec.cc file, and another thing |
|
230 * (actually the default value of YYLTYPE) in the iec.y.hh heder file. |
|
231 */ |
|
232 %code requires { |
|
233 /* define a new data type to store the locations, so we can also store |
|
234 * the filename in which the token is expressed. |
|
235 */ |
|
236 /* NOTE: since this code will be placed in the iec.y.hh header file, |
|
237 * as well as the iec.cc file that also includes the iec.y.hh header file, |
|
238 * declaring the typedef struct yyltype__local here would result in a |
|
239 * compilation error when compiling iec.cc, as this struct would be |
|
240 * declared twice. |
|
241 * We therefore use the #if !defined YYLTYPE ... |
|
242 * to make sure only the first declaration is parsed by the C++ compiler. |
|
243 * |
|
244 * At first glance it seems that what we really should do is delcare the |
|
245 * YYLTYPE directly as an anonymous struct, thus: |
|
246 * #define YYLTYPE struct{ ...} |
|
247 * however, this also results in compilation errors. |
|
248 * |
|
249 * I (Mario) think this is kind of a hack. If you know how to |
|
250 * do this re-declaration of YYLTYPE properly, please let me know! |
|
251 */ |
|
252 #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED |
|
253 typedef struct { |
|
254 int first_line; |
|
255 int first_column; |
|
256 const char *first_file; |
|
257 long int first_order; |
|
258 int last_line; |
|
259 int last_column; |
|
260 const char *last_file; |
|
261 long int last_order; |
|
262 } yyltype__local; |
|
263 #define YYLTYPE yyltype__local |
|
264 #endif |
|
265 } |
196 |
266 |
197 |
267 |
198 |
268 |
199 %union { |
269 %union { |
200 symbol_c *leaf; |
270 symbol_c *leaf; |
7827 /* ERROR_CHECK_END */ |
7897 /* ERROR_CHECK_END */ |
7828 |
7898 |
7829 |
7899 |
7830 void print_err_msg(int first_line, |
7900 void print_err_msg(int first_line, |
7831 int first_column, |
7901 int first_column, |
|
7902 const char *first_filename, |
|
7903 long int first_order, |
7832 int last_line, |
7904 int last_line, |
7833 int last_column, |
7905 int last_column, |
|
7906 const char *last_filename, |
|
7907 long int last_order, |
7834 const char *additional_error_msg) { |
7908 const char *additional_error_msg) { |
7835 if (full_token_loc) |
7909 |
7836 fprintf(stderr, "%s:%d-%d..%d-%d: error : %s\n", current_filename, first_line, first_column, last_line, last_column, additional_error_msg); |
7910 const char *unknown_file = "<unknown_file>"; |
7837 else |
7911 if (first_filename == NULL) first_filename = unknown_file; |
7838 fprintf(stderr, "%s:%d: error : %s\n", current_filename, first_line, additional_error_msg); |
7912 if ( last_filename == NULL) last_filename = unknown_file; |
|
7913 |
|
7914 if (full_token_loc) { |
|
7915 if (first_filename == last_filename) |
|
7916 fprintf(stderr, "%s:%d-%d..%d-%d: error : %s\n", first_filename, first_line, first_column, last_line, last_column, additional_error_msg); |
|
7917 else |
|
7918 fprintf(stderr, "%s:%d-%d..%s:%d-%d: error : %s\n", first_filename, first_line, first_column, last_filename, last_line, last_column, additional_error_msg); |
|
7919 } else { |
|
7920 fprintf(stderr, "%s:%d: error : %s\n", first_filename, first_line, additional_error_msg); |
|
7921 } |
7839 //fprintf(stderr, "error %d: %s\n", yynerrs /* a global variable */, additional_error_msg); |
7922 //fprintf(stderr, "error %d: %s\n", yynerrs /* a global variable */, additional_error_msg); |
7840 print_include_stack(); |
7923 print_include_stack(); |
7841 //fprintf(stderr, "%s(%d-%d): %s\n", current_filename, first_line, last_line, current_error_msg); |
7924 //fprintf(stderr, "%s(%d-%d): %s\n", current_filename, first_line, last_line, current_error_msg); |
7842 } |
7925 } |
7843 |
7926 |
7924 ERROR; |
8007 ERROR; |
7925 |
8008 |
7926 res = new identifier_c(strdup(name), |
8009 res = new identifier_c(strdup(name), |
7927 il_operator->first_line, |
8010 il_operator->first_line, |
7928 il_operator->first_column, |
8011 il_operator->first_column, |
|
8012 il_operator->first_file, |
|
8013 il_operator->first_order, |
7929 il_operator->last_line, |
8014 il_operator->last_line, |
7930 il_operator->last_column |
8015 il_operator->last_column, |
|
8016 il_operator->last_file, |
|
8017 il_operator->last_order |
7931 ); |
8018 ); |
7932 free(il_operator); |
8019 free(il_operator); |
7933 return res; |
8020 return res; |
7934 } |
8021 } |
7935 |
8022 |