]>
Commit | Line | Data |
---|---|---|
377029eb | 1 | /* Parser grammar for quick source code scan of Java(TM) language programs. |
bb644f25 | 2 | Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc. |
377029eb | 3 | Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com) |
4 | ||
5 | This file is part of GNU CC. | |
6 | ||
7 | GNU CC is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 2, or (at your option) | |
10 | any later version. | |
11 | ||
12 | GNU CC is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with GNU CC; see the file COPYING. If not, write to | |
19 | the Free Software Foundation, 59 Temple Place - Suite 330, | |
20 | Boston, MA 02111-1307, USA. | |
21 | ||
22 | Java and all Java-based marks are trademarks or registered trademarks | |
23 | of Sun Microsystems, Inc. in the United States and other countries. | |
24 | The Free Software Foundation is independent of Sun Microsystems, Inc. */ | |
25 | ||
26 | /* This file parses Java source code. Action can be further completed | |
27 | to achieve a desired behavior. This file isn't part of the Java | |
28 | language gcc front end. | |
29 | ||
30 | The grammar conforms to the Java grammar described in "The Java(TM) | |
31 | Language Specification. J. Gosling, B. Joy, G. Steele. Addison Wesley | |
32 | 1996, ISBN 0-201-63451-1" | |
33 | ||
34 | Some rules have been modified to support JDK1.1 inner classes | |
35 | definitions and other extensions. */ | |
36 | ||
37 | %{ | |
38 | #define JC1_LITE | |
39 | ||
103ad453 | 40 | #include "config.h" |
41 | #include "system.h" | |
805e22b2 | 42 | #include "coretypes.h" |
43 | #include "tm.h" | |
377029eb | 44 | |
377029eb | 45 | #include "obstack.h" |
5ce13bce | 46 | #include "toplev.h" |
377029eb | 47 | |
bb644f25 | 48 | #define obstack_chunk_alloc xmalloc |
49 | #define obstack_chunk_free free | |
50 | ||
377029eb | 51 | extern char *input_filename; |
52 | extern FILE *finput, *out; | |
53 | ||
54 | /* Obstack for the lexer. */ | |
55 | struct obstack temporary_obstack; | |
56 | ||
57 | /* The current parser context. */ | |
58 | static struct parser_ctxt *ctxp; | |
59 | ||
60 | /* Error and warning counts, current line number, because they're used | |
61 | elsewhere */ | |
62 | int java_error_count; | |
63 | int java_warning_count; | |
64 | int lineno; | |
65 | ||
66 | /* Tweak default rules when necessary. */ | |
67 | static int absorber; | |
68 | #define USE_ABSORBER absorber = 0 | |
69 | ||
bb644f25 | 70 | /* Keep track of the current package name. */ |
1c637495 | 71 | static const char *package_name; |
377029eb | 72 | |
73 | /* Keep track of whether things have be listed before. */ | |
74 | static int previous_output; | |
75 | ||
76 | /* Record modifier uses */ | |
77 | static int modifier_value; | |
78 | ||
cd269709 | 79 | /* Record (almost) cyclomatic complexity. */ |
80 | static int complexity; | |
81 | ||
52725f92 | 82 | /* Keeps track of number of bracket pairs after a variable declarator |
01b49881 | 83 | id. */ |
84 | static int bracket_count; | |
85 | ||
52725f92 | 86 | /* Numbers anonymous classes */ |
87 | static int anonymous_count; | |
88 | ||
bb644f25 | 89 | /* This is used to record the current class context. */ |
90 | struct class_context | |
91 | { | |
92 | char *name; | |
93 | struct class_context *next; | |
94 | }; | |
95 | ||
96 | /* The global class context. */ | |
97 | static struct class_context *current_class_context; | |
98 | ||
99 | /* A special constant used to represent an anonymous context. */ | |
100 | static const char *anonymous_context = "ANONYMOUS"; | |
101 | ||
102 | /* Count of method depth. */ | |
103 | static int method_depth; | |
104 | ||
377029eb | 105 | /* Record a method declaration */ |
106 | struct method_declarator { | |
1c637495 | 107 | const char *method_name; |
108 | const char *args; | |
377029eb | 109 | }; |
110 | #define NEW_METHOD_DECLARATOR(D,N,A) \ | |
111 | { \ | |
112 | (D) = \ | |
113 | (struct method_declarator *)xmalloc (sizeof (struct method_declarator)); \ | |
114 | (D)->method_name = (N); \ | |
115 | (D)->args = (A); \ | |
116 | } | |
117 | ||
118 | /* Two actions for this grammar */ | |
bb644f25 | 119 | static int make_class_name_recursive PARAMS ((struct obstack *stack, |
120 | struct class_context *ctx)); | |
121 | static char *get_class_name PARAMS ((void)); | |
fa334f7d | 122 | static void report_class_declaration PARAMS ((const char *)); |
123 | static void report_main_declaration PARAMS ((struct method_declarator *)); | |
f8ee1774 | 124 | static void push_class_context PARAMS ((const char *)); |
125 | static void pop_class_context PARAMS ((void)); | |
377029eb | 126 | |
cd269709 | 127 | void report PARAMS ((void)); |
128 | ||
377029eb | 129 | #include "lex.h" |
130 | #include "parse.h" | |
131 | %} | |
132 | ||
133 | %union { | |
134 | char *node; | |
135 | struct method_declarator *declarator; | |
136 | int value; /* For modifiers */ | |
137 | } | |
138 | ||
06fa675c | 139 | %{ |
4770b4b7 | 140 | extern int flag_assert; |
141 | ||
06fa675c | 142 | #include "lex.c" |
143 | %} | |
144 | ||
377029eb | 145 | %pure_parser |
146 | ||
147 | /* Things defined here have to match the order of what's in the | |
148 | binop_lookup table. */ | |
149 | ||
150 | %token PLUS_TK MINUS_TK MULT_TK DIV_TK REM_TK | |
151 | %token LS_TK SRS_TK ZRS_TK | |
152 | %token AND_TK XOR_TK OR_TK | |
153 | %token BOOL_AND_TK BOOL_OR_TK | |
154 | %token EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK | |
155 | ||
156 | /* This maps to the same binop_lookup entry than the token above */ | |
157 | ||
158 | %token PLUS_ASSIGN_TK MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK | |
159 | %token REM_ASSIGN_TK | |
160 | %token LS_ASSIGN_TK SRS_ASSIGN_TK ZRS_ASSIGN_TK | |
161 | %token AND_ASSIGN_TK XOR_ASSIGN_TK OR_ASSIGN_TK | |
162 | ||
163 | ||
164 | /* Modifier TOKEN have to be kept in this order. Don't scramble it */ | |
165 | ||
166 | %token PUBLIC_TK PRIVATE_TK PROTECTED_TK | |
167 | %token STATIC_TK FINAL_TK SYNCHRONIZED_TK | |
168 | %token VOLATILE_TK TRANSIENT_TK NATIVE_TK | |
169 | %token PAD_TK ABSTRACT_TK MODIFIER_TK | |
635826d3 | 170 | %token STRICT_TK |
377029eb | 171 | |
172 | /* Keep those two in order, too */ | |
173 | %token DECR_TK INCR_TK | |
174 | ||
175 | /* From now one, things can be in any order */ | |
176 | ||
177 | %token DEFAULT_TK IF_TK THROW_TK | |
178 | %token BOOLEAN_TK DO_TK IMPLEMENTS_TK | |
179 | %token THROWS_TK BREAK_TK IMPORT_TK | |
180 | %token ELSE_TK INSTANCEOF_TK RETURN_TK | |
181 | %token VOID_TK CATCH_TK INTERFACE_TK | |
182 | %token CASE_TK EXTENDS_TK FINALLY_TK | |
183 | %token SUPER_TK WHILE_TK CLASS_TK | |
184 | %token SWITCH_TK CONST_TK TRY_TK | |
185 | %token FOR_TK NEW_TK CONTINUE_TK | |
186 | %token GOTO_TK PACKAGE_TK THIS_TK | |
ec31870d | 187 | %token ASSERT_TK |
377029eb | 188 | |
189 | %token BYTE_TK SHORT_TK INT_TK LONG_TK | |
190 | %token CHAR_TK INTEGRAL_TK | |
191 | ||
192 | %token FLOAT_TK DOUBLE_TK FP_TK | |
193 | ||
194 | %token ID_TK | |
195 | ||
196 | %token REL_QM_TK REL_CL_TK NOT_TK NEG_TK | |
197 | ||
198 | %token ASSIGN_ANY_TK ASSIGN_TK | |
199 | %token OP_TK CP_TK OCB_TK CCB_TK OSB_TK CSB_TK SC_TK C_TK DOT_TK | |
200 | ||
201 | %token STRING_LIT_TK CHAR_LIT_TK INT_LIT_TK FP_LIT_TK | |
202 | %token TRUE_TK FALSE_TK BOOL_LIT_TK NULL_TK | |
203 | ||
204 | %type <node> ID_TK identifier name simple_name qualified_name type | |
205 | primitive_type reference_type array_type formal_parameter_list | |
206 | formal_parameter class_or_interface_type class_type interface_type | |
207 | %type <declarator> method_declarator | |
208 | %type <value> MODIFIER_TK | |
209 | ||
210 | %% | |
211 | /* 19.2 Production from 2.3: The Syntactic Grammar */ | |
212 | goal: | |
213 | compilation_unit | |
214 | ; | |
215 | ||
216 | /* 19.3 Productions from 3: Lexical structure */ | |
217 | literal: | |
218 | INT_LIT_TK | |
219 | | FP_LIT_TK | |
220 | | BOOL_LIT_TK | |
221 | | CHAR_LIT_TK | |
222 | | STRING_LIT_TK | |
223 | | NULL_TK | |
224 | ; | |
225 | ||
226 | /* 19.4 Productions from 4: Types, Values and Variables */ | |
227 | type: | |
228 | primitive_type | |
229 | | reference_type | |
230 | ; | |
231 | ||
232 | primitive_type: | |
233 | INTEGRAL_TK | |
234 | { | |
235 | /* use preset global here. FIXME */ | |
236 | $$ = xstrdup ("int"); | |
237 | } | |
238 | | FP_TK | |
239 | { | |
240 | /* use preset global here. FIXME */ | |
241 | $$ = xstrdup ("double"); | |
242 | } | |
243 | | BOOLEAN_TK | |
244 | { | |
245 | /* use preset global here. FIXME */ | |
246 | $$ = xstrdup ("boolean"); | |
247 | } | |
248 | ; | |
249 | ||
250 | reference_type: | |
251 | class_or_interface_type | |
252 | | array_type | |
253 | ; | |
254 | ||
255 | class_or_interface_type: | |
256 | name | |
257 | ; | |
258 | ||
259 | class_type: | |
260 | class_or_interface_type /* Default rule */ | |
261 | ; | |
262 | ||
263 | interface_type: | |
264 | class_or_interface_type | |
265 | ; | |
266 | ||
267 | array_type: | |
06c564bd | 268 | primitive_type dims |
377029eb | 269 | { |
06c564bd | 270 | while (bracket_count-- > 0) |
271 | $$ = concat ("[", $1, NULL); | |
377029eb | 272 | } |
06c564bd | 273 | | name dims |
274 | { | |
275 | while (bracket_count-- > 0) | |
276 | $$ = concat ("[", $1, NULL); | |
377029eb | 277 | } |
278 | ; | |
279 | ||
280 | /* 19.5 Productions from 6: Names */ | |
281 | name: | |
282 | simple_name /* Default rule */ | |
283 | | qualified_name /* Default rule */ | |
284 | ; | |
285 | ||
286 | simple_name: | |
287 | identifier /* Default rule */ | |
288 | ; | |
289 | ||
290 | qualified_name: | |
291 | name DOT_TK identifier | |
292 | { | |
1ab1061d | 293 | $$ = concat ($1, ".", $3, NULL); |
377029eb | 294 | } |
295 | ; | |
296 | ||
297 | identifier: | |
298 | ID_TK | |
299 | ; | |
300 | ||
301 | /* 19.6: Production from 7: Packages */ | |
302 | compilation_unit: | |
303 | | package_declaration | |
304 | | import_declarations | |
305 | | type_declarations | |
306 | | package_declaration import_declarations | |
307 | | package_declaration type_declarations | |
308 | | import_declarations type_declarations | |
309 | | package_declaration import_declarations type_declarations | |
310 | ; | |
311 | ||
312 | import_declarations: | |
313 | import_declaration | |
314 | | import_declarations import_declaration | |
315 | ; | |
316 | ||
317 | type_declarations: | |
318 | type_declaration | |
319 | | type_declarations type_declaration | |
320 | ; | |
321 | ||
322 | package_declaration: | |
323 | PACKAGE_TK name SC_TK | |
324 | { package_name = $2; } | |
325 | ; | |
326 | ||
327 | import_declaration: | |
328 | single_type_import_declaration | |
329 | | type_import_on_demand_declaration | |
330 | ; | |
331 | ||
332 | single_type_import_declaration: | |
333 | IMPORT_TK name SC_TK | |
334 | ; | |
335 | ||
336 | type_import_on_demand_declaration: | |
337 | IMPORT_TK name DOT_TK MULT_TK SC_TK | |
338 | ; | |
339 | ||
340 | type_declaration: | |
341 | class_declaration | |
342 | | interface_declaration | |
06c564bd | 343 | | empty_statement |
377029eb | 344 | ; |
345 | ||
346 | /* 19.7 Shortened from the original: | |
347 | modifiers: modifier | modifiers modifier | |
348 | modifier: any of public... */ | |
349 | modifiers: | |
350 | MODIFIER_TK | |
351 | { | |
352 | if ($1 == PUBLIC_TK) | |
353 | modifier_value++; | |
354 | if ($1 == STATIC_TK) | |
355 | modifier_value++; | |
356 | USE_ABSORBER; | |
357 | } | |
358 | | modifiers MODIFIER_TK | |
359 | { | |
360 | if ($2 == PUBLIC_TK) | |
361 | modifier_value++; | |
362 | if ($2 == STATIC_TK) | |
363 | modifier_value++; | |
364 | USE_ABSORBER; | |
365 | } | |
366 | ; | |
367 | ||
368 | /* 19.8.1 Production from $8.1: Class Declaration */ | |
369 | class_declaration: | |
370 | modifiers CLASS_TK identifier super interfaces | |
371 | { | |
372 | report_class_declaration($3); | |
373 | modifier_value = 0; | |
374 | } | |
375 | class_body | |
376 | | CLASS_TK identifier super interfaces | |
377 | { report_class_declaration($2); } | |
378 | class_body | |
379 | ; | |
380 | ||
381 | super: | |
382 | | EXTENDS_TK class_type | |
383 | ; | |
384 | ||
385 | interfaces: | |
386 | | IMPLEMENTS_TK interface_type_list | |
387 | ; | |
388 | ||
389 | interface_type_list: | |
390 | interface_type | |
391 | { USE_ABSORBER; } | |
392 | | interface_type_list C_TK interface_type | |
393 | { USE_ABSORBER; } | |
394 | ; | |
395 | ||
396 | class_body: | |
397 | OCB_TK CCB_TK | |
f8ee1774 | 398 | { pop_class_context (); } |
377029eb | 399 | | OCB_TK class_body_declarations CCB_TK |
f8ee1774 | 400 | { pop_class_context (); } |
377029eb | 401 | ; |
402 | ||
403 | class_body_declarations: | |
404 | class_body_declaration | |
405 | | class_body_declarations class_body_declaration | |
406 | ; | |
407 | ||
408 | class_body_declaration: | |
409 | class_member_declaration | |
410 | | static_initializer | |
411 | | constructor_declaration | |
412 | | block /* Added, JDK1.1, instance initializer */ | |
413 | ; | |
414 | ||
415 | class_member_declaration: | |
416 | field_declaration | |
417 | | method_declaration | |
418 | | class_declaration /* Added, JDK1.1 inner classes */ | |
419 | | interface_declaration /* Added, JDK1.1 inner classes */ | |
06c564bd | 420 | | empty_statement |
377029eb | 421 | ; |
422 | ||
423 | /* 19.8.2 Productions from 8.3: Field Declarations */ | |
424 | field_declaration: | |
425 | type variable_declarators SC_TK | |
426 | { USE_ABSORBER; } | |
427 | | modifiers type variable_declarators SC_TK | |
428 | { modifier_value = 0; } | |
429 | ; | |
430 | ||
431 | variable_declarators: | |
432 | /* Should we use build_decl_list () instead ? FIXME */ | |
433 | variable_declarator /* Default rule */ | |
434 | | variable_declarators C_TK variable_declarator | |
435 | ; | |
436 | ||
437 | variable_declarator: | |
438 | variable_declarator_id | |
439 | | variable_declarator_id ASSIGN_TK variable_initializer | |
440 | ; | |
441 | ||
442 | variable_declarator_id: | |
443 | identifier | |
01b49881 | 444 | { bracket_count = 0; USE_ABSORBER; } |
377029eb | 445 | | variable_declarator_id OSB_TK CSB_TK |
01b49881 | 446 | { ++bracket_count; } |
377029eb | 447 | ; |
448 | ||
449 | variable_initializer: | |
450 | expression | |
451 | | array_initializer | |
452 | ; | |
453 | ||
454 | /* 19.8.3 Productions from 8.4: Method Declarations */ | |
455 | method_declaration: | |
bb644f25 | 456 | method_header |
457 | { ++method_depth; } | |
458 | method_body | |
459 | { --method_depth; } | |
377029eb | 460 | ; |
461 | ||
462 | method_header: | |
463 | type method_declarator throws | |
464 | { USE_ABSORBER; } | |
465 | | VOID_TK method_declarator throws | |
466 | | modifiers type method_declarator throws | |
467 | { modifier_value = 0; } | |
468 | | modifiers VOID_TK method_declarator throws | |
469 | { | |
470 | report_main_declaration ($3); | |
471 | modifier_value = 0; | |
472 | } | |
473 | ; | |
474 | ||
475 | method_declarator: | |
476 | identifier OP_TK CP_TK | |
477 | { | |
478 | struct method_declarator *d; | |
479 | NEW_METHOD_DECLARATOR (d, $1, NULL); | |
480 | $$ = d; | |
481 | } | |
482 | | identifier OP_TK formal_parameter_list CP_TK | |
483 | { | |
484 | struct method_declarator *d; | |
485 | NEW_METHOD_DECLARATOR (d, $1, $3); | |
486 | $$ = d; | |
487 | } | |
488 | | method_declarator OSB_TK CSB_TK | |
489 | ; | |
490 | ||
491 | formal_parameter_list: | |
492 | formal_parameter | |
493 | | formal_parameter_list C_TK formal_parameter | |
494 | { | |
1ab1061d | 495 | $$ = concat ($1, ",", $3, NULL); |
377029eb | 496 | } |
497 | ; | |
498 | ||
499 | formal_parameter: | |
500 | type variable_declarator_id | |
501 | { | |
502 | USE_ABSORBER; | |
01b49881 | 503 | if (bracket_count) |
504 | { | |
505 | int i; | |
506 | char *n = xmalloc (bracket_count + 1 + strlen ($$)); | |
507 | for (i = 0; i < bracket_count; ++i) | |
508 | n[i] = '['; | |
509 | strcpy (n + bracket_count, $$); | |
510 | $$ = n; | |
511 | } | |
512 | else | |
513 | $$ = $1; | |
377029eb | 514 | } |
515 | | modifiers type variable_declarator_id /* Added, JDK1.1 final locals */ | |
01b49881 | 516 | { |
517 | if (bracket_count) | |
518 | { | |
519 | int i; | |
520 | char *n = xmalloc (bracket_count + 1 + strlen ($$)); | |
521 | for (i = 0; i < bracket_count; ++i) | |
522 | n[i] = '['; | |
523 | strcpy (n + bracket_count, $$); | |
524 | $$ = n; | |
525 | } | |
526 | else | |
527 | $$ = $2; | |
528 | } | |
377029eb | 529 | ; |
530 | ||
531 | throws: | |
532 | | THROWS_TK class_type_list | |
533 | ; | |
534 | ||
535 | class_type_list: | |
536 | class_type | |
537 | { USE_ABSORBER; } | |
538 | | class_type_list C_TK class_type | |
539 | { USE_ABSORBER; } | |
540 | ; | |
541 | ||
542 | method_body: | |
543 | block | |
377029eb | 544 | | SC_TK |
545 | ; | |
546 | ||
547 | /* 19.8.4 Productions from 8.5: Static Initializers */ | |
548 | static_initializer: | |
549 | static block | |
377029eb | 550 | ; |
551 | ||
552 | static: /* Test lval.sub_token here */ | |
553 | MODIFIER_TK | |
554 | { USE_ABSORBER; } | |
555 | ; | |
556 | ||
557 | /* 19.8.5 Productions from 8.6: Constructor Declarations */ | |
558 | /* NOTE FOR FURTHER WORK ON CONSTRUCTORS: | |
559 | - If a forbidded modifier is found, the the error is either the use of | |
560 | a forbidded modifier for a constructor OR bogus attempt to declare a | |
561 | method without having specified the return type. FIXME */ | |
562 | constructor_declaration: | |
563 | constructor_declarator throws constructor_body | |
564 | | modifiers constructor_declarator throws constructor_body | |
565 | { modifier_value = 0; } | |
566 | /* extra SC_TK, FIXME */ | |
567 | | constructor_declarator throws constructor_body SC_TK | |
568 | /* extra SC_TK, FIXME */ | |
569 | | modifiers constructor_declarator throws constructor_body SC_TK | |
570 | { modifier_value = 0; } | |
571 | /* I'm not happy with the SC_TK addition. It isn't in the grammer and should | |
572 | probably be matched by and empty statement. But it doesn't work. FIXME */ | |
573 | ; | |
574 | ||
575 | constructor_declarator: | |
576 | simple_name OP_TK CP_TK | |
577 | { USE_ABSORBER; } | |
578 | | simple_name OP_TK formal_parameter_list CP_TK | |
579 | { USE_ABSORBER; } | |
580 | ; | |
581 | ||
582 | constructor_body: | |
583 | OCB_TK CCB_TK | |
584 | | OCB_TK explicit_constructor_invocation CCB_TK | |
585 | | OCB_TK block_statements CCB_TK | |
586 | | OCB_TK explicit_constructor_invocation block_statements CCB_TK | |
587 | ; | |
588 | ||
589 | /* Error recovery for that rule moved down expression_statement: rule. */ | |
590 | explicit_constructor_invocation: | |
591 | this_or_super OP_TK CP_TK SC_TK | |
592 | | this_or_super OP_TK argument_list CP_TK SC_TK | |
593 | /* Added, JDK1.1 inner classes. Modified because the rule | |
594 | 'primary' couldn't work. */ | |
595 | | name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK | |
596 | { USE_ABSORBER; } | |
597 | | name DOT_TK SUPER_TK OP_TK CP_TK SC_TK | |
598 | { USE_ABSORBER; } | |
599 | ; | |
600 | ||
601 | this_or_super: /* Added, simplifies error diagnostics */ | |
602 | THIS_TK | |
603 | | SUPER_TK | |
604 | ; | |
605 | ||
606 | /* 19.9 Productions from 9: Interfaces */ | |
607 | /* 19.9.1 Productions from 9.1: Interfaces Declarations */ | |
608 | interface_declaration: | |
f8ee1774 | 609 | INTERFACE_TK identifier |
eec4b190 | 610 | { report_class_declaration ($2); modifier_value = 0; } |
f8ee1774 | 611 | interface_body |
612 | | modifiers INTERFACE_TK identifier | |
eec4b190 | 613 | { report_class_declaration ($3); modifier_value = 0; } |
f8ee1774 | 614 | interface_body |
615 | | INTERFACE_TK identifier extends_interfaces | |
eec4b190 | 616 | { report_class_declaration ($2); modifier_value = 0; } |
f8ee1774 | 617 | interface_body |
618 | | modifiers INTERFACE_TK identifier extends_interfaces | |
eec4b190 | 619 | { report_class_declaration ($3); modifier_value = 0; } |
f8ee1774 | 620 | interface_body |
377029eb | 621 | ; |
622 | ||
623 | extends_interfaces: | |
624 | EXTENDS_TK interface_type | |
625 | | extends_interfaces C_TK interface_type | |
626 | ; | |
627 | ||
628 | interface_body: | |
629 | OCB_TK CCB_TK | |
f8ee1774 | 630 | { pop_class_context (); } |
377029eb | 631 | | OCB_TK interface_member_declarations CCB_TK |
f8ee1774 | 632 | { pop_class_context (); } |
377029eb | 633 | ; |
634 | ||
635 | interface_member_declarations: | |
636 | interface_member_declaration | |
637 | | interface_member_declarations interface_member_declaration | |
638 | ; | |
639 | ||
640 | interface_member_declaration: | |
641 | constant_declaration | |
642 | | abstract_method_declaration | |
643 | | class_declaration /* Added, JDK1.1 inner classes */ | |
644 | | interface_declaration /* Added, JDK1.1 inner classes */ | |
645 | ; | |
646 | ||
647 | constant_declaration: | |
648 | field_declaration | |
649 | ; | |
650 | ||
651 | abstract_method_declaration: | |
652 | method_header SC_TK | |
653 | ; | |
654 | ||
655 | /* 19.10 Productions from 10: Arrays */ | |
656 | array_initializer: | |
657 | OCB_TK CCB_TK | |
658 | | OCB_TK variable_initializers CCB_TK | |
659 | | OCB_TK C_TK CCB_TK | |
660 | | OCB_TK variable_initializers C_TK CCB_TK | |
661 | ; | |
662 | ||
663 | variable_initializers: | |
664 | variable_initializer | |
665 | | variable_initializers C_TK variable_initializer | |
666 | ; | |
667 | ||
668 | /* 19.11 Production from 14: Blocks and Statements */ | |
669 | block: | |
670 | OCB_TK CCB_TK | |
671 | | OCB_TK block_statements CCB_TK | |
672 | ; | |
673 | ||
674 | block_statements: | |
675 | block_statement | |
676 | | block_statements block_statement | |
677 | ; | |
678 | ||
679 | block_statement: | |
680 | local_variable_declaration_statement | |
681 | | statement | |
682 | | class_declaration /* Added, JDK1.1 inner classes */ | |
683 | ; | |
684 | ||
685 | local_variable_declaration_statement: | |
686 | local_variable_declaration SC_TK /* Can't catch missing ';' here */ | |
687 | ; | |
688 | ||
689 | local_variable_declaration: | |
690 | type variable_declarators | |
691 | { USE_ABSORBER; } | |
692 | | modifiers type variable_declarators /* Added, JDK1.1 final locals */ | |
693 | { modifier_value = 0; } | |
694 | ; | |
695 | ||
696 | statement: | |
697 | statement_without_trailing_substatement | |
698 | | labeled_statement | |
699 | | if_then_statement | |
700 | | if_then_else_statement | |
701 | | while_statement | |
702 | | for_statement | |
703 | ; | |
704 | ||
705 | statement_nsi: | |
706 | statement_without_trailing_substatement | |
707 | | labeled_statement_nsi | |
708 | | if_then_else_statement_nsi | |
709 | | while_statement_nsi | |
710 | | for_statement_nsi | |
711 | ; | |
712 | ||
713 | statement_without_trailing_substatement: | |
714 | block | |
715 | | empty_statement | |
716 | | expression_statement | |
717 | | switch_statement | |
718 | | do_statement | |
719 | | break_statement | |
720 | | continue_statement | |
721 | | return_statement | |
722 | | synchronized_statement | |
723 | | throw_statement | |
724 | | try_statement | |
ec31870d | 725 | | assert_statement |
377029eb | 726 | ; |
727 | ||
728 | empty_statement: | |
729 | SC_TK | |
730 | ; | |
731 | ||
732 | label_decl: | |
733 | identifier REL_CL_TK | |
734 | { USE_ABSORBER; } | |
735 | ; | |
736 | ||
737 | labeled_statement: | |
738 | label_decl statement | |
739 | ; | |
740 | ||
741 | labeled_statement_nsi: | |
742 | label_decl statement_nsi | |
743 | ; | |
744 | ||
745 | /* We concentrate here a bunch of error handling rules that we couldn't write | |
746 | earlier, because expression_statement catches a missing ';'. */ | |
747 | expression_statement: | |
748 | statement_expression SC_TK | |
749 | ; | |
750 | ||
751 | statement_expression: | |
752 | assignment | |
753 | | pre_increment_expression | |
754 | | pre_decrement_expression | |
755 | | post_increment_expression | |
756 | | post_decrement_expression | |
757 | | method_invocation | |
758 | | class_instance_creation_expression | |
759 | ; | |
760 | ||
761 | if_then_statement: | |
cd269709 | 762 | IF_TK OP_TK expression CP_TK statement { ++complexity; } |
377029eb | 763 | ; |
764 | ||
765 | if_then_else_statement: | |
766 | IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement | |
cd269709 | 767 | { ++complexity; } |
377029eb | 768 | ; |
769 | ||
770 | if_then_else_statement_nsi: | |
771 | IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi | |
cd269709 | 772 | { ++complexity; } |
377029eb | 773 | ; |
774 | ||
775 | switch_statement: | |
776 | SWITCH_TK OP_TK expression CP_TK switch_block | |
777 | ; | |
778 | ||
779 | switch_block: | |
780 | OCB_TK CCB_TK | |
781 | | OCB_TK switch_labels CCB_TK | |
782 | | OCB_TK switch_block_statement_groups CCB_TK | |
783 | | OCB_TK switch_block_statement_groups switch_labels CCB_TK | |
784 | ; | |
785 | ||
786 | switch_block_statement_groups: | |
787 | switch_block_statement_group | |
788 | | switch_block_statement_groups switch_block_statement_group | |
789 | ; | |
790 | ||
791 | switch_block_statement_group: | |
cd269709 | 792 | switch_labels block_statements { ++complexity; } |
377029eb | 793 | ; |
794 | ||
795 | ||
796 | switch_labels: | |
797 | switch_label | |
798 | | switch_labels switch_label | |
799 | ; | |
800 | ||
801 | switch_label: | |
802 | CASE_TK constant_expression REL_CL_TK | |
803 | | DEFAULT_TK REL_CL_TK | |
804 | ; | |
805 | ||
806 | while_expression: | |
cd269709 | 807 | WHILE_TK OP_TK expression CP_TK { ++complexity; } |
377029eb | 808 | ; |
809 | ||
810 | while_statement: | |
811 | while_expression statement | |
812 | ; | |
813 | ||
814 | while_statement_nsi: | |
815 | while_expression statement_nsi | |
816 | ; | |
817 | ||
818 | do_statement_begin: | |
819 | DO_TK | |
820 | ; | |
821 | ||
822 | do_statement: | |
823 | do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK | |
cd269709 | 824 | { ++complexity; } |
377029eb | 825 | ; |
826 | ||
827 | for_statement: | |
828 | for_begin SC_TK expression SC_TK for_update CP_TK statement | |
829 | | for_begin SC_TK SC_TK for_update CP_TK statement | |
830 | ; | |
831 | ||
832 | for_statement_nsi: | |
833 | for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi | |
834 | | for_begin SC_TK SC_TK for_update CP_TK statement_nsi | |
835 | ; | |
836 | ||
837 | for_header: | |
838 | FOR_TK OP_TK | |
839 | ; | |
840 | ||
841 | for_begin: | |
cd269709 | 842 | for_header for_init { ++complexity; } |
377029eb | 843 | ; |
844 | for_init: /* Can be empty */ | |
845 | | statement_expression_list | |
846 | | local_variable_declaration | |
847 | ; | |
848 | ||
849 | for_update: /* Can be empty */ | |
850 | | statement_expression_list | |
851 | ; | |
852 | ||
853 | statement_expression_list: | |
854 | statement_expression | |
855 | | statement_expression_list C_TK statement_expression | |
856 | ; | |
857 | ||
858 | break_statement: | |
859 | BREAK_TK SC_TK | |
860 | | BREAK_TK identifier SC_TK | |
861 | ; | |
862 | ||
cd269709 | 863 | /* `continue' with a label is considered for complexity but ordinary |
864 | continue is not. */ | |
377029eb | 865 | continue_statement: |
866 | CONTINUE_TK SC_TK | |
cd269709 | 867 | | CONTINUE_TK identifier SC_TK { ++complexity; } |
377029eb | 868 | ; |
869 | ||
870 | return_statement: | |
871 | RETURN_TK SC_TK | |
872 | | RETURN_TK expression SC_TK | |
873 | ; | |
874 | ||
875 | throw_statement: | |
cd269709 | 876 | THROW_TK expression SC_TK { ++complexity; } |
377029eb | 877 | ; |
878 | ||
ec31870d | 879 | assert_statement: |
880 | ASSERT_TK expression REL_CL_TK expression SC_TK | |
881 | | ASSERT_TK expression SC_TK | |
882 | | ASSERT_TK error | |
883 | {yyerror ("Missing term"); RECOVER;} | |
884 | | ASSERT_TK expression error | |
885 | {yyerror ("';' expected"); RECOVER;} | |
886 | ; | |
377029eb | 887 | synchronized_statement: |
888 | synchronized OP_TK expression CP_TK block | |
889 | | synchronized OP_TK expression CP_TK error | |
890 | ; | |
891 | ||
892 | synchronized: /* Test lval.sub_token here */ | |
893 | MODIFIER_TK | |
894 | { USE_ABSORBER; } | |
895 | ; | |
896 | ||
897 | try_statement: | |
898 | TRY_TK block catches | |
899 | | TRY_TK block finally | |
900 | | TRY_TK block catches finally | |
901 | ; | |
902 | ||
903 | catches: | |
904 | catch_clause | |
905 | | catches catch_clause | |
906 | ; | |
907 | ||
908 | catch_clause: | |
cd269709 | 909 | CATCH_TK OP_TK formal_parameter CP_TK block { ++complexity; } |
377029eb | 910 | ; |
911 | ||
912 | finally: | |
cd269709 | 913 | FINALLY_TK block { ++complexity; } |
377029eb | 914 | ; |
915 | ||
916 | /* 19.12 Production from 15: Expressions */ | |
917 | primary: | |
918 | primary_no_new_array | |
919 | | array_creation_expression | |
920 | ; | |
921 | ||
922 | primary_no_new_array: | |
923 | literal | |
924 | | THIS_TK | |
925 | | OP_TK expression CP_TK | |
926 | | class_instance_creation_expression | |
927 | | field_access | |
928 | | method_invocation | |
929 | | array_access | |
06c564bd | 930 | | type_literals |
377029eb | 931 | /* Added, JDK1.1 inner classes. Documentation is wrong |
932 | refering to a 'ClassName' (class_name) rule that doesn't | |
933 | exist. Used name instead. */ | |
934 | | name DOT_TK THIS_TK | |
935 | { USE_ABSORBER; } | |
936 | ; | |
937 | ||
06c564bd | 938 | type_literals: |
939 | name DOT_TK CLASS_TK | |
940 | { USE_ABSORBER; } | |
941 | | array_type DOT_TK CLASS_TK | |
942 | { USE_ABSORBER; } | |
943 | | primitive_type DOT_TK CLASS_TK | |
944 | { USE_ABSORBER; } | |
945 | | VOID_TK DOT_TK CLASS_TK | |
946 | { USE_ABSORBER; } | |
947 | ; | |
948 | ||
377029eb | 949 | class_instance_creation_expression: |
950 | NEW_TK class_type OP_TK argument_list CP_TK | |
951 | | NEW_TK class_type OP_TK CP_TK | |
52725f92 | 952 | | anonymous_class_creation |
377029eb | 953 | | something_dot_new identifier OP_TK CP_TK |
954 | | something_dot_new identifier OP_TK CP_TK class_body | |
955 | | something_dot_new identifier OP_TK argument_list CP_TK | |
956 | | something_dot_new identifier OP_TK argument_list CP_TK class_body | |
957 | ; | |
958 | ||
52725f92 | 959 | anonymous_class_creation: |
960 | NEW_TK class_type OP_TK CP_TK | |
bb644f25 | 961 | { report_class_declaration (anonymous_context); } |
52725f92 | 962 | class_body |
963 | | NEW_TK class_type OP_TK argument_list CP_TK | |
bb644f25 | 964 | { report_class_declaration (anonymous_context); } |
52725f92 | 965 | class_body |
966 | ; | |
967 | ||
377029eb | 968 | something_dot_new: /* Added, not part of the specs. */ |
969 | name DOT_TK NEW_TK | |
970 | { USE_ABSORBER; } | |
971 | | primary DOT_TK NEW_TK | |
972 | ; | |
973 | ||
974 | argument_list: | |
975 | expression | |
976 | | argument_list C_TK expression | |
977 | | argument_list C_TK error | |
978 | ; | |
979 | ||
980 | array_creation_expression: | |
981 | NEW_TK primitive_type dim_exprs | |
982 | | NEW_TK class_or_interface_type dim_exprs | |
983 | | NEW_TK primitive_type dim_exprs dims | |
984 | | NEW_TK class_or_interface_type dim_exprs dims | |
985 | /* Added, JDK1.1 anonymous array. Initial documentation rule | |
986 | modified */ | |
987 | | NEW_TK class_or_interface_type dims array_initializer | |
988 | | NEW_TK primitive_type dims array_initializer | |
989 | ; | |
990 | ||
991 | dim_exprs: | |
992 | dim_expr | |
993 | | dim_exprs dim_expr | |
994 | ; | |
995 | ||
996 | dim_expr: | |
997 | OSB_TK expression CSB_TK | |
998 | ; | |
999 | ||
1000 | dims: | |
1001 | OSB_TK CSB_TK | |
06c564bd | 1002 | { bracket_count = 1; } |
377029eb | 1003 | | dims OSB_TK CSB_TK |
06c564bd | 1004 | { bracket_count++; } |
377029eb | 1005 | ; |
1006 | ||
1007 | field_access: | |
1008 | primary DOT_TK identifier | |
1009 | | SUPER_TK DOT_TK identifier | |
1010 | ; | |
1011 | ||
cd269709 | 1012 | /* We include method invocation in the complexity measure on the |
1013 | theory that most method calls are virtual and therefore involve a | |
1014 | decision point. */ | |
377029eb | 1015 | method_invocation: |
1016 | name OP_TK CP_TK | |
cd269709 | 1017 | { USE_ABSORBER; ++complexity; } |
377029eb | 1018 | | name OP_TK argument_list CP_TK |
cd269709 | 1019 | { USE_ABSORBER; ++complexity; } |
1020 | | primary DOT_TK identifier OP_TK CP_TK { ++complexity; } | |
1021 | | primary DOT_TK identifier OP_TK argument_list CP_TK { ++complexity; } | |
1022 | | SUPER_TK DOT_TK identifier OP_TK CP_TK { ++complexity; } | |
1023 | | SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK { ++complexity; } | |
377029eb | 1024 | ; |
1025 | ||
1026 | array_access: | |
1027 | name OSB_TK expression CSB_TK | |
1028 | { USE_ABSORBER; } | |
1029 | | primary_no_new_array OSB_TK expression CSB_TK | |
1030 | ; | |
1031 | ||
1032 | postfix_expression: | |
1033 | primary | |
1034 | | name | |
1035 | { USE_ABSORBER; } | |
1036 | | post_increment_expression | |
1037 | | post_decrement_expression | |
1038 | ; | |
1039 | ||
1040 | post_increment_expression: | |
1041 | postfix_expression INCR_TK | |
1042 | ; | |
1043 | ||
1044 | post_decrement_expression: | |
1045 | postfix_expression DECR_TK | |
1046 | ; | |
1047 | ||
1048 | unary_expression: | |
1049 | pre_increment_expression | |
1050 | | pre_decrement_expression | |
1051 | | PLUS_TK unary_expression | |
1052 | | MINUS_TK unary_expression | |
1053 | | unary_expression_not_plus_minus | |
1054 | ; | |
1055 | ||
1056 | pre_increment_expression: | |
1057 | INCR_TK unary_expression | |
1058 | ; | |
1059 | ||
1060 | pre_decrement_expression: | |
1061 | DECR_TK unary_expression | |
1062 | ; | |
1063 | ||
1064 | unary_expression_not_plus_minus: | |
1065 | postfix_expression | |
1066 | | NOT_TK unary_expression | |
1067 | | NEG_TK unary_expression | |
1068 | | cast_expression | |
1069 | ; | |
1070 | ||
1071 | cast_expression: /* Error handling here is potentially weak */ | |
1072 | OP_TK primitive_type dims CP_TK unary_expression | |
1073 | | OP_TK primitive_type CP_TK unary_expression | |
1074 | | OP_TK expression CP_TK unary_expression_not_plus_minus | |
1075 | | OP_TK name dims CP_TK unary_expression_not_plus_minus | |
1076 | ; | |
1077 | ||
1078 | multiplicative_expression: | |
1079 | unary_expression | |
1080 | | multiplicative_expression MULT_TK unary_expression | |
1081 | | multiplicative_expression DIV_TK unary_expression | |
1082 | | multiplicative_expression REM_TK unary_expression | |
1083 | ; | |
1084 | ||
1085 | additive_expression: | |
1086 | multiplicative_expression | |
1087 | | additive_expression PLUS_TK multiplicative_expression | |
1088 | | additive_expression MINUS_TK multiplicative_expression | |
1089 | ; | |
1090 | ||
1091 | shift_expression: | |
1092 | additive_expression | |
1093 | | shift_expression LS_TK additive_expression | |
1094 | | shift_expression SRS_TK additive_expression | |
1095 | | shift_expression ZRS_TK additive_expression | |
1096 | ; | |
1097 | ||
1098 | relational_expression: | |
1099 | shift_expression | |
1100 | | relational_expression LT_TK shift_expression | |
1101 | | relational_expression GT_TK shift_expression | |
1102 | | relational_expression LTE_TK shift_expression | |
1103 | | relational_expression GTE_TK shift_expression | |
1104 | | relational_expression INSTANCEOF_TK reference_type | |
1105 | ; | |
1106 | ||
1107 | equality_expression: | |
1108 | relational_expression | |
1109 | | equality_expression EQ_TK relational_expression | |
1110 | | equality_expression NEQ_TK relational_expression | |
1111 | ; | |
1112 | ||
1113 | and_expression: | |
1114 | equality_expression | |
1115 | | and_expression AND_TK equality_expression | |
1116 | ; | |
1117 | ||
1118 | exclusive_or_expression: | |
1119 | and_expression | |
1120 | | exclusive_or_expression XOR_TK and_expression | |
1121 | ; | |
1122 | ||
1123 | inclusive_or_expression: | |
1124 | exclusive_or_expression | |
1125 | | inclusive_or_expression OR_TK exclusive_or_expression | |
1126 | ; | |
1127 | ||
1128 | conditional_and_expression: | |
1129 | inclusive_or_expression | |
1130 | | conditional_and_expression BOOL_AND_TK inclusive_or_expression | |
cd269709 | 1131 | { ++complexity; } |
377029eb | 1132 | ; |
1133 | ||
1134 | conditional_or_expression: | |
1135 | conditional_and_expression | |
1136 | | conditional_or_expression BOOL_OR_TK conditional_and_expression | |
cd269709 | 1137 | { ++complexity; } |
377029eb | 1138 | ; |
1139 | ||
1140 | conditional_expression: /* Error handling here is weak */ | |
1141 | conditional_or_expression | |
1142 | | conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression | |
cd269709 | 1143 | { ++complexity; } |
377029eb | 1144 | ; |
1145 | ||
1146 | assignment_expression: | |
1147 | conditional_expression | |
1148 | | assignment | |
1149 | ; | |
1150 | ||
1151 | assignment: | |
1152 | left_hand_side assignment_operator assignment_expression | |
1153 | ; | |
1154 | ||
1155 | left_hand_side: | |
1156 | name | |
1157 | { USE_ABSORBER; } | |
1158 | | field_access | |
1159 | | array_access | |
1160 | ; | |
1161 | ||
1162 | assignment_operator: | |
1163 | ASSIGN_ANY_TK | |
1164 | | ASSIGN_TK | |
1165 | ; | |
1166 | ||
1167 | expression: | |
1168 | assignment_expression | |
1169 | ; | |
1170 | ||
1171 | constant_expression: | |
1172 | expression | |
1173 | ; | |
1174 | ||
1175 | %% | |
1176 | \f | |
377029eb | 1177 | /* Create a new parser context */ |
1178 | ||
1179 | void | |
1180 | java_push_parser_context () | |
1181 | { | |
1182 | struct parser_ctxt *new = | |
1ab1061d | 1183 | (struct parser_ctxt *) xcalloc (1, sizeof (struct parser_ctxt)); |
377029eb | 1184 | |
377029eb | 1185 | new->next = ctxp; |
1186 | ctxp = new; | |
1187 | } | |
1188 | ||
f8ee1774 | 1189 | static void |
1190 | push_class_context (name) | |
1191 | const char *name; | |
1192 | { | |
bb644f25 | 1193 | struct class_context *ctx; |
1194 | ||
1195 | ctx = (struct class_context *) xmalloc (sizeof (struct class_context)); | |
1196 | ctx->name = (char *) name; | |
1197 | ctx->next = current_class_context; | |
1198 | current_class_context = ctx; | |
f8ee1774 | 1199 | } |
1200 | ||
1201 | static void | |
1202 | pop_class_context () | |
1203 | { | |
bb644f25 | 1204 | struct class_context *ctx; |
1205 | ||
1206 | if (current_class_context == NULL) | |
1207 | return; | |
1208 | ||
1209 | ctx = current_class_context->next; | |
1210 | if (current_class_context->name != anonymous_context) | |
1211 | free (current_class_context->name); | |
1212 | free (current_class_context); | |
1213 | ||
1214 | current_class_context = ctx; | |
1215 | if (current_class_context == NULL) | |
1216 | anonymous_count = 0; | |
1217 | } | |
1218 | ||
1219 | /* Recursively construct the class name. This is just a helper | |
1220 | function for get_class_name(). */ | |
1221 | static int | |
1222 | make_class_name_recursive (stack, ctx) | |
1223 | struct obstack *stack; | |
1224 | struct class_context *ctx; | |
1225 | { | |
1226 | if (! ctx) | |
1227 | return 0; | |
1228 | ||
1229 | make_class_name_recursive (stack, ctx->next); | |
1230 | ||
1231 | /* Replace an anonymous context with the appropriate counter value. */ | |
1232 | if (ctx->name == anonymous_context) | |
52725f92 | 1233 | { |
bb644f25 | 1234 | char buf[50]; |
1235 | ++anonymous_count; | |
1236 | sprintf (buf, "%d", anonymous_count); | |
1237 | ctx->name = xstrdup (buf); | |
52725f92 | 1238 | } |
bb644f25 | 1239 | |
1240 | obstack_grow (stack, ctx->name, strlen (ctx->name)); | |
1241 | obstack_1grow (stack, '$'); | |
1242 | ||
1243 | return ISDIGIT (ctx->name[0]); | |
1244 | } | |
1245 | ||
1246 | /* Return a newly allocated string holding the name of the class. */ | |
1247 | static char * | |
1248 | get_class_name () | |
1249 | { | |
1250 | char *result; | |
1251 | int last_was_digit; | |
1252 | struct obstack name_stack; | |
1253 | ||
1254 | obstack_init (&name_stack); | |
1255 | ||
1256 | /* Duplicate the logic of parse.y:maybe_make_nested_class_name(). */ | |
1257 | last_was_digit = make_class_name_recursive (&name_stack, | |
1258 | current_class_context->next); | |
1259 | ||
1260 | if (! last_was_digit | |
1261 | && method_depth | |
1262 | && current_class_context->name != anonymous_context) | |
52725f92 | 1263 | { |
bb644f25 | 1264 | char buf[50]; |
1265 | ++anonymous_count; | |
1266 | sprintf (buf, "%d", anonymous_count); | |
1267 | obstack_grow (&name_stack, buf, strlen (buf)); | |
1268 | obstack_1grow (&name_stack, '$'); | |
52725f92 | 1269 | } |
bb644f25 | 1270 | |
1271 | if (current_class_context->name == anonymous_context) | |
1272 | { | |
1273 | char buf[50]; | |
1274 | ++anonymous_count; | |
1275 | sprintf (buf, "%d", anonymous_count); | |
1276 | current_class_context->name = xstrdup (buf); | |
1277 | obstack_grow0 (&name_stack, buf, strlen (buf)); | |
1278 | } | |
1279 | else | |
1280 | obstack_grow0 (&name_stack, current_class_context->name, | |
1281 | strlen (current_class_context->name)); | |
1282 | ||
1283 | result = xstrdup (obstack_finish (&name_stack)); | |
1284 | obstack_free (&name_stack, NULL); | |
1285 | ||
1286 | return result; | |
f8ee1774 | 1287 | } |
1288 | ||
377029eb | 1289 | /* Actions defined here */ |
1290 | ||
1291 | static void | |
1292 | report_class_declaration (name) | |
1c637495 | 1293 | const char * name; |
377029eb | 1294 | { |
1295 | extern int flag_dump_class, flag_list_filename; | |
1296 | ||
52725f92 | 1297 | push_class_context (name); |
377029eb | 1298 | if (flag_dump_class) |
1299 | { | |
bb644f25 | 1300 | char *name = get_class_name (); |
1301 | ||
377029eb | 1302 | if (!previous_output) |
1303 | { | |
1304 | if (flag_list_filename) | |
1305 | fprintf (out, "%s: ", input_filename); | |
1306 | previous_output = 1; | |
1307 | } | |
bb644f25 | 1308 | |
377029eb | 1309 | if (package_name) |
bb644f25 | 1310 | fprintf (out, "%s.%s ", package_name, name); |
377029eb | 1311 | else |
bb644f25 | 1312 | fprintf (out, "%s ", name); |
1313 | ||
1314 | free (name); | |
377029eb | 1315 | } |
377029eb | 1316 | } |
1317 | ||
1318 | static void | |
1319 | report_main_declaration (declarator) | |
1320 | struct method_declarator *declarator; | |
1321 | { | |
1322 | extern int flag_find_main; | |
1323 | ||
1324 | if (flag_find_main | |
1325 | && modifier_value == 2 | |
1326 | && !strcmp (declarator->method_name, "main") | |
1327 | && declarator->args | |
1328 | && declarator->args [0] == '[' | |
d86f7f49 | 1329 | && (! strcmp (declarator->args+1, "String") |
1330 | || ! strcmp (declarator->args + 1, "java.lang.String")) | |
bb644f25 | 1331 | && current_class_context) |
377029eb | 1332 | { |
1333 | if (!previous_output) | |
1334 | { | |
bb644f25 | 1335 | char *name = get_class_name (); |
377029eb | 1336 | if (package_name) |
bb644f25 | 1337 | fprintf (out, "%s.%s ", package_name, name); |
377029eb | 1338 | else |
bb644f25 | 1339 | fprintf (out, "%s", name); |
1340 | free (name); | |
377029eb | 1341 | previous_output = 1; |
1342 | } | |
1343 | } | |
1344 | } | |
1345 | ||
cd269709 | 1346 | void |
1347 | report () | |
1348 | { | |
1349 | extern int flag_complexity; | |
1350 | if (flag_complexity) | |
1351 | fprintf (out, "%s %d\n", input_filename, complexity); | |
1352 | } | |
1353 | ||
377029eb | 1354 | /* Reset global status used by the report functions. */ |
1355 | ||
1356 | void reset_report () | |
1357 | { | |
1358 | previous_output = 0; | |
52725f92 | 1359 | package_name = NULL; |
bb644f25 | 1360 | current_class_context = NULL; |
cd269709 | 1361 | complexity = 0; |
377029eb | 1362 | } |
1363 | ||
1364 | void | |
1365 | yyerror (msg) | |
1c637495 | 1366 | const char *msg ATTRIBUTE_UNUSED; |
377029eb | 1367 | { |
567b6c3b | 1368 | fprintf (stderr, "%s: %d: %s\n", input_filename, lineno, msg); |
1369 | exit (1); | |
377029eb | 1370 | } |