home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / INDENTSR.ZIP / PARSE.C < prev    next >
C/C++ Source or Header  |  1992-08-27  |  9KB  |  328 lines

  1. /*
  2.  * Copyright (c) 1985 Sun Microsystems, Inc.
  3.  * Copyright (c) 1980 The Regents of the University of California.
  4.  * Copyright (c) 1976 Board of Trustees of the University of Illinois.
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms are permitted
  8.  * provided that the above copyright notice and this paragraph are
  9.  * duplicated in all such forms and that any documentation,
  10.  * advertising materials, and other materials related to such
  11.  * distribution and use acknowledge that the software was developed
  12.  * by the University of California, Berkeley, the University of Illinois,
  13.  * Urbana, and Sun Microsystems, Inc.  The name of either University
  14.  * or Sun Microsystems may not be used to endorse or promote products
  15.  * derived from this software without specific prior written permission.
  16.  * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
  17.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  18.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19.  */
  20.  
  21. #ifndef lint
  22. static char sccsid[] = "@(#)parse.c 5.8 (Berkeley) 88/09/15";
  23.  
  24. #endif                    /* not lint */
  25.  
  26. #include "globals.h"
  27. #include "codes.h"
  28.  
  29. #ifdef ANSIC
  30. static void reduce(void);
  31.  
  32. void 
  33. parse(int tk)
  34. #else
  35. parse(tk)
  36.     int tk;                /* the code for the construct scanned */
  37.  
  38. #endif
  39. {
  40.     int i;
  41.  
  42. #ifdef debug
  43.     printf("%2d - %s\n", tk, token);
  44. #endif
  45.  
  46.     while (ps.p_stack[ps.tos] == ifhead && tk != elselit) {
  47.     /* true if we have an if without an else */
  48.     ps.p_stack[ps.tos] = stmt;    /* apply the if(..) stmt ::= stmt
  49.                      * reduction */
  50.     reduce();            /* see if this allows any reduction */
  51.     }
  52.  
  53.  
  54.     switch (tk) {            /* go on and figure out what to do
  55.                      * with the input */
  56.  
  57.     case decl:                /* scanned a declaration word */
  58.     ps.search_brace = btype_2 && !btype_3;
  59.     /* indicate that following brace should be on same line */
  60.     if (ps.p_stack[ps.tos] != decl) {    /* only put one declaration
  61.                          * onto stack */
  62.         break_comma = true;        /* while in declaration, newline
  63.                      * should be forced after comma */
  64.         ps.p_stack[++ps.tos] = decl;
  65.         ps.il[ps.tos] = ps.i_l_follow;
  66.  
  67.         if (ps.ljust_decl) {    /* only do if we want left justified
  68.                      * declarations */
  69.         ps.ind_level = 0;
  70.         for (i = ps.tos - 1; i > 0; --i)
  71.             if (ps.p_stack[i] == decl)
  72.             ++ps.ind_level;    /* indentation is number of
  73.                      * declaration levels deep we are */
  74.         ps.i_l_follow = ps.ind_level;
  75.         }
  76.     }
  77.     break;
  78.  
  79.     case ifstmt:            /* scanned if (...) */
  80.     if (ps.p_stack[ps.tos] == elsehead && ps.else_if)    /* "else if ..." */
  81.         ps.i_l_follow = ps.il[ps.tos];
  82.     case dolit:            /* 'do' */
  83.     case forstmt:            /* for (...) */
  84.     ps.p_stack[++ps.tos] = tk;
  85.     ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
  86.     ++ps.i_l_follow;        /* subsequent statements should be
  87.                      * indented 1 */
  88.     ps.search_brace = btype_2 && !btype_3;
  89.     break;
  90.  
  91.     case lbrace:            /* scanned { */
  92.     break_comma = false;        /* don't break comma in an initial
  93.                      * list */
  94.     if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl
  95.         || ps.p_stack[ps.tos] == stmtl)
  96.         ++ps.i_l_follow;        /* it is a random, isolated stmt
  97.                      * group or a declaration */
  98.     else {
  99.         if (s_code == e_code) {
  100.         /*
  101.          * only do this if there is nothing on the line
  102.          */
  103.         --ps.ind_level;
  104.         /*
  105.          * it is a group as part of a while, for, etc.
  106.          */
  107.         if (ps.p_stack[ps.tos] == swstmt && ps.case_indent >= (float) 1 &&
  108.             ps.case_code_indent >= (float) 1)
  109.             --ps.ind_level;
  110.         /*
  111.          * for a switch, brace should be two levels out from the code
  112.          */
  113.         }
  114.     }
  115.  
  116.     ps.p_stack[++ps.tos] = lbrace;
  117.     ps.il[ps.tos] = ps.ind_level;
  118.     ps.p_stack[++ps.tos] = stmt;
  119.     /* allow null stmt between braces */
  120.     ps.il[ps.tos] = ps.i_l_follow;
  121.     break;
  122.  
  123.     case whilestmt:            /* scanned while (...) */
  124.     if (ps.p_stack[ps.tos] == dohead) {
  125.         /* it is matched with do stmt */
  126.         ps.ind_level = ps.i_l_follow = ps.il[ps.tos];
  127.         ps.p_stack[++ps.tos] = whilestmt;
  128.         ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
  129.     } else {            /* it is a while loop */
  130.         ps.p_stack[++ps.tos] = whilestmt;
  131.         ps.il[ps.tos] = ps.i_l_follow;
  132.         ++ps.i_l_follow;
  133.         ps.search_brace = btype_2 && !btype_3;
  134.     }
  135.  
  136.     break;
  137.  
  138.     case elselit:            /* scanned an else */
  139.  
  140.     if (ps.p_stack[ps.tos] != ifhead)
  141.         diag(1, "Unmatched 'else'");
  142.     else {
  143.         ps.ind_level = ps.il[ps.tos];    /* indentation for else
  144.                          * should be same as for if */
  145.         ps.i_l_follow = ps.ind_level + 1;    /* everything following
  146.                          * should be in 1 level */
  147.         ps.p_stack[ps.tos] = elsehead;
  148.         /* remember if with else */
  149.         ps.search_brace = (btype_2 && !btype_3) | ps.else_if;
  150.     }
  151.     break;
  152.  
  153.     case rbrace:            /* scanned a } */
  154.     /* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */
  155.     if (ps.p_stack[ps.tos - 1] == lbrace) {
  156.         if (btype_3)
  157.         ps.i_l_follow = ps.il[--ps.tos];
  158.         else
  159.         ps.ind_level = ps.i_l_follow = ps.il[--ps.tos];
  160.         ps.p_stack[ps.tos] = stmt;
  161.     } else
  162.         diag(1, "Stmt nesting error.");
  163.     break;
  164.  
  165.     case swstmt:            /* had switch (...) */
  166.     ps.p_stack[++ps.tos] = swstmt;
  167.     ps.cstk[ps.tos] = case_ind;
  168.     /* save current case indent level */
  169.     ps.il[ps.tos] = ps.i_l_follow;
  170.     case_ind = ps.i_l_follow + ps.case_indent;
  171.     /*
  172.      * cases should be one level down from switch
  173.      */
  174.     ps.i_l_follow += ps.case_indent + ps.case_code_indent;
  175.     /*
  176.      * statements should be two levels in
  177.      */
  178.     ps.search_brace = btype_2 && !btype_3;
  179.     break;
  180.  
  181.     case semicolon:            /* this indicates a simple stmt */
  182.     break_comma = false;        /* turn off flag to break after
  183.                      * commas in a declaration */
  184.     ps.p_stack[++ps.tos] = stmt;
  185.     ps.il[ps.tos] = ps.ind_level;
  186.     break;
  187.  
  188.     default:                /* this is an error */
  189.     diag(1, "Unknown code to parser");
  190.     return;
  191.  
  192.  
  193.     }                    /* end of switch */
  194.  
  195.     reduce();                /* see if any reduction can be done */
  196.  
  197. #ifdef debug
  198.     for (i = 1; i <= ps.tos; ++i)
  199.     printf("(%d %d)", ps.p_stack[i], ps.il[i]);
  200.     printf("\n");
  201. #endif
  202.  
  203.     return;
  204. }
  205.  
  206. /*
  207.  * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
  208.  *
  209.  * All rights reserved
  210.  *
  211.  *
  212.  * NAME: reduce
  213.  *
  214.  * FUNCTION: Implements the reduce part of the parsing algorithm
  215.  *
  216.  * ALGORITHM: The following reductions are done.  Reductions are repeated until
  217.  * no more are possible.
  218.  *
  219.  * Old TOS    New TOS <stmt> <stmt>    <stmtl> <stmtl> <stmt>    <stmtl> do
  220.  * <stmt>   "dostmt" if <stmt>    "ifstmt" switch <stmt>    <stmt> decl
  221.  * <stmt>   <stmt> "ifelse" <stmt>  <stmt> for <stmt>    <stmt> while
  222.  * <stmt>   <stmt> "dostmt" while   <stmt>
  223.  *
  224.  * On each reduction, ps.i_l_follow (the indentation for the following line) is
  225.  * set to the indentation level associated with the old TOS.
  226.  *
  227.  * PARAMETERS: None
  228.  *
  229.  * RETURNS: Nothing
  230.  *
  231.  * GLOBALS: ps.cstk ps.i_l_follow = ps.il ps.p_stack = ps.tos =
  232.  *
  233.  * CALLS: None
  234.  *
  235.  * CALLED BY: parse
  236.  *
  237.  * HISTORY: initial coding  November 1976   D A Willcox of CAC
  238.  *
  239.  */
  240. /*----------------------------------------------*\
  241. |   REDUCTION PHASE            |
  242. \*----------------------------------------------*/
  243. #ifdef ANSIC
  244. static void 
  245. reduce(void)
  246. #else
  247. reduce()
  248. #endif
  249. {
  250.  
  251.     register int i;
  252.  
  253.     for (;;) {                /* keep looping until there is
  254.                      * nothing left to reduce */
  255.  
  256.     switch (ps.p_stack[ps.tos]) {
  257.  
  258.     case stmt:
  259.         switch (ps.p_stack[ps.tos - 1]) {
  260.  
  261.         case stmt:
  262.         case stmtl:
  263.         /* stmtl stmt or stmt stmt */
  264.         ps.p_stack[--ps.tos] = stmtl;
  265.         break;
  266.  
  267.         case dolit:        /* <do> <stmt> */
  268.         ps.p_stack[--ps.tos] = dohead;
  269.         ps.i_l_follow = ps.il[ps.tos];
  270.         break;
  271.  
  272.         case ifstmt:
  273.         /* <if> <stmt> */
  274.         ps.p_stack[--ps.tos] = ifhead;
  275.         for (i = ps.tos - 1;
  276.             (
  277.             ps.p_stack[i] != stmt
  278.             &&
  279.             ps.p_stack[i] != stmtl
  280.             &&
  281.             ps.p_stack[i] != lbrace
  282.             );
  283.             --i);
  284.         ps.i_l_follow = ps.il[i];
  285.         /*
  286.          * for the time being, we will assume that there is no else
  287.          * on this if, and set the indentation level accordingly. If
  288.          * an else is scanned, it will be fixed up later
  289.          */
  290.         break;
  291.  
  292.         case swstmt:
  293.         /* <switch> <stmt> */
  294.         case_ind = ps.cstk[ps.tos - 1];
  295.  
  296.         case decl:            /* finish of a declaration */
  297.         case elsehead:
  298.         /* <<if> <stmt> else> <stmt> */
  299.         case forstmt:
  300.         /* <for> <stmt> */
  301.         case whilestmt:
  302.         /* <while> <stmt> */
  303.         ps.p_stack[--ps.tos] = stmt;
  304.         ps.i_l_follow = ps.il[ps.tos];
  305.         break;
  306.  
  307.         default:            /* <anything else> <stmt> */
  308.         return;
  309.  
  310.         }                /* end of section for <stmt> on top
  311.                      * of stack */
  312.         break;
  313.  
  314.     case whilestmt:        /* while (...) on top */
  315.         if (ps.p_stack[ps.tos - 1] == dohead) {
  316.         /* it is termination of a do while */
  317.         ps.p_stack[--ps.tos] = stmt;
  318.         break;
  319.         } else
  320.         return;
  321.  
  322.     default:            /* anything else on top */
  323.         return;
  324.  
  325.     }
  326.     }
  327. }
  328.