1 /** \file
2 * Copyright (c) 1999, 2000 Carlo Wood. All rights reserved.<br>
3 * Copyright (c) 1994 Joseph Arceneaux. All rights reserved.<br>
4 * Copyright (c) 1985 Sun Microsystems, Inc. <br>
5 * Copyright (c) 1980 The Regents of the University of California.<br>
6 * Copyright (c) 1976 Board of Trustees of the University of Illinois. All rights reserved.<br>
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * - 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * - 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.<br>
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * This program is free software; you can redistribute it and/or
33 * modify it under the terms of the GNU General Public License
34 * as published by the Free Software Foundation; either version 3
35 * of the License, or (at your option) any later version.
36 *
37 * This program is distributed in the hope that it will be useful,
38 * but WITHOUT ANY WARRANTY; without even the implied warranty of
39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 * GNU General Public License for more details.
41 *
42 * You should have received a copy of the GNU General Public License
43 * along with this program. If not, see <http://www.gnu.org/licenses/>.
44 *
45 */
46
47 #include "sys.h"
48 #include "indent.h"
49 #include "parse.h"
50 #include "globs.h"
51
52 RCSTAG_CC ("$Id$");
53
54 parser_state_ty *parser_state_tos = NULL;
55
56 #define INITIAL_BUFFER_SIZE 1000
57 #define INITIAL_STACK_SIZE 2
58
59 /**
60 *
61 */
62
init_parser(void)63 extern void init_parser(void)
64 {
65 parser_state_tos = xmalloc(sizeof (parser_state_ty));
66
67 /* GDB_HOOK_parser_state_tos */
68 parser_state_tos->p_stack_size = INITIAL_STACK_SIZE;
69 parser_state_tos->p_stack = xmalloc(INITIAL_STACK_SIZE * sizeof (codes_ty));
70 parser_state_tos->il = xmalloc(INITIAL_STACK_SIZE * sizeof (int));
71 parser_state_tos->cstk = xmalloc(INITIAL_STACK_SIZE * sizeof (int));
72 parser_state_tos->paren_indents_size = 8;
73 parser_state_tos->paren_indents = xmalloc(parser_state_tos->paren_indents_size * sizeof (short));
74
75 /* Although these are supposed to grow if we reach the end,
76 * I can find no place in the code which does this. */
77 combuf = xmalloc(INITIAL_BUFFER_SIZE);
78 labbuf = xmalloc(INITIAL_BUFFER_SIZE);
79 codebuf = xmalloc(INITIAL_BUFFER_SIZE);
80
81 save_com.size = INITIAL_BUFFER_SIZE;
82 save_com.end = save_com.ptr = xmalloc(save_com.size);
83 save_com.len = save_com.column = 0;
84
85 di_stack_alloc = 2;
86 di_stack = xmalloc(di_stack_alloc * sizeof (*di_stack));
87 }
88
89 /**
90 * Free all memory allocated in init_parser().
91 */
uninit_parser(void)92 extern void uninit_parser(void)
93 {
94 if (!parser_state_tos)
95 {
96 return;
97 }
98
99 xfree(parser_state_tos->p_stack);
100 xfree(parser_state_tos->il);
101 xfree(parser_state_tos->cstk);
102 xfree(parser_state_tos->paren_indents);
103 xfree(parser_state_tos);
104 xfree(save_com.ptr);
105 xfree(combuf);
106 xfree(labbuf);
107 xfree(codebuf);
108 xfree(di_stack);
109 parser_state_tos = NULL;
110 }
111
112 /**
113 *
114 */
115
reset_parser(void)116 extern void reset_parser(void)
117 {
118 parser_state_tos->next = 0;
119 parser_state_tos->tos = 0;
120 parser_state_tos->p_stack[0] = stmt; /*!< this is the parser's stack */
121 parser_state_tos->last_nl = true; /*!< this is true if the last thing
122 * scanned was a newline */
123 parser_state_tos->last_token = start_token;
124 parser_state_tos->last_saw_nl = false;
125 parser_state_tos->broken_at_non_nl = false;
126 parser_state_tos->box_com = false;
127 parser_state_tos->cast_mask = 0;
128 parser_state_tos->noncast_mask = 0;
129 parser_state_tos->sizeof_mask = 0;
130 parser_state_tos->block_init = 0;
131 parser_state_tos->block_init_level = 0;
132 parser_state_tos->col_1 = false;
133 parser_state_tos->com_col = 0;
134 parser_state_tos->dec_nest = 0;
135 parser_state_tos->i_l_follow = 0;
136 parser_state_tos->ind_level = 0;
137 parser_state_tos->last_u_d = false;
138 parser_state_tos->p_l_follow = 0;
139 parser_state_tos->paren_level = 0;
140 parser_state_tos->paren_depth = 0;
141 parser_state_tos->search_brace = false;
142 parser_state_tos->use_ff = false;
143 parser_state_tos->its_a_keyword = false;
144 parser_state_tos->sizeof_keyword = false;
145 parser_state_tos->in_parameter_declaration = false;
146 parser_state_tos->just_saw_decl = 0;
147 parser_state_tos->in_decl = false;
148 parser_state_tos->decl_on_line = false;
149 parser_state_tos->in_or_st = 0;
150 parser_state_tos->want_blank = false;
151 parser_state_tos->in_stmt = false;
152 parser_state_tos->ind_stmt = false;
153 parser_state_tos->procname = "\0";
154 parser_state_tos->procname_end = "\0";
155 parser_state_tos->classname = "\0";
156 parser_state_tos->classname_end = "\0";
157 parser_state_tos->pcase = false;
158 parser_state_tos->dec_nest = 0;
159 parser_state_tos->can_break = bb_none;
160 parser_state_tos->saw_double_colon = false;
161 parser_state_tos->is_func_ptr_decl = false;
162
163 parser_state_tos->il[0] = 0;
164 parser_state_tos->cstk[0] = 0;
165
166 save_com.len = save_com.column = 0;
167
168 di_stack[parser_state_tos->dec_nest] = 0;
169
170 l_com = combuf + INITIAL_BUFFER_SIZE - 5;
171 l_lab = labbuf + INITIAL_BUFFER_SIZE - 5;
172 l_code = codebuf + INITIAL_BUFFER_SIZE - 5;
173 combuf[0] = codebuf[0] = labbuf[0] = ' ';
174 combuf[1] = codebuf[1] = labbuf[1] = '\0';
175
176 else_or_endif = false;
177 s_lab = e_lab = labbuf + 1;
178 s_code = e_code = codebuf + 1;
179 s_com = e_com = combuf + 1;
180
181 line_no = 1;
182 had_eof = false;
183 break_comma = false;
184 bp_save = 0;
185 be_save = 0;
186
187 if (settings.tabsize <= 0)
188 {
189 settings.tabsize = 1;
190 }
191
192 prefix_blankline_requested = 0;
193 }
194
195 /**
196 * like ++parser_state_tos->tos but checks for stack overflow and extends
197 * stack if necessary.
198 */
199
inc_pstack(void)200 extern int inc_pstack(void)
201 {
202 if (++parser_state_tos->tos >= parser_state_tos->p_stack_size)
203 {
204 parser_state_tos->p_stack_size *= 2;
205 parser_state_tos->p_stack =
206 xrealloc(parser_state_tos->p_stack,
207 parser_state_tos->p_stack_size * sizeof(codes_ty));
208 parser_state_tos->il =
209 xrealloc(parser_state_tos->il,
210 parser_state_tos->p_stack_size * sizeof(int));
211 parser_state_tos->cstk =
212 xrealloc(parser_state_tos->cstk,
213 parser_state_tos->p_stack_size * sizeof(int));
214 }
215
216 parser_state_tos->cstk[parser_state_tos->tos] = parser_state_tos->cstk[parser_state_tos->tos - 1];
217 return parser_state_tos->tos;
218 }
219
220 #ifdef DEBUG
221 /**
222 *
223 */
224
225 static char **debug_symbol_strings;
226
227 /**
228 *
229 */
230
debug_init(void)231 extern void debug_init(void)
232 {
233 int size = ((int) number_of_codes) * sizeof (char *);
234
235 debug_symbol_strings = xmalloc (size);
236
237 debug_symbol_strings[code_eof] = "code_eof";
238 debug_symbol_strings[newline] = "newline";
239 debug_symbol_strings[lparen] = "lparen";
240 debug_symbol_strings[rparen] = "rparen";
241 debug_symbol_strings[start_token] = "start_token";
242 debug_symbol_strings[unary_op] = "unary_op";
243 debug_symbol_strings[binary_op] = "binary_op";
244 debug_symbol_strings[postop] = "postop";
245 debug_symbol_strings[question] = "question";
246 debug_symbol_strings[casestmt] = "casestmt";
247 debug_symbol_strings[colon] = "colon";
248 debug_symbol_strings[doublecolon] = "doublecolon";
249 debug_symbol_strings[semicolon] = "semicolon";
250 debug_symbol_strings[lbrace] = "lbrace";
251 debug_symbol_strings[rbrace] = "rbrace";
252 debug_symbol_strings[ident] = "ident";
253 debug_symbol_strings[overloaded] = "overloaded";
254 debug_symbol_strings[cpp_operator] = "cpp_operator";
255 debug_symbol_strings[comma] = "comma";
256 debug_symbol_strings[comment] = "comment";
257 debug_symbol_strings[cplus_comment] = "cplus_comment";
258 debug_symbol_strings[swstmt] = "swstmt";
259 debug_symbol_strings[preesc] = "preesc";
260 debug_symbol_strings[form_feed] = "form_feed";
261 debug_symbol_strings[decl] = "decl";
262 debug_symbol_strings[sp_paren] = "sp_paren";
263 debug_symbol_strings[sp_nparen] = "sp_nparen";
264 debug_symbol_strings[sp_else] = "sp_else";
265 debug_symbol_strings[ifstmt] = "ifstmt";
266 debug_symbol_strings[elseifstmt] = "elseifstmt";
267 debug_symbol_strings[whilestmt] = "whilestmt";
268 debug_symbol_strings[forstmt] = "forstmt";
269 debug_symbol_strings[stmt] = "stmt";
270 debug_symbol_strings[stmtl] = "stmtl";
271 debug_symbol_strings[elselit] = "elselit";
272 debug_symbol_strings[dolit] = "dolit";
273 debug_symbol_strings[dohead] = "dohead";
274 debug_symbol_strings[dostmt] = "dostmt";
275 debug_symbol_strings[ifhead] = "ifhead";
276 debug_symbol_strings[elsehead] = "elsehead";
277 debug_symbol_strings[struct_delim] = "struct_delim";
278 debug_symbol_strings[attribute] = "attribute";
279 }
280
281 #endif
282
283 /**
284 *
285 */
286
parse(codes_ty tk)287 extern exit_values_ty parse (
288 codes_ty tk) /*!< the code for the construct scanned */
289 {
290 int i;
291
292 #ifdef DEBUG
293 if (debug)
294 {
295 if (tk >= code_eof && tk < number_of_codes)
296 {
297 printf ("Parse: %s\n", debug_symbol_strings[tk]);
298 }
299 else
300 {
301 printf ("Parse: Unknown code: %d for %s\n", (int) tk, token ? token : "NULL");
302 }
303 }
304 #endif
305
306 while ((parser_state_tos->p_stack[parser_state_tos->tos] == ifhead) &&
307 (tk != elselit))
308 {
309 /* true if we have an if without an else */
310
311 /* apply the if(..) stmt ::= stmt reduction */
312
313 parser_state_tos->p_stack[parser_state_tos->tos] = stmt;
314 reduce (); /* see if this allows any reduction */
315 }
316
317
318 switch (tk)
319 {
320 /* go on and figure out what to do with the input */
321
322 case decl:
323 /* scanned a declaration word */
324 parser_state_tos->search_brace = settings.braces_on_struct_decl_line;
325
326 /* indicate that following brace should be on same line */
327
328 if ((parser_state_tos->p_stack[parser_state_tos->tos] != decl) &&
329 (parser_state_tos->block_init == 0))
330 {
331 /* only put one declaration onto stack */
332
333 break_comma = true; /* while in declaration, newline should be
334 * forced after comma */
335 inc_pstack ();
336 parser_state_tos->p_stack[parser_state_tos->tos] = decl;
337 parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->i_l_follow;
338
339 if (settings.ljust_decl)
340 { /* only do if we want left justified
341 * declarations */
342 parser_state_tos->ind_level = 0;
343 for (i = parser_state_tos->tos - 1; i > 0; --i)
344 {
345 if (parser_state_tos->p_stack[i] == decl)
346 {
347 /* indentation is number of declaration levels deep we are
348 * times spaces per level */
349 parser_state_tos->ind_level += settings.ind_size;
350 }
351 }
352
353 parser_state_tos->i_l_follow = parser_state_tos->ind_level;
354 }
355 }
356 break;
357
358 case ifstmt: /* scanned if (...) */
359 if (parser_state_tos->p_stack[parser_state_tos->tos] == elsehead)
360 {
361 parser_state_tos->i_l_follow = parser_state_tos->il[parser_state_tos->tos];
362 }
363 /* falls through */
364
365 case dolit: /* 'do' */
366 case forstmt: /* for (...) */
367 case casestmt: /* case n: */
368 inc_pstack ();
369 parser_state_tos->p_stack[parser_state_tos->tos] = tk;
370 parser_state_tos->ind_level = parser_state_tos->i_l_follow;
371 parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->ind_level;
372
373 if (tk != casestmt)
374 {
375 parser_state_tos->i_l_follow += settings.ind_size; /* subsequent statements
376 * should be indented */
377 }
378
379 parser_state_tos->search_brace = settings.btype_2;
380 break;
381
382 case lbrace: /* scanned { */
383 break_comma = false; /* don't break comma in an initial list */
384 if (parser_state_tos->p_stack[parser_state_tos->tos] == stmt
385 || parser_state_tos->p_stack[parser_state_tos->tos] == stmtl)
386 {
387 /* it is a random, isolated stmt group or a declaration */
388 parser_state_tos->i_l_follow += settings.ind_size;
389 }
390 else if (parser_state_tos->p_stack[parser_state_tos->tos] == decl)
391 {
392 parser_state_tos->i_l_follow += settings.ind_size;
393
394 if ( ( (parser_state_tos->last_rw == rw_struct_like) ||
395 (parser_state_tos->last_rw == rw_enum)) &&
396 ( (parser_state_tos->block_init != 1) ||
397 (parser_state_tos->block_init_level == 0)) &&
398 (parser_state_tos->last_token != rparen) &&
399 (!settings.braces_on_struct_decl_line))
400 {
401 parser_state_tos->ind_level += settings.struct_brace_indent;
402 parser_state_tos->i_l_follow += settings.struct_brace_indent;
403 }
404 }
405 else if (parser_state_tos->p_stack[parser_state_tos->tos] == casestmt)
406 {
407 parser_state_tos->ind_level += settings.case_brace_indent - settings.ind_size;
408 parser_state_tos->i_l_follow += settings.case_brace_indent;
409 }
410 else
411 {
412 /* It is a group as part of a while, for, etc. */
413
414 /* Only do this if there is nothing on the line */
415 if (s_code == e_code)
416 {
417 parser_state_tos->ind_level -= settings.ind_size;
418 }
419
420 /* For -bl formatting, indent by settings.brace_indent additional spaces
421 * e.g. if (foo == bar) { <--> settings.brace_indent spaces (in this
422 * example, 4) */
423
424 if (!settings.btype_2)
425 {
426 parser_state_tos->ind_level += settings.brace_indent;
427 parser_state_tos->i_l_follow += settings.brace_indent;
428 }
429
430 if (parser_state_tos->p_stack[parser_state_tos->tos] == swstmt)
431 {
432 parser_state_tos->i_l_follow += settings.case_indent;
433 }
434 }
435
436 inc_pstack ();
437 parser_state_tos->p_stack[parser_state_tos->tos] = lbrace;
438 parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->ind_level;
439
440 inc_pstack ();
441 parser_state_tos->p_stack[parser_state_tos->tos] = stmt;
442
443 /* allow null stmt between braces */
444
445 parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->i_l_follow;
446 break;
447
448 case whilestmt: /* scanned while (...) */
449 if (parser_state_tos->p_stack[parser_state_tos->tos] == dohead)
450 {
451 /* it is matched with do stmt */
452 parser_state_tos->i_l_follow = parser_state_tos->il[parser_state_tos->tos];
453 parser_state_tos->ind_level = parser_state_tos->il[parser_state_tos->tos];
454 inc_pstack ();
455 parser_state_tos->p_stack[parser_state_tos->tos] = whilestmt;
456
457 parser_state_tos->ind_level = parser_state_tos->i_l_follow;
458 parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->i_l_follow;
459 }
460 else
461 { /* it is a while loop */
462 inc_pstack ();
463 parser_state_tos->p_stack[parser_state_tos->tos] = whilestmt;
464 parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->i_l_follow;
465 parser_state_tos->i_l_follow += settings.ind_size;
466 parser_state_tos->search_brace = settings.btype_2;
467 }
468
469 break;
470
471 case elselit: /* scanned an else */
472
473 if (parser_state_tos->p_stack[parser_state_tos->tos] != ifhead)
474 {
475 ERROR(_("Unmatched 'else'"), NULL, NULL);
476 }
477 else
478 {
479 /* indentation for else should be same as for if */
480 parser_state_tos->ind_level = parser_state_tos->il[parser_state_tos->tos];
481
482 /* everything following should be in 1 level */
483 parser_state_tos->i_l_follow = (parser_state_tos->ind_level + settings.ind_size);
484
485 parser_state_tos->p_stack[parser_state_tos->tos] = elsehead;
486 /* remember if with else */
487 parser_state_tos->search_brace = true;
488 }
489 break;
490
491 case rbrace: /* scanned a } */
492 /* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */
493 if ((parser_state_tos->tos > 0) && (parser_state_tos->p_stack[parser_state_tos->tos - 1] == lbrace))
494 {
495 parser_state_tos->i_l_follow = parser_state_tos->il[--parser_state_tos->tos];
496 parser_state_tos->ind_level = parser_state_tos->i_l_follow;
497 parser_state_tos->p_stack[parser_state_tos->tos] = stmt;
498 }
499 else
500 {
501 ERROR(_("Stmt nesting error."), NULL, NULL);
502 }
503 break;
504
505 case swstmt: /* had switch (...) */
506 inc_pstack ();
507 parser_state_tos->p_stack[parser_state_tos->tos] = swstmt;
508 parser_state_tos->cstk[parser_state_tos->tos] = settings.case_indent + parser_state_tos->i_l_follow;
509 if (!settings.btype_2)
510 {
511 parser_state_tos->cstk[parser_state_tos->tos] += settings.brace_indent;
512 }
513
514 /* save current case indent level */
515 parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->i_l_follow;
516
517 /* case labels should be one level down from switch, plus
518 * `settings.case_indent' if any. Then, statements should be the `settings.ind_size'
519 * further. */
520
521 parser_state_tos->i_l_follow += settings.ind_size;
522 parser_state_tos->search_brace = settings.btype_2;
523 break;
524
525 case semicolon: /* this indicates a simple stmt */
526 break_comma = false; /* turn off flag to break after commas in a
527 * declaration */
528
529 if (parser_state_tos->p_stack[parser_state_tos->tos] == dostmt)
530 {
531 parser_state_tos->p_stack[parser_state_tos->tos] = stmt;
532 }
533 else
534 {
535 inc_pstack ();
536 parser_state_tos->p_stack[parser_state_tos->tos] = stmt;
537 parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->ind_level;
538 }
539 break;
540
541 /* This is a fatal error which cases the program to exit. */
542 default:
543 fatal (_("Unknown code to parser"), 0);
544 }
545
546 reduce (); /* see if any reduction can be done */
547
548 #ifdef DEBUG
549 if (debug)
550 {
551 printf ("\n");
552
553 printf ("ParseStack [%d]:\n", (int) parser_state_tos->p_stack_size);
554
555 for (i = 1; i <= parser_state_tos->tos; ++i)
556 {
557 printf (" stack[%d] => stack: %d [%-10s] ind_level: %d\n",
558 (int)i, (int)parser_state_tos->p_stack[i],
559 debug_symbol_strings[parser_state_tos->p_stack[i]],
560 (int)parser_state_tos->il[i]);
561 }
562
563 printf ("\n");
564 }
565 #endif
566
567 return total_success;
568 }
569
570 /**
571 * NAME: reduce
572 *
573 * FUNCTION: Implements the reduce part of the parsing algorithm
574 *
575 * ALGORITHM: The following reductions are done. Reductions are repeated until
576 * no more are possible.
577 *
578 * Old TOS New TOS [stmt] [stmt] [stmtl] [stmtl] [stmt]
579 * [stmtl] do [stmt] dohead [dohead] [whilestmt]
580 * [dostmt] if [stmt] "ifstmt" switch [stmt] [stmt]
581 * decl [stmt] [stmt] "ifelse" [stmt] [stmt] for
582 * [stmt] [stmt] while [stmt] [stmt]
583 * "dostmt" while [stmt]
584 *
585 * On each reduction, parser_state_tos->i_l_follow (the indentation for the
586 * following line) is set to the indentation level associated with the old
587 * TOS.
588 *
589 * PARAMETERS: None
590 *
591 * RETURNS: Nothing
592 *
593 * GLOBALS: parser_state_tos->cstk parser_state_tos->i_l_follow =
594 * parser_state_tos->il parser_state_tos->p_stack = parser_state_tos->tos =
595 *
596 * CALLS: None
597 *
598 * CALLED BY: parse
599 *
600 * HISTORY: initial coding November 1976 D A Willcox of CAC
601 *
602 */
603
reduce(void)604 extern void reduce(void)
605 {
606 int i;
607
608 for (;;)
609 {
610 /* keep looping until there is nothing left to reduce */
611
612 switch (parser_state_tos->p_stack[parser_state_tos->tos])
613 {
614 case stmt:
615 if (parser_state_tos->tos == 0) return;
616 switch (parser_state_tos->p_stack[parser_state_tos->tos - 1])
617 {
618 case stmt:
619 case stmtl:
620 /* stmtl stmt or stmt stmt */
621 parser_state_tos->p_stack[--parser_state_tos->tos] = stmtl;
622 break;
623
624 case dolit: /* [do] [stmt] */
625 parser_state_tos->p_stack[--parser_state_tos->tos] = dohead;
626 parser_state_tos->i_l_follow = parser_state_tos->il[parser_state_tos->tos];
627 break;
628
629 case ifstmt:
630 /* [if] [stmt] */
631 parser_state_tos->p_stack[--parser_state_tos->tos] = ifhead;
632 for (i = parser_state_tos->tos - 1;
633 ( (parser_state_tos->p_stack[i] != stmt) &&
634 (parser_state_tos->p_stack[i] != stmtl) &&
635 (parser_state_tos->p_stack[i] != lbrace));
636 --i)
637 {
638 }
639
640 parser_state_tos->i_l_follow = parser_state_tos->il[i];
641
642 /* for the time being, we will assume that there is no else on
643 * this if, and set the indentation level accordingly. If an
644 * else is scanned, it will be fixed up later */
645
646 break;
647
648 case swstmt:
649 /* [switch] [stmt] */
650 case decl: /* finish of a declaration */
651 case elsehead:
652 /* [[if] [stmt] else] [stmt] */
653 case forstmt:
654 /* [for] [stmt] */
655 case casestmt:
656 /* [case n:] [stmt] */
657 case whilestmt:
658 /* [while] [stmt] */
659 parser_state_tos->p_stack[--parser_state_tos->tos] = stmt;
660 parser_state_tos->i_l_follow = parser_state_tos->il[parser_state_tos->tos];
661 break;
662
663 default: /* [anything else] [stmt] */
664 return;
665
666 } /* end of section for [stmt] on top of stack */
667 break;
668
669 case whilestmt: /* while (...) on top */
670 if (parser_state_tos->p_stack[parser_state_tos->tos - 1] == dohead)
671 {
672 /* it is termination of a do while */
673 parser_state_tos->p_stack[--parser_state_tos->tos] = dostmt;
674 break;
675 }
676 else
677 return;
678
679 default: /* anything else on top */
680 return;
681
682 }
683 }
684 }
685
686 /**
687 * This kludge is called from main. It is just like parse(semicolon) except
688 * that it does not clear break_comma. Leaving break_comma alone is
689 * necessary to make sure that "int foo(), bar()" gets formatted correctly
690 * under -bc. */
691
parse_lparen_in_decl(void)692 extern void parse_lparen_in_decl(void)
693 {
694 inc_pstack ();
695 parser_state_tos->p_stack[parser_state_tos->tos] = stmt;
696 parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->ind_level;
697
698 reduce ();
699 }
700