121971Sdist /* 235500Sbostic * Copyright (c) 1985 Sun Microsystems, Inc. 335500Sbostic * 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 * 7*42688Sbostic * %sccs.include.redist.c% 821971Sdist */ 98805Smckusick 1021971Sdist #ifndef lint 11*42688Sbostic static char sccsid[] = "@(#)parse.c 5.11 (Berkeley) 06/01/90"; 1233767Sbostic #endif /* not lint */ 1321971Sdist 1436969Sbostic #include "indent_globs.h" 1536969Sbostic #include "indent_codes.h" 168805Smckusick 1724456Smckusick parse(tk) 1824456Smckusick int tk; /* the code for the construct scanned */ 198805Smckusick { 2024456Smckusick int i; 218805Smckusick 228805Smckusick #ifdef debug 2324456Smckusick printf("%2d - %s\n", tk, token); 248805Smckusick #endif 2535500Sbostic 2624456Smckusick while (ps.p_stack[ps.tos] == ifhead && tk != elselit) { 2724456Smckusick /* true if we have an if without an else */ 2824456Smckusick ps.p_stack[ps.tos] = stmt; /* apply the if(..) stmt ::= stmt 2935500Sbostic * reduction */ 3024456Smckusick reduce(); /* see if this allows any reduction */ 318805Smckusick } 328805Smckusick 338805Smckusick 3435500Sbostic switch (tk) { /* go on and figure out what to do with the 3535500Sbostic * input */ 368805Smckusick 3735500Sbostic case decl: /* scanned a declaration word */ 3835500Sbostic ps.search_brace = btype_2; 3935500Sbostic /* indicate that following brace should be on same line */ 4035500Sbostic if (ps.p_stack[ps.tos] != decl) { /* only put one declaration 4135500Sbostic * onto stack */ 4235500Sbostic break_comma = true; /* while in declaration, newline should be 4335500Sbostic * forced after comma */ 4435500Sbostic ps.p_stack[++ps.tos] = decl; 4535500Sbostic ps.il[ps.tos] = ps.i_l_follow; 468805Smckusick 4735500Sbostic if (ps.ljust_decl) {/* only do if we want left justified 4835500Sbostic * declarations */ 4935500Sbostic ps.ind_level = 0; 5035500Sbostic for (i = ps.tos - 1; i > 0; --i) 5135500Sbostic if (ps.p_stack[i] == decl) 5235500Sbostic ++ps.ind_level; /* indentation is number of 5335500Sbostic * declaration levels deep we are */ 5435500Sbostic ps.i_l_follow = ps.ind_level; 558805Smckusick } 5635500Sbostic } 5735500Sbostic break; 588805Smckusick 5935500Sbostic case ifstmt: /* scanned if (...) */ 6035500Sbostic if (ps.p_stack[ps.tos] == elsehead && ps.else_if) /* "else if ..." */ 6135500Sbostic ps.i_l_follow = ps.il[ps.tos]; 6235500Sbostic case dolit: /* 'do' */ 6335500Sbostic case forstmt: /* for (...) */ 6435500Sbostic ps.p_stack[++ps.tos] = tk; 6535500Sbostic ps.il[ps.tos] = ps.ind_level = ps.i_l_follow; 6635500Sbostic ++ps.i_l_follow; /* subsequent statements should be indented 1 */ 6735500Sbostic ps.search_brace = btype_2; 6835500Sbostic break; 698805Smckusick 7035500Sbostic case lbrace: /* scanned { */ 7135500Sbostic break_comma = false; /* don't break comma in an initial list */ 7235500Sbostic if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl 7335500Sbostic || ps.p_stack[ps.tos] == stmtl) 7435500Sbostic ++ps.i_l_follow; /* it is a random, isolated stmt group or a 7535500Sbostic * declaration */ 7635500Sbostic else { 7735500Sbostic if (s_code == e_code) { 7835500Sbostic /* 7935500Sbostic * only do this if there is nothing on the line 8035500Sbostic */ 8135500Sbostic --ps.ind_level; 8235500Sbostic /* 8335500Sbostic * it is a group as part of a while, for, etc. 8435500Sbostic */ 8535500Sbostic if (ps.p_stack[ps.tos] == swstmt && ps.case_indent >= 1) 8624456Smckusick --ps.ind_level; 8735500Sbostic /* 8835500Sbostic * for a switch, brace should be two levels out from the code 8935500Sbostic */ 908805Smckusick } 9135500Sbostic } 928805Smckusick 9335500Sbostic ps.p_stack[++ps.tos] = lbrace; 9435500Sbostic ps.il[ps.tos] = ps.ind_level; 9535500Sbostic ps.p_stack[++ps.tos] = stmt; 9635500Sbostic /* allow null stmt between braces */ 9735500Sbostic ps.il[ps.tos] = ps.i_l_follow; 9835500Sbostic break; 9935500Sbostic 10035500Sbostic case whilestmt: /* scanned while (...) */ 10135500Sbostic if (ps.p_stack[ps.tos] == dohead) { 10235500Sbostic /* it is matched with do stmt */ 10335500Sbostic ps.ind_level = ps.i_l_follow = ps.il[ps.tos]; 10435500Sbostic ps.p_stack[++ps.tos] = whilestmt; 10535500Sbostic ps.il[ps.tos] = ps.ind_level = ps.i_l_follow; 10635500Sbostic } 10735500Sbostic else { /* it is a while loop */ 10835500Sbostic ps.p_stack[++ps.tos] = whilestmt; 10924456Smckusick ps.il[ps.tos] = ps.i_l_follow; 11035500Sbostic ++ps.i_l_follow; 11135500Sbostic ps.search_brace = btype_2; 11235500Sbostic } 1138805Smckusick 11435500Sbostic break; 1158805Smckusick 11635500Sbostic case elselit: /* scanned an else */ 1178805Smckusick 11835500Sbostic if (ps.p_stack[ps.tos] != ifhead) 11935500Sbostic diag(1, "Unmatched 'else'"); 12035500Sbostic else { 12135500Sbostic ps.ind_level = ps.il[ps.tos]; /* indentation for else should 12235500Sbostic * be same as for if */ 12335500Sbostic ps.i_l_follow = ps.ind_level + 1; /* everything following should 12435500Sbostic * be in 1 level */ 12535500Sbostic ps.p_stack[ps.tos] = elsehead; 12635500Sbostic /* remember if with else */ 12735500Sbostic ps.search_brace = btype_2 | ps.else_if; 12835500Sbostic } 12935500Sbostic break; 1308805Smckusick 13135500Sbostic case rbrace: /* scanned a } */ 13235500Sbostic /* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */ 13335500Sbostic if (ps.p_stack[ps.tos - 1] == lbrace) { 13435500Sbostic ps.ind_level = ps.i_l_follow = ps.il[--ps.tos]; 13535500Sbostic ps.p_stack[ps.tos] = stmt; 13635500Sbostic } 13735500Sbostic else 13835500Sbostic diag(1, "Stmt nesting error."); 13935500Sbostic break; 1408805Smckusick 14135500Sbostic case swstmt: /* had switch (...) */ 14235500Sbostic ps.p_stack[++ps.tos] = swstmt; 14335500Sbostic ps.cstk[ps.tos] = case_ind; 14435500Sbostic /* save current case indent level */ 14535500Sbostic ps.il[ps.tos] = ps.i_l_follow; 14635500Sbostic case_ind = ps.i_l_follow + ps.case_indent; /* cases should be one 14724456Smckusick * level down from 14824456Smckusick * switch */ 14935502Sbostic ps.i_l_follow += ps.case_indent + 1; /* statements should be two 15035500Sbostic * levels in */ 15135500Sbostic ps.search_brace = btype_2; 15235500Sbostic break; 1538805Smckusick 15435500Sbostic case semicolon: /* this indicates a simple stmt */ 15535500Sbostic break_comma = false; /* turn off flag to break after commas in a 15635500Sbostic * declaration */ 15735500Sbostic ps.p_stack[++ps.tos] = stmt; 15835500Sbostic ps.il[ps.tos] = ps.ind_level; 15935500Sbostic break; 1608805Smckusick 16135500Sbostic default: /* this is an error */ 16235500Sbostic diag(1, "Unknown code to parser"); 16335500Sbostic return; 1648805Smckusick 1658805Smckusick 16624456Smckusick } /* end of switch */ 1678805Smckusick 16824456Smckusick reduce(); /* see if any reduction can be done */ 16935500Sbostic 1708805Smckusick #ifdef debug 17124456Smckusick for (i = 1; i <= ps.tos; ++i) 17224456Smckusick printf("(%d %d)", ps.p_stack[i], ps.il[i]); 17324456Smckusick printf("\n"); 1748805Smckusick #endif 17535500Sbostic 1768805Smckusick return; 1778805Smckusick } 17835500Sbostic 17935500Sbostic /* 18035500Sbostic * NAME: reduce 18135500Sbostic * 18235500Sbostic * FUNCTION: Implements the reduce part of the parsing algorithm 18335500Sbostic * 18436555Sbostic * ALGORITHM: The following reductions are done. Reductions are repeated 18536555Sbostic * until no more are possible. 18635500Sbostic * 18736555Sbostic * Old TOS New TOS 18836555Sbostic * <stmt> <stmt> <stmtl> 18936555Sbostic * <stmtl> <stmt> <stmtl> 19036555Sbostic * do <stmt> "dostmt" 19136555Sbostic * if <stmt> "ifstmt" 19236555Sbostic * switch <stmt> <stmt> 19336555Sbostic * decl <stmt> <stmt> 19436555Sbostic * "ifelse" <stmt> <stmt> 19536555Sbostic * for <stmt> <stmt> 19636555Sbostic * while <stmt> <stmt> 19736555Sbostic * "dostmt" while <stmt> 19835500Sbostic * 19936555Sbostic * On each reduction, ps.i_l_follow (the indentation for the following line) 20036555Sbostic * is set to the indentation level associated with the old TOS. 20135500Sbostic * 20235500Sbostic * PARAMETERS: None 20335500Sbostic * 20435500Sbostic * RETURNS: Nothing 20535500Sbostic * 20635500Sbostic * GLOBALS: ps.cstk ps.i_l_follow = ps.il ps.p_stack = ps.tos = 20735500Sbostic * 20835500Sbostic * CALLS: None 20935500Sbostic * 21036555Sbostic * CALLED BY: parse 21135500Sbostic * 21235500Sbostic * HISTORY: initial coding November 1976 D A Willcox of CAC 21335500Sbostic * 21436555Sbostic */ 2158805Smckusick /*----------------------------------------------*\ 21635500Sbostic | REDUCTION PHASE | 2178805Smckusick \*----------------------------------------------*/ 21835500Sbostic reduce() 21935500Sbostic { 2208805Smckusick 22124456Smckusick register int i; 2228805Smckusick 22335500Sbostic for (;;) { /* keep looping until there is nothing left to 22435500Sbostic * reduce */ 2258805Smckusick 22624456Smckusick switch (ps.p_stack[ps.tos]) { 2278805Smckusick 22835500Sbostic case stmt: 22935500Sbostic switch (ps.p_stack[ps.tos - 1]) { 2308805Smckusick 23135500Sbostic case stmt: 23235500Sbostic case stmtl: 23335500Sbostic /* stmtl stmt or stmt stmt */ 23435500Sbostic ps.p_stack[--ps.tos] = stmtl; 23535500Sbostic break; 2368805Smckusick 23735500Sbostic case dolit: /* <do> <stmt> */ 23835500Sbostic ps.p_stack[--ps.tos] = dohead; 23935500Sbostic ps.i_l_follow = ps.il[ps.tos]; 24035500Sbostic break; 2418805Smckusick 24235500Sbostic case ifstmt: 24335500Sbostic /* <if> <stmt> */ 24435500Sbostic ps.p_stack[--ps.tos] = ifhead; 24535500Sbostic for (i = ps.tos - 1; 24635500Sbostic ( 24735500Sbostic ps.p_stack[i] != stmt 24835500Sbostic && 24935500Sbostic ps.p_stack[i] != stmtl 25035500Sbostic && 25135500Sbostic ps.p_stack[i] != lbrace 25235500Sbostic ); 25335500Sbostic --i); 25435500Sbostic ps.i_l_follow = ps.il[i]; 25535500Sbostic /* 25635500Sbostic * for the time being, we will assume that there is no else on 25735500Sbostic * this if, and set the indentation level accordingly. If an 25835500Sbostic * else is scanned, it will be fixed up later 25935500Sbostic */ 26035500Sbostic break; 2618805Smckusick 26235500Sbostic case swstmt: 26335500Sbostic /* <switch> <stmt> */ 26435500Sbostic case_ind = ps.cstk[ps.tos - 1]; 2658805Smckusick 26635500Sbostic case decl: /* finish of a declaration */ 26735500Sbostic case elsehead: 26835500Sbostic /* <<if> <stmt> else> <stmt> */ 26935500Sbostic case forstmt: 27035500Sbostic /* <for> <stmt> */ 27135500Sbostic case whilestmt: 27235500Sbostic /* <while> <stmt> */ 27335500Sbostic ps.p_stack[--ps.tos] = stmt; 27435500Sbostic ps.i_l_follow = ps.il[ps.tos]; 27535500Sbostic break; 2768805Smckusick 27735500Sbostic default: /* <anything else> <stmt> */ 27835500Sbostic return; 2798805Smckusick 28035500Sbostic } /* end of section for <stmt> on top of stack */ 28135500Sbostic break; 28235500Sbostic 28335500Sbostic case whilestmt: /* while (...) on top */ 28435500Sbostic if (ps.p_stack[ps.tos - 1] == dohead) { 28535500Sbostic /* it is termination of a do while */ 28635500Sbostic ps.p_stack[--ps.tos] = stmt; 2878805Smckusick break; 28835500Sbostic } 28935500Sbostic else 29035500Sbostic return; 2918805Smckusick 29235500Sbostic default: /* anything else on top */ 29335500Sbostic return; 2948805Smckusick 29524456Smckusick } 29624456Smckusick } 2978805Smckusick } 298