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