home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / cpm68k / sdb.lbr / COM.CQ / COM.C
Encoding:
C/C++ Source or Header  |  1986-10-31  |  10.4 KB  |  425 lines

  1. /* -*-c,save-*- */
  2. /* SDB - expression compiler 
  3.     syntax:
  4.         <expr>          ::= <lor> <EOS>
  5.         <lor>           ::= <land> { '|' <land> }
  6.         <land>          ::= <relat> { '&' <relat> }
  7.         <relat>         ::= <primary> { <relop> <primary> }
  8.         <primary>       ::= <factor> | <unop> <unary>
  9.         <factor>        ::= <number> | <string> | '(' <query> ')'
  10.         <number>        ::= <digit> | <number> <digit>
  11.         <string>        ::= '"' <chars> '"'
  12.         <chars>         ::= nil | <chars> <character>
  13.         <relop>         ::= '=' | '<>' | '<' | '>' | '<=' | '>='
  14.         <unop>          ::= '+' | '-' | '~'
  15. */
  16.  
  17. #include "sdbio.h"
  18.  
  19. /* #define DEBUG    1    /* debug hackery */
  20. #ifdef DEBUG
  21. #define LOCAL
  22. #else
  23. #define LOCAL static
  24. #endif
  25.  
  26. extern int dbv_token;
  27. extern char dbv_tstring[];
  28. extern int dbv_tvalue;
  29.  
  30. extern int db_xand();
  31. extern int db_xor();
  32. extern int db_xnot();
  33. extern int db_xlss();
  34. extern int db_xleq();
  35. extern int db_xeql();
  36. extern int db_xgeq();
  37. extern int db_xgtr();
  38. extern int db_xneq();
  39. extern int db_xpush();
  40. extern int db_xstop();
  41.  
  42. LOCAL union codecell code[CODEMAX+1];
  43. LOCAL int cndx;
  44. LOCAL struct sel *selptr;
  45.  
  46. /* compile - compile a boolean expression */
  47. int db_compile(slptr)
  48.   struct sel *slptr;
  49. {
  50.     int result,i;
  51.     union codecell *cptr;
  52. #ifdef Lattice
  53.     int (*dns)();  /*dns*/
  54. #endif
  55.  
  56.     /* save the selection structure pointer */
  57.     selptr = slptr;
  58.  
  59.     /* initialize the code array index */
  60.     cndx = 0;
  61.  
  62.     /* parse the boolean expression */
  63.     if (!expr(&result)) {
  64.         code[cndx++].c_operator = db_xstop;
  65.         freelit(code);
  66.         return (FALSE);
  67.     }
  68.  
  69.     /* terminate the code */
  70.     code[cndx++].c_operator = db_xstop;
  71.  
  72.     /* allocate space for the code array */
  73.     if ((cptr = malloc(sizeof(union codecell) * cndx)) == NULL) {
  74.         freelit(code);
  75.         return (FALSE);
  76.     }
  77.  
  78.     /* store the code into the code array */
  79.     slptr->sl_where = cptr;
  80.     for (i = 0; i < cndx; i++) {
  81.         (*cptr++).c_operator = code[i].c_operator;
  82. #ifndef Lattice
  83.         if (code[i].c_operator == db_xpush)
  84. #else
  85.         if ( code[i].c_operator == (dns=db_xpush) )  /*dns*/
  86. #endif
  87.             (*cptr++).c_operand = code[++i].c_operand;
  88.     }
  89.  
  90.     /* return successfully */
  91.     return (TRUE);
  92. }
  93.  
  94. /* db_fcode - free a code array */
  95. db_fcode(slptr)
  96.   struct sel *slptr;
  97. {
  98.     /* make sure there is a where clause */
  99.     if (slptr->sl_where == NULL)
  100.         return;
  101.  
  102.     /* free the literals */
  103.     freelit(slptr->sl_where);
  104.  
  105.     /* free the code array */
  106.     free(slptr->sl_where);
  107. }
  108.  
  109. /* operator - insert an operator into the code array */
  110. LOCAL int operator(opr)
  111.   int (*opr)();
  112. {
  113.     /* insert the operator */
  114.     if (cndx < CODEMAX)
  115.         code[cndx++].c_operator = opr;
  116.     else
  117.         return (db_ferror(CDSIZE));
  118.  
  119.     /* return successfully */
  120.     return (TRUE);
  121. }
  122.  
  123. /* operand - insert an operand into the code array */
  124. LOCAL int operand(opr)
  125.   struct operand *opr;
  126. {
  127.     /* insert the push operator */
  128.     if (!operator(db_xpush))
  129.         return (FALSE);
  130.  
  131.     /* insert the operand */
  132.     if (cndx < CODEMAX)
  133.         code[cndx++].c_operand = opr;
  134.     else
  135.         return (db_ferror(CDSIZE));
  136.  
  137.     /* return successfully */
  138.     return (TRUE);
  139. }
  140.  
  141. /* expr - compile an expression */
  142. LOCAL int expr(result)
  143.   int *result;
  144. {
  145.     int lval,rval;
  146.  
  147.     if (!land(&lval))
  148.         return (FALSE);
  149.     while (db_token() == '|') {
  150.         db_ntoken();
  151.         if (!land(&rval))
  152.             return (FALSE);
  153.         if (!operator(db_xor))
  154.             return (FALSE);
  155.     }
  156.     *result = lval;
  157.     return (TRUE);
  158. }
  159.  
  160. LOCAL int land(result)
  161.   int *result;
  162. {
  163.     int lval,rval;
  164.  
  165.     if (!relat(&lval))
  166.         return (FALSE);
  167.     while (db_token() == '&') {
  168.         db_ntoken();
  169.         if (!relat(&rval))
  170.             return (FALSE);
  171.         if (!operator(db_xand))
  172.             return (FALSE);
  173.     }
  174.     *result = lval;
  175.     return (TRUE);
  176. }
  177.  
  178. LOCAL int relat(result)
  179.   int *result;
  180. {
  181.     int lval,rval;
  182.     int tkn;
  183.  
  184.     if (!primary(&lval))
  185.         return (FALSE);
  186.     while (db_token() <= LSS && dbv_token >= GTR) {
  187.         tkn = db_ntoken();
  188.         if (!primary(&rval))
  189.             return (FALSE);
  190.         switch (tkn) {
  191.         case LSS:
  192.                 if (!operator(db_xlss))
  193.                     return (FALSE);
  194.                 break;
  195.         case LEQ:
  196.                 if (!operator(db_xleq))
  197.                     return (FALSE);
  198.                 break;
  199.         case EQL:
  200.                 if (!operator(db_xeql))
  201.                     return (FALSE);
  202.                 break;
  203.         case NEQ:
  204.                 if (!operator(db_xneq))
  205.                     return (FALSE);
  206.                 break;
  207.         case GEQ:
  208.                 if (!operator(db_xgeq))
  209.                     return (FALSE);
  210.                 break;
  211.         case GTR:
  212.                 if (!operator(db_xgtr))
  213.                     return (FALSE);
  214.                 break;
  215.         }
  216.     }
  217.     *result = lval;
  218.     return (TRUE);
  219. }
  220.  
  221. LOCAL int primary(result)
  222.   int *result;
  223. {
  224.     int val;
  225.     int tkn;
  226.  
  227.     if (db_token() == '~') {
  228.         tkn = db_ntoken();
  229.         if (!primary(&val))
  230.             return (FALSE);
  231.         switch (tkn) {
  232.         case '~':
  233.                 if (!operator(db_xnot))
  234.                     return (FALSE);
  235.                 break;
  236.         }
  237.     }
  238.     else
  239.         if (!factor(&val))
  240.             return (FALSE);
  241.     *result = val;
  242.     return (TRUE);
  243. }
  244.  
  245. LOCAL int factor(result)
  246.   int *result;
  247. {
  248.     int val;
  249.  
  250.     if (db_token() == '(') {
  251.         db_ntoken();
  252.         if (!expr(&val))
  253.             return (FALSE);
  254.         if (db_token() != ')')
  255.             return (db_ferror(SYNTAX));
  256.         db_ntoken();
  257.     }
  258.     else
  259.         if (!get_operand(&val))
  260.             return (FALSE);
  261.     *result = val;
  262.     return (TRUE);
  263. }
  264.  
  265. /* get_operand - get an operand (number, string, or attribute) */
  266. LOCAL int get_operand(result)
  267.   int *result;
  268. {
  269.     /* determine operand type */
  270.     if (db_ntoken() == NUMBER)
  271.         return (get_number(result));
  272.     else if (dbv_token == ID)
  273.         return (get_attr(result));
  274.     else if (dbv_token == STRING)
  275.         return (get_string(result));
  276.     else
  277.         return (db_ferror(SYNTAX));
  278. }
  279.  
  280. /* get_attr - get an attribute argument */
  281. LOCAL int get_attr(result)
  282.   int *result;
  283. {
  284.     struct operand *opr;
  285.     char rname[RNSIZE+1],aname[ANSIZE+1];
  286.     char *aptr; int atype,alen;
  287.  
  288. #ifdef DEBUG
  289.     printf("*** get_attr(): dbv_tstring = %s\n", dbv_tstring);
  290. #endif
  291.     /* save the attribute name */
  292.     strncpy(aname,dbv_tstring,ANSIZE); aname[ANSIZE] = EOS;
  293.  
  294.     /* check for a "." indicating a qualified attribute name */
  295.     if (db_token() == '.') {
  296.         db_ntoken();
  297.  
  298.         /* the previous ID was really a relation name */
  299.         strcpy(rname,aname);
  300.  
  301.         /* check for the real attribute name */
  302.         if (db_ntoken() != ID)
  303.             return (db_ferror(SYNTAX));
  304.  
  305. #ifdef DEBUG
  306.     printf("***           : dbv_tstring = %s\n", dbv_tstring);
  307. #endif
  308.         /* save the attribute name */
  309.         strncpy(aname,dbv_tstring,ANSIZE); aname[ANSIZE] = EOS;
  310.  
  311.         /* lookup the attribute name */
  312.         if (!db_sattr(selptr,rname,aname,&atype,&aptr,&alen))
  313.             return (FALSE);
  314.     }
  315.     else
  316.         if (!db_sattr(selptr,NULL,aname,&atype,&aptr,&alen))
  317.             return (FALSE);
  318.  
  319.     /* get a new operand structure */
  320.     if ((opr = malloc(sizeof(struct operand))) == NULL)
  321.         return (db_ferror(INSMEM));
  322.  
  323.     /* initialize the new operand structure */
  324.     opr->o_type = ATTR;
  325.     opr->o_value.ov_char.ovc_type = atype;
  326.     opr->o_value.ov_char.ovc_string = aptr;
  327.     opr->o_value.ov_char.ovc_length = alen;
  328.  
  329.     /* insert the operand into the code array */
  330.     if (!operand(opr)) {
  331.         free(opr);
  332.         return (FALSE);
  333.     }
  334.  
  335.     /* store operand type */
  336.     *result = atype;
  337.  
  338.     /* return successfully */
  339.     return (TRUE);
  340. }
  341.  
  342. /* get_number - get a numeric operand */
  343. LOCAL int get_number(result)
  344.   int *result;
  345. {
  346.     struct operand *opr;
  347.  
  348.     /* get a new operand structure */
  349.     if ((opr = malloc(sizeof(struct operand))) == NULL)
  350.         return (db_ferror(INSMEM));
  351.  
  352.     /* initialize the new operand structure */
  353.     opr->o_type = LITERAL;
  354.     if ((opr->o_value.ov_char.ovc_string =
  355.                 malloc(strlen(dbv_tstring)+1)) == NULL) {
  356.         free(opr);
  357.         return (db_ferror(INSMEM));
  358.     }
  359.     opr->o_value.ov_char.ovc_type = TNUM;
  360.     strcpy(opr->o_value.ov_char.ovc_string,dbv_tstring);
  361.     opr->o_value.ov_char.ovc_length = strlen(dbv_tstring);
  362.  
  363.     /* insert the operand into the code array */
  364.     if (!operand(opr)) {
  365.         free(opr->o_value.ov_char.ovc_string); free(opr);
  366.         return (FALSE);
  367.     }
  368.  
  369.     /* operand type is number */
  370.     *result = TNUM;
  371.  
  372.     /* return successfully */
  373.     return (TRUE);
  374. }
  375.  
  376. /* get_string - get a string operand */
  377. LOCAL int get_string(result)
  378.   int *result;
  379. {
  380.     struct operand *opr;
  381.  
  382.     /* get a new operand structure */
  383.     if ((opr = malloc(sizeof(struct operand))) == NULL)
  384.         return (db_ferror(INSMEM));
  385.  
  386.     /* initialize the new operand structure */
  387.     opr->o_type = LITERAL;
  388.     if ((opr->o_value.ov_char.ovc_string =
  389.                 malloc(strlen(dbv_tstring)+1)) == NULL) {
  390.         free(opr);
  391.         return (db_ferror(INSMEM));
  392.     }
  393.     opr->o_value.ov_char.ovc_type = TCHAR;
  394.     strcpy(opr->o_value.ov_char.ovc_string,dbv_tstring);
  395.     opr->o_value.ov_char.ovc_length = strlen(dbv_tstring);
  396.  
  397.     /* insert the operand into the code array */
  398.     if (!operand(opr)) {
  399.         free(opr->o_value.ov_char.ovc_string); free(opr);
  400.         return (FALSE);
  401.     }
  402.  
  403.     /* operand type is character */
  404.     *result = TCHAR;
  405.  
  406.     /* return successfully */
  407.     return (TRUE);
  408. }
  409.  
  410. /* freelit - free the literals in a code array */
  411. LOCAL freelit(cptr)
  412.   union codecell *cptr;
  413. {
  414. #ifdef Lattice
  415.     int (*dns)();  /*dns*/
  416.     for (; (*cptr).c_operator != (dns=db_xstop); cptr++)  /*dns*/
  417.         if ((*cptr).c_operator == (dns=db_xpush) )        /*dns*/
  418. #else
  419.     for (; (*cptr).c_operator != db_xstop; cptr++)
  420.         if ((*cptr).c_operator == db_xpush )
  421. #endif
  422.             if ((*++cptr).c_operand->o_type == LITERAL)
  423.                 free((*cptr).c_operand->o_value.ov_char.ovc_string);
  424. }
  425.