home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / SQZH102.ZIP / token.c < prev    next >
C/C++ Source or Header  |  1993-01-05  |  10KB  |  421 lines

  1. #define  INCL_DOSFILEMGR
  2. #include <os2.h>
  3.  
  4. #include <stdio.h>
  5. #include <malloc.h>
  6. #include <memory.h>
  7.  
  8. #include "token.h"
  9.  
  10. #define TAB        9
  11. #define LF        10
  12. #define FF        12
  13. #define CR        13
  14. #define EOFILE    26
  15. #define D_QUOTE   34
  16. #define SPACE     ' '
  17. #define OPCHAR    '='
  18. #define IDCHAR    'A'
  19.  
  20. #define STATE_ENTRY static BOOL NEAR PASCAL
  21. #define LAST_CHAR ((int)'~'+1)
  22.  
  23.   /* cheat and not pass these, this ain't threaded */
  24. static FBUFFER IN;
  25. static FBUFFER OUT;
  26.  
  27.  
  28. /****************************************************************************
  29. * Create a lex/file buffer.
  30. *****************************************************************************/
  31. PFBUFFER createLex( int fhandle )
  32. {
  33. PFBUFFER lex = malloc( sizeof(FBUFFER)+LEX_BUFFER );
  34.  
  35.   if ( lex ) {
  36.     lex->fhandle   = fhandle;
  37.     lex->bytesRead = 0;  
  38.     lex->curChar   = CR;
  39.     lex->lastChar  = CR;
  40.     lex->buffer    = (void *)(lex + 1);
  41.     lex->bufferPos = lex->buffer;
  42.   }
  43.   return( lex );
  44.  
  45. } /* createLex */
  46.  
  47.  
  48. /****************************************************************************
  49. * Close a lex/file buffer.
  50. *****************************************************************************/
  51. void closeLex( PFBUFFER lex )
  52. {
  53.    DosClose( lex->fhandle );
  54.    free( lex );
  55.  
  56. } /* closeLex */
  57.  
  58.  
  59. /****************************************************************************
  60. *  Get the next character from the lexical analyzer IN.
  61. *****************************************************************************/
  62. static unsigned NEAR nextChar( void )
  63. {
  64. unsigned data;
  65.  
  66.   if ( IN.bytesRead == 0 ) {
  67.     unsigned err = DosRead( IN.fhandle, IN.buffer,
  68.                             LEX_BUFFER, &IN.bytesRead );
  69.     if ( err != 0 ) {
  70.       printf( "Dos file error %u\n", err );
  71.       IN.bytesRead = 0;
  72.     }
  73.     if ( IN.bytesRead != LEX_BUFFER )
  74.       IN.buffer[IN.bytesRead] = EOFILE;   /* set end of file */
  75.     IN.bufferPos = IN.buffer;
  76.   }
  77.   data = (unsigned)(*(IN.bufferPos));
  78.   IN.bufferPos++;
  79.   IN.bytesRead--;
  80.  
  81.   return( data );
  82.  
  83. } /* nextChar */
  84.  
  85.  
  86. /****************************************************************************
  87. *  Put the next character into the file buffer.
  88. *****************************************************************************/
  89. static void NEAR putChar( unsigned data )
  90. {
  91.  
  92.   if ( data == EOFILE || OUT.bytesRead == LEX_BUFFER ) {
  93.     unsigned bytes;
  94.     DosWrite( OUT.fhandle, OUT.buffer, OUT.bytesRead, &bytes );
  95.     OUT.bytesRead = 0;
  96.   }
  97.  
  98.   OUT.buffer[OUT.bytesRead] = (char)data;
  99.   OUT.bytesRead++;
  100.  
  101. } /* putChar */
  102.  
  103.  
  104. /****************************************************************************
  105. *  Remove white space.
  106. *****************************************************************************/
  107. STATE_ENTRY whiteSpace( void )
  108. {
  109. unsigned chr;
  110.  
  111.            /* if an id char, put in a separator */
  112.   if ( IN.lastChar == IDCHAR ) {
  113.     putChar( SPACE );
  114.     IN.lastChar = SPACE;
  115.   }
  116.   do {
  117.     chr = nextChar( );
  118.   }while ( chr == SPACE || chr == TAB );
  119.  
  120.   IN.curChar = chr;
  121.   return( FALSE );
  122.  
  123. }  /* whiteSpace */
  124.  
  125.  
  126. /****************************************************************************
  127. * Deal with CR/LF remove multiple instances of them.
  128. *****************************************************************************/
  129. STATE_ENTRY cariageReturn( void )
  130. {
  131. unsigned chr;
  132.  
  133.   if ( IN.lastChar != CR ) {
  134.     putChar( CR );
  135.     putChar( LF );
  136.     IN.lastChar = CR;
  137.   }
  138.   do {
  139.     chr = nextChar( );
  140.   }while ( chr == CR || chr == LF );
  141.   IN.curChar = chr;
  142.   return( FALSE );
  143.  
  144. }  /* cariageReturn */
  145.  
  146.  
  147. /****************************************************************************
  148. *  Any operator character.
  149. *****************************************************************************/
  150. STATE_ENTRY opChar( void )
  151. {
  152.  
  153.   putChar(IN.curChar );
  154.   IN.lastChar = OPCHAR;  /* an operator acts as a separator */
  155.   IN.curChar = nextChar( );
  156.   return( FALSE );
  157.  
  158. }  /* opChar */
  159.  
  160.  
  161. /****************************************************************************
  162. *  Any id/numeric character.
  163. *****************************************************************************/
  164. STATE_ENTRY idChar( void )
  165. {
  166.  
  167.   putChar(IN.curChar );
  168.   IN.lastChar = IDCHAR;  /* must separate with white space */
  169.   IN.curChar = nextChar( );
  170.   return( FALSE );
  171.  
  172. }  /* idChar */
  173.  
  174.  
  175. /****************************************************************************
  176. *  Double Quote char, a string follows.  Allow C style escape sequences in
  177. * the string.
  178. *****************************************************************************/
  179. STATE_ENTRY doubleQuote( void )
  180. {
  181. unsigned chr;
  182.  
  183.   putChar(D_QUOTE );
  184.   chr = nextChar( );
  185.   for (;;) {
  186.     while ( chr != D_QUOTE && chr != '\\' && chr != EOFILE ) {
  187.       putChar(chr);
  188.       chr = nextChar();
  189.     }
  190.     if ( chr == EOFILE )
  191.       return( TRUE );
  192.     else if ( chr == '\\' ) {   /* accept whatever is next */
  193.       putChar(chr );
  194.       chr = nextChar();
  195.     }else
  196.       break;
  197.   }
  198.   putChar(D_QUOTE );
  199.   IN.lastChar = SPACE;  /* acts as a separator */
  200.   IN.curChar = nextChar( );
  201.   return( FALSE );
  202.  
  203. }  /* doubleQuote */
  204.  
  205.  
  206. /****************************************************************************
  207. *  Divide character
  208. *****************************************************************************/
  209. STATE_ENTRY divChar( void )
  210. {
  211. unsigned chr;
  212.   
  213.   chr = nextChar( );
  214.   if ( chr == '/' ) {            /* beginning of C++ comment */
  215.     while ( chr != EOFILE && chr != CR )
  216.       chr = nextChar();
  217.     if ( chr == EOFILE )
  218.       return( TRUE );
  219.   }else if ( chr != '*' ) {    /* plane old divide char */
  220.     IN.lastChar = SPACE;
  221.     putChar('/');
  222.   }else {                      /* beginning of comment */
  223.     chr = nextChar();
  224.     for (;;) {
  225.       while ( chr != EOFILE && chr != '*')
  226.         chr = nextChar();
  227.       if ( chr == EOFILE )
  228.         return( TRUE );
  229.       else {
  230.         chr = nextChar();
  231.         if ( chr == '/' )
  232.          break;
  233.       }
  234.     }
  235.     chr = nextChar( );
  236.   }
  237.  
  238.   IN.curChar = chr;
  239.   return( FALSE );
  240.  
  241. }  /* divChar */
  242.  
  243.  
  244. /****************************************************************************
  245. *  A char that should not occur in state 1.
  246. *****************************************************************************/
  247. STATE_ENTRY bogusChar( void )
  248. {
  249.  
  250.   printf( "unknown char '%c' in stream\n", IN.curChar );
  251.   IN.lastChar = IDCHAR;  /* must separate with white space */
  252.   IN.curChar = nextChar( );
  253.   return( TRUE );
  254.  
  255. }  /* bogusChar */
  256.  
  257. /****************************************************************************
  258. * End of file char.
  259. *****************************************************************************/
  260. STATE_ENTRY eofChar( void )
  261. {
  262.  
  263.   IN.curChar = nextChar( );
  264.   return( TRUE );
  265.  
  266. }  /* eofChar */
  267.  
  268.  
  269. /****************************************************************************
  270. * Read and dump the file.
  271. *****************************************************************************/
  272. BOOL processFiles( PFBUFFER in,
  273.                    PFBUFFER out )
  274. {
  275.  
  276. static BOOL (NEAR PASCAL *state[LAST_CHAR])(void) = {
  277.   bogusChar,  /* 0 */
  278.   bogusChar,  /* 1 */
  279.   bogusChar,  /* 2 */
  280.   bogusChar,  /* 3 */
  281.   bogusChar,  /* 4 */
  282.   bogusChar,  /* 5 */
  283.   bogusChar,  /* 6 */
  284.   bogusChar,  /* 7 */
  285.   bogusChar,  /* 8 */
  286.   whiteSpace, /* Tab */
  287.   whiteSpace, /* Line Feed, if in pair, sucked up by CR */
  288.   bogusChar,  /* 11 */
  289.   bogusChar,  /* 12 */
  290.   cariageReturn,  /* 13 */
  291.   bogusChar,  /* 14 */
  292.   bogusChar,  /* 15 */
  293.   bogusChar,  /* 16 */
  294.   bogusChar,  /* 17 */
  295.   bogusChar,  /* 18 */
  296.   bogusChar,  /* 19 */
  297.   bogusChar,  /* 20 */
  298.   bogusChar,  /* 21 */
  299.   bogusChar,  /* 22 */
  300.   bogusChar,  /* 23 */
  301.   bogusChar,  /* 24 */
  302.   bogusChar,  /* 25 */
  303.   eofChar,    /* Eof */
  304.   bogusChar,  /* 27 */
  305.   bogusChar,  /* 28 */
  306.   bogusChar,  /* 29 */
  307.   bogusChar,  /* 30 */
  308.   bogusChar,  /* 31 */
  309.   whiteSpace,  /* Blank */
  310.   opChar,      /* ! */
  311.   doubleQuote, /* " */
  312.   opChar,      /* # */
  313.   bogusChar,   /* $ */
  314.   opChar,      /* % */
  315.   opChar,      /* & */
  316.   opChar,      /* ' */
  317.   opChar,      /* ( */
  318.   opChar,      /* ) */
  319.   opChar,      /* * */
  320.   opChar,      /* + */
  321.   opChar,      /* , */
  322.   opChar,      /* - */
  323.   idChar,      /* . */
  324.   divChar,     /* / */
  325.   idChar,      /* 0 */
  326.   idChar,      /* 1 */
  327.   idChar,      /* 2 */
  328.   idChar,      /* 3 */
  329.   idChar,      /* 4 */
  330.   idChar,      /* 5 */
  331.   idChar,      /* 6 */
  332.   idChar,      /* 7 */
  333.   idChar,      /* 8 */
  334.   idChar,      /* 9 */
  335.   opChar,     /* : */
  336.   opChar,     /* ; */
  337.   opChar,     /* < */
  338.   opChar,     /* = */
  339.   opChar,     /* > */
  340.   opChar,     /* ? */
  341.   bogusChar,  /* @ */
  342.   idChar,  /* A */
  343.   idChar,  /* B */
  344.   idChar,  /* C */
  345.   idChar,  /* D */
  346.   idChar,  /* E */
  347.   idChar,  /* F */
  348.   idChar,  /* G */
  349.   idChar,  /* H */
  350.   idChar,  /* I */
  351.   idChar,  /* J */
  352.   idChar,  /* K */
  353.   idChar,  /* L */
  354.   idChar,  /* M */
  355.   idChar,  /* N */
  356.   idChar,  /* O */
  357.   idChar,  /* P */
  358.   idChar,  /* Q */
  359.   idChar,  /* R */
  360.   idChar,  /* S */
  361.   idChar,  /* T */
  362.   idChar,  /* U */
  363.   idChar,  /* V */
  364.   idChar,  /* W */
  365.   idChar,  /* X */
  366.   idChar,  /* Y */
  367.   idChar,  /* Z */
  368.   opChar,  /* [ */
  369.   opChar,  /* \ */
  370.   opChar,  /* ] */
  371.   opChar,  /* ^ */
  372.   idChar,  /* _ */
  373.   bogusChar,  /* ` */
  374.   idChar,  /* a */
  375.   idChar,  /* b */
  376.   idChar,  /* c */
  377.   idChar,  /* d */
  378.   idChar,  /* e */
  379.   idChar,  /* f */
  380.   idChar,  /* g */
  381.   idChar,  /* h */
  382.   idChar,  /* i */
  383.   idChar,  /* j */
  384.   idChar,  /* k */
  385.   idChar,  /* l */
  386.   idChar,  /* m */
  387.   idChar,  /* n */
  388.   idChar,  /* o */
  389.   idChar,  /* p */
  390.   idChar,  /* q */
  391.   idChar,  /* r */
  392.   idChar,  /* s */
  393.   idChar,  /* t */
  394.   idChar,  /* u */
  395.   idChar,  /* v */
  396.   idChar,  /* w */
  397.   idChar,  /* x */
  398.   idChar,  /* y */
  399.   idChar,  /* z */
  400.   opChar,  /* { */
  401.   opChar,  /* | */
  402.   opChar,  /* } */
  403.   opChar   /* ~ */
  404. };
  405.  
  406.   memcpy( &IN, in, sizeof(FBUFFER) );
  407.   memcpy( &OUT, out, sizeof(FBUFFER) );
  408.  
  409.   while ( IN.curChar < LAST_CHAR && (state[IN.curChar])() == FALSE ) ;
  410.  
  411.   if ( IN.curChar >= LAST_CHAR )
  412.     bogusChar();
  413.  
  414.     /* flush the buffer */
  415.   putChar( EOFILE );
  416.  
  417.   return( IN.curChar == EOFILE );
  418.  
  419. }  /* processFile */
  420.  
  421.