home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume13 / bool-eval / build.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-01-31  |  6.8 KB  |  293 lines

  1. /* (c) copyright 1987 jim frost
  2.  * all rights reserved
  3.  *
  4.  * this program is copyrighted material.  the author gives permission
  5.  * to duplicate and redistribute this program provided the following
  6.  * conditions are met:
  7.  *   - this copyright notice is not removed.
  8.  *   - all duplicate copies or distributions contain full source
  9.  *     and documentation, including copyright notices.
  10.  *   - duplicate copies or distributions outside a single site are
  11.  *     original distributions without modifications.  (this is to keep
  12.  *     bastardized versions from showing up all over thie place.)
  13.  *
  14.  * this program source may be modified provided the following
  15.  * conditions are met:
  16.  *   - modified source is not distributed to other sites.
  17.  *   - modifications (including, but not limited to, bug fixes) are
  18.  *     sent to the author if the modifications are to be distributed.
  19.  *     no modified source is to be distributed unless done so by the
  20.  *     author.
  21.  *
  22.  * no warranty, either express or implied, is given for this program.
  23.  * the author makes no guarantees of fitness for any use of this
  24.  * program.  the author is not responsible for damages resulting from
  25.  * the use of this program for any purpose.
  26.  *
  27.  * 'site' refers to one or more computers under a single management.
  28.  * 'author' refers to the copyright holder, jim frost.
  29.  * 'source' refers to all files related to this program.
  30.  * 'documentation' refers to non-compilable files in the distribution.
  31.  *
  32.  * basically this notice is to keep me out of trouble should anything
  33.  * go wrong (i really *do* test these things though) and to make sure
  34.  * that the distribution of code is centralized.  makes bug fixes and
  35.  * enhancements much easier.
  36.  *
  37.  * thank you for your attention to this copyright notice.  if everyone
  38.  * follows this, you may find this a useful tool that is pretty well
  39.  * supported.
  40.  *
  41.  * author information:
  42.  *   jim frost                    permanent usnail address:
  43.  *   madd@bucsb.bu.edu            75 washington street
  44.  *   ..!harvard!bu-cs!bucsb!madd  laconia, nh  03246.
  45.  */
  46. /* build.c:
  47.  *
  48.  * this reads in a file from a pointer and builds an evaluation tree.
  49.  */
  50.  
  51. #include "bool.h"
  52.  
  53. extern int err,   /* syntax error detected */
  54.            paren, /* parenthesis depth counter */
  55.            no_print;
  56.  
  57. /*
  58.  * this function checks a BOOL_EXP for syntax errors and sets "err"
  59.  * accordingly.
  60.  */
  61.  
  62. static void check_syn(t)
  63. BOOL_EXP *t;
  64. {
  65.   switch (t->opcode) {
  66.     case FALSE :
  67.     case TRUE :
  68.     case TOKEN :
  69.       return;
  70.     case AND :
  71.     case OR :
  72.     case XOR :
  73.       if ((!t->b1) && (!t->b2)) {
  74.         err= 1;
  75.         printf("\nNull expression.\n");
  76.       }
  77.       else if (!t->b2) {
  78.         err= 1;
  79.         printf("\nMissing expression.\n");
  80.       }
  81.       return;
  82.     case UNDEF :
  83.       if ((t->b1) && (!(t->b2))) { /* single expression */
  84.         check_syn(t->b1);
  85.         return;
  86.       }
  87.       err= 1;
  88.       printf("\nMissing operator.\n");
  89.       t->value= '?';
  90.       return;
  91.     default :
  92.       panic("check_syn");
  93.   }
  94. }
  95.  
  96. BOOL_EXP *build(f)
  97. FILE       *f;            /* file we are getting input from */
  98. { int      a;
  99.   char     c,             /* current char we are reading */
  100.            tok[MAXTOKEN]; /* current token we are reading */
  101.   BOOL_EXP *t,*u;         /* current tree node and child tree node */
  102.  
  103. /*
  104.  * if eof then make SURE we return null.  this will force a synerr
  105.  * during syntax checking above or an indicative error message from
  106.  * top level.
  107.  */
  108.  
  109.   if (feof(f))
  110.     return(NULL);
  111.  
  112. /*
  113.  * get a new BOOL_EXP node to build with
  114.  */
  115.  
  116.   t= newbnode();
  117.  
  118. /*
  119.  * loop through the entire file.  a syntax error will automatically
  120.  * drop out of this loop and back up through the tree.  exiting is
  121.  * also done depending on conditions found in the source.
  122.  */
  123.  
  124.   c= ' ';
  125.   while (!feof(f))  {
  126.  
  127.     if (c == ';') {
  128.       check_syn(t);
  129.       return(t);
  130.     }
  131.     if ((c == ' ') || (c == '\011') || (c == '\n') || (c == '\r')) {
  132.       cget(f,c);
  133.       continue;
  134.     }
  135. /*
  136.  * end subexression evaluation.  do syntax error checking at current
  137.  * node to be sure it's ok.  return status to caller.
  138.  */
  139.  
  140.     if (c == ')') {
  141.       if (!paren--) {
  142.         err= 1;
  143.         printf("\nMismatched parenthesis.\n");
  144.       }
  145.       else
  146.         check_syn(t);
  147.       return(t);
  148.     }
  149.  
  150. /*
  151.  * if structure is full then we have to make it a substruct.  note
  152.  * that changing this can alter precedence determination from left
  153.  * to right or right to left.
  154.  */
  155.  
  156.     if (t->b2) {
  157.       u= t;
  158.       t= newbnode();
  159.       t->b1= u;
  160.     }
  161.  
  162.     if (begtok(c)) { /* found a token so evaluate it */
  163.  
  164. /*
  165.  * loop for token name
  166.  */
  167.  
  168.       a= 0;
  169.       do {
  170.         if (a < MAXTOKEN) /* truncate overlong tokens */
  171.           tok[a]= c;
  172.         a++;
  173.         if (feof(f))
  174.           break;
  175.         cget(f,c);
  176.       } while (intok(c));
  177.       tok[a]= '\0';
  178.  
  179. /*
  180.  * build node for token
  181.  */
  182.  
  183.       u= newbnode();
  184.       u->opcode= TOKEN;
  185.       u->value= get_token(tok);
  186.       if (t->b1)
  187.         t->b2= u;
  188.       else
  189.         t->b1= u;
  190.     }
  191.     else {
  192.       switch (c) {
  193.  
  194. /*
  195.  * comments.  this doesn't have a possible backslash preceeding it because
  196.  * I really don't care if you want to put special chars in your comments.
  197.  * two different comment types are used to allow you to comment out whole
  198.  * sections of code, which IS useful.
  199.  */
  200.  
  201.         case '[' :
  202.           while (c != ']') {
  203.             if (feof(f)) {
  204.               err= 1;
  205.               return(t);
  206.             }
  207.             cget(f,c);
  208.           }
  209.           break;
  210.         case '{' :
  211.           while (c != '}') {
  212.             if (feof(f)) {
  213.               err= 1;
  214.               return(t);
  215.             }
  216.             cget(f,c);
  217.           }
  218.           break;
  219.  
  220. /*
  221.  * true or false
  222.  */
  223.  
  224.         case '1' :
  225.         case '0' :
  226.           u= newbnode();
  227.           if (t->b1)
  228.             t->b2= u;
  229.           else
  230.             t->b1= u;
  231.           if (c == '0')
  232.             u->opcode= FALSE;
  233.           else
  234.             u->opcode= TRUE;
  235.           break;
  236.           
  237. /*
  238.  * subexpressions begin with a paren
  239.  */
  240.  
  241.         case '(' :
  242.           paren++;
  243.           if (t->b1)
  244.             t->b2= build(f);
  245.           else
  246.             t->b1= build(f);
  247.           if (err)
  248.             return(t);
  249.           break;
  250.  
  251. /*
  252.  * handle each unary operation
  253.  */
  254.  
  255.         case '!' : /* not */
  256.         case '~' :
  257.         case '/' :
  258.           if (t->b1)
  259.             t->n2= c;
  260.           else
  261.             t->n1= c;
  262.           break;
  263.  
  264. /*
  265.  * handle each of the binary operators
  266.  */
  267.  
  268.         case '&' : /* and */
  269.         case '*' :
  270.           t->opcode= AND;
  271.           t->value= c;
  272.           break;
  273.         case '|' : /* or */
  274.         case '+' :
  275.           t->opcode= OR;
  276.           t->value= c;
  277.           break;
  278.         case '^' : /* xor */
  279.           t->opcode= XOR;
  280.           t->value= c;
  281.           break;
  282.         default :
  283.           err= 1;
  284.           printf("\nIllegal character '%c'\n",c);
  285.           return(t);
  286.       }
  287.       cget(f,c);
  288.     }
  289.   }
  290.   check_syn(t); /* check for syntax errors before leaving */
  291.   return(t);
  292. }
  293.