121971Sdist /* 2*35500Sbostic * Copyright (c) 1985 Sun Microsystems, Inc. 3*35500Sbostic * Copyright (c) 1980 The Regents of the University of California. 433767Sbostic * Copyright (c) 1976 Board of Trustees of the University of Illinois. 533767Sbostic * All rights reserved. 633767Sbostic * 733767Sbostic * Redistribution and use in source and binary forms are permitted 834885Sbostic * provided that the above copyright notice and this paragraph are 934885Sbostic * duplicated in all such forms and that any documentation, 1034885Sbostic * advertising materials, and other materials related to such 1134885Sbostic * distribution and use acknowledge that the software was developed 12*35500Sbostic * by the University of California, Berkeley, the University of Illinois, 13*35500Sbostic * Urbana, and Sun Microsystems, Inc. The name of either University 14*35500Sbostic * or Sun Microsystems may not be used to endorse or promote products 15*35500Sbostic * derived from this software without specific prior written permission. 1634885Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1734885Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1834885Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1921971Sdist */ 208805Smckusick 2121971Sdist #ifndef lint 22*35500Sbostic static char sccsid[] = "@(#)parse.c 5.7 (Berkeley) 09/15/88"; 2333767Sbostic #endif /* not lint */ 2421971Sdist 25*35500Sbostic #include "./indent_globs.h"; 26*35500Sbostic #include "./indent_codes.h"; 278805Smckusick 288805Smckusick 298805Smckusick 308805Smckusick 3124456Smckusick parse(tk) 3224456Smckusick int tk; /* the code for the construct scanned */ 338805Smckusick { 3424456Smckusick int i; 358805Smckusick 368805Smckusick #ifdef debug 3724456Smckusick printf("%2d - %s\n", tk, token); 388805Smckusick #endif 39*35500Sbostic 4024456Smckusick while (ps.p_stack[ps.tos] == ifhead && tk != elselit) { 4124456Smckusick /* true if we have an if without an else */ 4224456Smckusick ps.p_stack[ps.tos] = stmt; /* apply the if(..) stmt ::= stmt 43*35500Sbostic * reduction */ 4424456Smckusick reduce(); /* see if this allows any reduction */ 458805Smckusick } 468805Smckusick 478805Smckusick 48*35500Sbostic switch (tk) { /* go on and figure out what to do with the 49*35500Sbostic * input */ 508805Smckusick 51*35500Sbostic case decl: /* scanned a declaration word */ 52*35500Sbostic ps.search_brace = btype_2; 53*35500Sbostic /* indicate that following brace should be on same line */ 54*35500Sbostic if (ps.p_stack[ps.tos] != decl) { /* only put one declaration 55*35500Sbostic * onto stack */ 56*35500Sbostic break_comma = true; /* while in declaration, newline should be 57*35500Sbostic * forced after comma */ 58*35500Sbostic ps.p_stack[++ps.tos] = decl; 59*35500Sbostic ps.il[ps.tos] = ps.i_l_follow; 608805Smckusick 61*35500Sbostic if (ps.ljust_decl) {/* only do if we want left justified 62*35500Sbostic * declarations */ 63*35500Sbostic ps.ind_level = 0; 64*35500Sbostic for (i = ps.tos - 1; i > 0; --i) 65*35500Sbostic if (ps.p_stack[i] == decl) 66*35500Sbostic ++ps.ind_level; /* indentation is number of 67*35500Sbostic * declaration levels deep we are */ 68*35500Sbostic ps.i_l_follow = ps.ind_level; 698805Smckusick } 70*35500Sbostic } 71*35500Sbostic break; 728805Smckusick 73*35500Sbostic case ifstmt: /* scanned if (...) */ 74*35500Sbostic if (ps.p_stack[ps.tos] == elsehead && ps.else_if) /* "else if ..." */ 75*35500Sbostic ps.i_l_follow = ps.il[ps.tos]; 76*35500Sbostic case dolit: /* 'do' */ 77*35500Sbostic case forstmt: /* for (...) */ 78*35500Sbostic ps.p_stack[++ps.tos] = tk; 79*35500Sbostic ps.il[ps.tos] = ps.ind_level = ps.i_l_follow; 80*35500Sbostic ++ps.i_l_follow; /* subsequent statements should be indented 1 */ 81*35500Sbostic ps.search_brace = btype_2; 82*35500Sbostic break; 838805Smckusick 84*35500Sbostic case lbrace: /* scanned { */ 85*35500Sbostic break_comma = false; /* don't break comma in an initial list */ 86*35500Sbostic if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl 87*35500Sbostic || ps.p_stack[ps.tos] == stmtl) 88*35500Sbostic ++ps.i_l_follow; /* it is a random, isolated stmt group or a 89*35500Sbostic * declaration */ 90*35500Sbostic else { 91*35500Sbostic if (s_code == e_code) { 92*35500Sbostic /* 93*35500Sbostic * only do this if there is nothing on the line 94*35500Sbostic */ 95*35500Sbostic --ps.ind_level; 96*35500Sbostic /* 97*35500Sbostic * it is a group as part of a while, for, etc. 98*35500Sbostic */ 99*35500Sbostic if (ps.p_stack[ps.tos] == swstmt && ps.case_indent >= 1) 10024456Smckusick --ps.ind_level; 101*35500Sbostic /* 102*35500Sbostic * for a switch, brace should be two levels out from the code 103*35500Sbostic */ 1048805Smckusick } 105*35500Sbostic } 1068805Smckusick 107*35500Sbostic ps.p_stack[++ps.tos] = lbrace; 108*35500Sbostic ps.il[ps.tos] = ps.ind_level; 109*35500Sbostic ps.p_stack[++ps.tos] = stmt; 110*35500Sbostic /* allow null stmt between braces */ 111*35500Sbostic ps.il[ps.tos] = ps.i_l_follow; 112*35500Sbostic break; 113*35500Sbostic 114*35500Sbostic case whilestmt: /* scanned while (...) */ 115*35500Sbostic if (ps.p_stack[ps.tos] == dohead) { 116*35500Sbostic /* it is matched with do stmt */ 117*35500Sbostic ps.ind_level = ps.i_l_follow = ps.il[ps.tos]; 118*35500Sbostic ps.p_stack[++ps.tos] = whilestmt; 119*35500Sbostic ps.il[ps.tos] = ps.ind_level = ps.i_l_follow; 120*35500Sbostic } 121*35500Sbostic else { /* it is a while loop */ 122*35500Sbostic ps.p_stack[++ps.tos] = whilestmt; 12324456Smckusick ps.il[ps.tos] = ps.i_l_follow; 124*35500Sbostic ++ps.i_l_follow; 125*35500Sbostic ps.search_brace = btype_2; 126*35500Sbostic } 1278805Smckusick 128*35500Sbostic break; 1298805Smckusick 130*35500Sbostic case elselit: /* scanned an else */ 1318805Smckusick 132*35500Sbostic if (ps.p_stack[ps.tos] != ifhead) 133*35500Sbostic diag(1, "Unmatched 'else'"); 134*35500Sbostic else { 135*35500Sbostic ps.ind_level = ps.il[ps.tos]; /* indentation for else should 136*35500Sbostic * be same as for if */ 137*35500Sbostic ps.i_l_follow = ps.ind_level + 1; /* everything following should 138*35500Sbostic * be in 1 level */ 139*35500Sbostic ps.p_stack[ps.tos] = elsehead; 140*35500Sbostic /* remember if with else */ 141*35500Sbostic ps.search_brace = btype_2 | ps.else_if; 142*35500Sbostic } 143*35500Sbostic break; 1448805Smckusick 145*35500Sbostic case rbrace: /* scanned a } */ 146*35500Sbostic /* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */ 147*35500Sbostic if (ps.p_stack[ps.tos - 1] == lbrace) { 148*35500Sbostic ps.ind_level = ps.i_l_follow = ps.il[--ps.tos]; 149*35500Sbostic ps.p_stack[ps.tos] = stmt; 150*35500Sbostic } 151*35500Sbostic else 152*35500Sbostic diag(1, "Stmt nesting error."); 153*35500Sbostic break; 1548805Smckusick 155*35500Sbostic case swstmt: /* had switch (...) */ 156*35500Sbostic ps.p_stack[++ps.tos] = swstmt; 157*35500Sbostic ps.cstk[ps.tos] = case_ind; 158*35500Sbostic /* save current case indent level */ 159*35500Sbostic ps.il[ps.tos] = ps.i_l_follow; 160*35500Sbostic case_ind = ps.i_l_follow + ps.case_indent; /* cases should be one 16124456Smckusick * level down from 16224456Smckusick * switch */ 163*35500Sbostic ps.i_l_follow + = ps.case_indent + 1; /* statements should be two 164*35500Sbostic * levels in */ 165*35500Sbostic ps.search_brace = btype_2; 166*35500Sbostic break; 1678805Smckusick 168*35500Sbostic case semicolon: /* this indicates a simple stmt */ 169*35500Sbostic break_comma = false; /* turn off flag to break after commas in a 170*35500Sbostic * declaration */ 171*35500Sbostic ps.p_stack[++ps.tos] = stmt; 172*35500Sbostic ps.il[ps.tos] = ps.ind_level; 173*35500Sbostic break; 1748805Smckusick 175*35500Sbostic default: /* this is an error */ 176*35500Sbostic diag(1, "Unknown code to parser"); 177*35500Sbostic return; 1788805Smckusick 1798805Smckusick 18024456Smckusick } /* end of switch */ 1818805Smckusick 18224456Smckusick reduce(); /* see if any reduction can be done */ 183*35500Sbostic 1848805Smckusick #ifdef debug 18524456Smckusick for (i = 1; i <= ps.tos; ++i) 18624456Smckusick printf("(%d %d)", ps.p_stack[i], ps.il[i]); 18724456Smckusick printf("\n"); 1888805Smckusick #endif 189*35500Sbostic 1908805Smckusick return; 1918805Smckusick } 192*35500Sbostic 193*35500Sbostic /* 194*35500Sbostic * Copyright (C) 1976 by the Board of Trustees of the University of Illinois 195*35500Sbostic * 196*35500Sbostic * All rights reserved 197*35500Sbostic * 198*35500Sbostic * 199*35500Sbostic * NAME: reduce 200*35500Sbostic * 201*35500Sbostic * FUNCTION: Implements the reduce part of the parsing algorithm 202*35500Sbostic * 203*35500Sbostic * ALGORITHM: The following reductions are done. Reductions are repeated until 204*35500Sbostic * no more are possible. 205*35500Sbostic * 20624456Smckusick * Old TOS New TOS <stmt> <stmt> <stmtl> <stmtl> <stmt> <stmtl> do 207*35500Sbostic * <stmt> "dostmt" if <stmt> "ifstmt" switch <stmt> <stmt> decl 208*35500Sbostic * <stmt> <stmt> "ifelse" <stmt> <stmt> for <stmt> <stmt> while 209*35500Sbostic * <stmt> <stmt> "dostmt" while <stmt> 210*35500Sbostic * 21124456Smckusick * On each reduction, ps.i_l_follow (the indentation for the following line) is 212*35500Sbostic * set to the indentation level associated with the old TOS. 213*35500Sbostic * 214*35500Sbostic * PARAMETERS: None 215*35500Sbostic * 216*35500Sbostic * RETURNS: Nothing 217*35500Sbostic * 218*35500Sbostic * GLOBALS: ps.cstk ps.i_l_follow = ps.il ps.p_stack = ps.tos = 219*35500Sbostic * 220*35500Sbostic * CALLS: None 221*35500Sbostic * 22224456Smckusick * CALLED BY: parse 223*35500Sbostic * 224*35500Sbostic * HISTORY: initial coding November 1976 D A Willcox of CAC 225*35500Sbostic * 22624456Smckusick */ 2278805Smckusick /*----------------------------------------------*\ 228*35500Sbostic | REDUCTION PHASE | 2298805Smckusick \*----------------------------------------------*/ 230*35500Sbostic reduce() 231*35500Sbostic { 2328805Smckusick 23324456Smckusick register int i; 2348805Smckusick 235*35500Sbostic for (;;) { /* keep looping until there is nothing left to 236*35500Sbostic * reduce */ 2378805Smckusick 23824456Smckusick switch (ps.p_stack[ps.tos]) { 2398805Smckusick 240*35500Sbostic case stmt: 241*35500Sbostic switch (ps.p_stack[ps.tos - 1]) { 2428805Smckusick 243*35500Sbostic case stmt: 244*35500Sbostic case stmtl: 245*35500Sbostic /* stmtl stmt or stmt stmt */ 246*35500Sbostic ps.p_stack[--ps.tos] = stmtl; 247*35500Sbostic break; 2488805Smckusick 249*35500Sbostic case dolit: /* <do> <stmt> */ 250*35500Sbostic ps.p_stack[--ps.tos] = dohead; 251*35500Sbostic ps.i_l_follow = ps.il[ps.tos]; 252*35500Sbostic break; 2538805Smckusick 254*35500Sbostic case ifstmt: 255*35500Sbostic /* <if> <stmt> */ 256*35500Sbostic ps.p_stack[--ps.tos] = ifhead; 257*35500Sbostic for (i = ps.tos - 1; 258*35500Sbostic ( 259*35500Sbostic ps.p_stack[i] != stmt 260*35500Sbostic && 261*35500Sbostic ps.p_stack[i] != stmtl 262*35500Sbostic && 263*35500Sbostic ps.p_stack[i] != lbrace 264*35500Sbostic ); 265*35500Sbostic --i); 266*35500Sbostic ps.i_l_follow = ps.il[i]; 267*35500Sbostic /* 268*35500Sbostic * for the time being, we will assume that there is no else on 269*35500Sbostic * this if, and set the indentation level accordingly. If an 270*35500Sbostic * else is scanned, it will be fixed up later 271*35500Sbostic */ 272*35500Sbostic break; 2738805Smckusick 274*35500Sbostic case swstmt: 275*35500Sbostic /* <switch> <stmt> */ 276*35500Sbostic case_ind = ps.cstk[ps.tos - 1]; 2778805Smckusick 278*35500Sbostic case decl: /* finish of a declaration */ 279*35500Sbostic case elsehead: 280*35500Sbostic /* <<if> <stmt> else> <stmt> */ 281*35500Sbostic case forstmt: 282*35500Sbostic /* <for> <stmt> */ 283*35500Sbostic case whilestmt: 284*35500Sbostic /* <while> <stmt> */ 285*35500Sbostic ps.p_stack[--ps.tos] = stmt; 286*35500Sbostic ps.i_l_follow = ps.il[ps.tos]; 287*35500Sbostic break; 2888805Smckusick 289*35500Sbostic default: /* <anything else> <stmt> */ 290*35500Sbostic return; 2918805Smckusick 292*35500Sbostic } /* end of section for <stmt> on top of stack */ 293*35500Sbostic break; 294*35500Sbostic 295*35500Sbostic case whilestmt: /* while (...) on top */ 296*35500Sbostic if (ps.p_stack[ps.tos - 1] == dohead) { 297*35500Sbostic /* it is termination of a do while */ 298*35500Sbostic ps.p_stack[--ps.tos] = stmt; 2998805Smckusick break; 300*35500Sbostic } 301*35500Sbostic else 302*35500Sbostic return; 3038805Smckusick 304*35500Sbostic default: /* anything else on top */ 305*35500Sbostic return; 3068805Smckusick 30724456Smckusick } 30824456Smckusick } 3098805Smckusick } 310