home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume10 / ifp / part06 / interp / inob.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-07-06  |  6.3 KB  |  271 lines

  1.  
  2. /****** inob.c ********************************************************/
  3. /**                                                                  **/
  4. /**                    University of Illinois                        **/
  5. /**                                                                  **/
  6. /**                Department of Computer Science                    **/
  7. /**                                                                  **/
  8. /**   Tool: IFP                         Version: 0.5                 **/
  9. /**                                                                  **/
  10. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  11. /**                                                                  **/
  12. /**   Revised by: Arch D. Robison       Date:   Aug 6, 1986          **/
  13. /**                                                                  **/
  14. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  15. /**                            Prof. W. J. Kubitz                    **/
  16. /**                                                                  **/
  17. /**                                                                  **/
  18. /**------------------------------------------------------------------**/
  19. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  20. /**                       All Rights Reserved.                       **/
  21. /**********************************************************************/
  22.  
  23. /*************** object input parser (recursive descent) ***************/
  24.  
  25.  
  26. #include <stdio.h>
  27. #include <ctype.h>
  28. #include "struct.h"
  29. #include "node.h"
  30. #include "string.h"
  31. #include "inob.h"
  32.  
  33. /*
  34.  * ObDelim
  35.  *
  36.  * Theses characters delimit objects.
  37.  * Compare with NodeDelim in inimport.c 
  38.  */
  39. private char ObDelim[] = " ,<>|[](){};:\t\n";
  40.  
  41. /*
  42.  * InBlanks
  43.  *
  44.  * Skip to first non-blank character not in comment.
  45.  *
  46.  * Input
  47.  *     F = input descriptor
  48.  *
  49.  * Output
  50.  *    F = input descriptor pointing to non-blank character
  51.  */
  52. void InBlanks (F)
  53.    register InDesc *F;
  54.    {
  55.       while (1) {
  56.  
  57.      while (1) {
  58.         if (!*F->InPtr)
  59.            if (F->InLineNum >= 0) 
  60.           if (NULL != fgets (F->InBuf,INBUFSIZE,F->InFile)) {
  61.              F->InPtr = F->InBuf;
  62.              F->InLineNum++;
  63.           }
  64.         if (!isspace (*F->InPtr)) break;
  65.         F->InPtr++;
  66.      }
  67.  
  68.      if (*F->InPtr == '(' && F->InPtr[1] == '*') {
  69.         F->ComLevel++;
  70.         F->InPtr+=2;
  71.      } else if (*F->InPtr == '*' && F->InPtr[1] == ')') {
  72.         F->ComLevel--;
  73.         F->InPtr+=2;
  74.      } else if (F->ComLevel && *F->InPtr) F->InPtr++;
  75.      else break;
  76.       }
  77.    }
  78.  
  79. /*
  80.  * IsTok
  81.  *
  82.  * Check if next token in input is S.  Skip if found.
  83.  */
  84. boolean IsTok (F,S)
  85.    InDesc *F;
  86.    register char *S;
  87.    {
  88.       register char *T;
  89.  
  90.       for (T = F->InPtr; *S; S++,T++)
  91.      if (*S != *T) return 0;
  92.  
  93.       /* Check if alphabetic token is prefix of longer token */
  94.       if (isalpha (T[-1]) && isalpha (T[0])) return 0; 
  95.  
  96.       F->InPtr = T;
  97.       InBlanks (F);
  98.       return 1;
  99.    }
  100.  
  101. /*
  102.  * InString
  103.  *
  104.  * Input a string. 
  105.  *
  106.  * Input
  107.  *      *F = input descriptor pointing to first character of string
  108.  *      Delim = string of non-alphanumeric delimiters
  109.  *      Quoted = skip closing delimiter
  110.  *
  111.  * Output
  112.  *      *F = input descriptor pointing to next token after string
  113.  *      X = string object
  114.  *      result = pointer to string, NULL if SysError or empty string.
  115.  *
  116.  * A SysError may occur, in which case X = bottom.
  117.  */
  118. StrPtr InString (F,X,Delim,Quoted)
  119.    register InDesc *F;
  120.    ObjectPtr X;
  121.    char *Delim;
  122.    boolean Quoted;
  123.    {
  124.       CharPtr U;
  125.       register char C;
  126.  
  127.       RepTag (X,STRING);
  128.       X->String = NULL;
  129.       CPInit (&U,&X->String);
  130.       do {
  131.          extern char *index ();
  132.      C = *F->InPtr++;
  133.      if (!isalnum (C) && NULL != index (Delim,C)) C = '\0';
  134.      CPAppend (&U,C);
  135.      if (SysError) {RepTag (X,BOTTOM); return NULL;}
  136.       } while (C);
  137.       if (!Quoted) F->InPtr--;
  138.       InBlanks (F);
  139.       return X->String;
  140.    }
  141.  
  142.  
  143. /*
  144.  * InList
  145.  *
  146.  * Input a list
  147.  *
  148.  * Input
  149.  *     F = input descriptor pointing to first token after '<'
  150.  *
  151.  * Output
  152.  *     result = true iff no error occurs
  153.  *     *X = sequence, or unchanged if error occurs.
  154.  */
  155. private boolean InList (F,X)
  156.    register InDesc *F;
  157.    ObjectPtr X;
  158.    {
  159.       ListPtr R=NULL;
  160.       register MetaPtr A = &R;
  161.  
  162.       while (!IsTok (F,">")) {
  163.      if (!*F->InPtr) {
  164.         DelLPtr (R);
  165.         return InError (F,"unfinished sequence");
  166.      }   
  167.      NewList (A,1L);
  168.      if (SysError || !InObject (F,&(*A)->Val)) {
  169.         DelLPtr (R);
  170.         return 0;
  171.      }
  172.      A = & (*A)->Next;
  173.      (void) IsTok (F,",");
  174.       }
  175.       RepTag (X,LIST);
  176.       X->List = R;
  177.       return 1;
  178.    }
  179.  
  180. /*
  181.  * InObject
  182.  *
  183.  * Read an object.
  184.  *
  185.  * Input
  186.  *      *F = input descriptor pointing to object
  187.  *
  188.  * Output
  189.  *      *F = input descriptor pointing to next token
  190.  *    result = true iff object is read successfully.
  191.  *
  192.  * A SysError may occur, in which case X is unchanged.
  193.  */
  194. boolean InObject (F,X)
  195.    register InDesc *F;
  196.    register ObjectPtr X;
  197.    {
  198.       if (IsTok (F,"<")) return InList (F,X);
  199.  
  200.       else if (IsTok (F,"(")) {
  201.  
  202.      (void) InComp (F,X,NIL);
  203.      if (!IsTok (F,")")) return InError (F,"')' expected");
  204.  
  205.       } else { 
  206.  
  207.      /* Input atom */
  208.  
  209.      static char Delim[2] = {'\0','\0'};
  210.      *Delim = *F->InPtr;
  211.  
  212.      if (*Delim == '\"' || *Delim == '\'') {
  213.         F->InPtr++;
  214.         (void) InString (F,X,Delim,1);
  215.      } else {
  216.  
  217.         FPint K;
  218.         register StrPtr S = InString (F,X,ObDelim,0);
  219.         if (S == NULL) return SysError || InError (F,"object expected");
  220.         if (S->StrChar[1] == '\0')
  221.            switch (S->StrChar[0]) {
  222.           case 'f':
  223.              RepBool (X,0);
  224.              return 1;
  225.           case 't':
  226.              RepBool (X,1);
  227.              return 1;
  228.           case '?':
  229.              RepTag (X,BOTTOM);
  230.              return 1;
  231.            }
  232.         if (StrToFloat (X) && !GetFPInt (X,&K)) {
  233.            X->Tag = INT;
  234.            X->Int = K;
  235.         } 
  236.      }
  237.       }
  238.       return 1;
  239.    }
  240.  
  241. /*
  242.  * InitIn
  243.  *
  244.  * Initialize input descriptor for node N and file FileDesc.
  245.  * Advance the input pointer to the first token.
  246.  *
  247.  * Input
  248.  *    *F = input descriptor
  249.  *    M = module pointer
  250.  *    FileDesc = open file descriptor
  251.  *    LineNum = 0 for normal input, -1 if single-line mode
  252.  */
  253. void InitIn (F,M,FileDesc,LineNum)
  254.    register InDesc *F;
  255.    NodePtr M;
  256.    FILE *FileDesc;
  257.    int LineNum;
  258.    {
  259.       F->InFile = FileDesc;
  260.       F->InLineNum= LineNum;
  261.       F->InPtr = F->InBuf;
  262.       *F->InPtr = '\0';
  263.       F->InDefMod = M;
  264.       F->ComLevel = 0;
  265.       InBlanks (F);
  266.    }
  267.  
  268.  
  269. /******************************* end of inob.c *******************************/
  270.  
  271.