home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * Module : Lexical Analyzer --- Process the input text file into tokens
- * that the configuration file parser can understand.
- *
- * Routines : Lex() - Return the next token from the file.
- * OpenPrg - Open the back up program script file.
- *
- * Author : John W. M. Stevens
- ******************************************************************************/
-
- #include "compiler.h"
-
- #include "lex.h"
-
- /* Type definitions for this file. */
- typedef struct key_st {
- char c;
- TKNS val;
- struct key_st *branch;
- } KEY;
-
- /* Constants local to this file. */
- #define NOT_FND -2
-
- /* Object Data. */
- static char word[80]; /* Last string analyzed. */
- static int LnNo = 0; /* The current line number reading the script. */
- static FILE *PrgFl; /* Pointer to the ASCII file that contains the
- * backup program script.
- */
-
- /* Trie data structure containing all the keywords and punctuation marks for
- * the backup language.
- */
- static
- KEY T8[2] = {
- { ' ', 2, NULL },
- { 'e', T_ALTERNATE, NULL }
- };
-
- static
- KEY T7[2] = {
- { ' ', 2, NULL },
- { 't', 0, T8 }
- };
-
- static
- KEY T6[2] = {
- { ' ', 2, NULL },
- { 'a', 0, T7 }
- };
-
- static
- KEY T5[2] = {
- { ' ', 2, NULL },
- { 'n', 0, T6 }
- };
-
- static
- KEY T4[2] = {
- { ' ', 2, NULL },
- { 'r', 0, T5 }
- };
-
- static
- KEY T3[2] = {
- { ' ', 2, NULL },
- { 'e', 0, T4 }
- };
-
- static
- KEY T2[2] = {
- { ' ', 2, NULL },
- { 't', 0, T3 }
- };
-
- static
- KEY T1[2] = {
- { ' ', 2, NULL },
- { 'l', 0, T2 }
- };
-
- static
- KEY Tb[2] = {
- { ' ', 2, NULL },
- { 'y', T_BODY, NULL }
- };
-
- static
- KEY Ta[2] = {
- { ' ', 2, NULL },
- { 'd', 0, Tb }
- };
-
- static
- KEY T9[2] = {
- { ' ', 2, NULL },
- { 'o', 0, Ta }
- };
-
- static
- KEY Te[2] = {
- { ' ', 2, NULL },
- { 'e', T_CASE, NULL }
- };
-
- static
- KEY Td[2] = {
- { ' ', 2, NULL },
- { 's', 0, Te }
- };
-
- static
- KEY Tc[2] = {
- { ' ', 2, NULL },
- { 'a', 0, Td }
- };
-
- static
- KEY T13[2] = {
- { ' ', 2, NULL },
- { 'r', T_HEADER, NULL }
- };
-
- static
- KEY T12[2] = {
- { ' ', 2, NULL },
- { 'e', 0, T13 }
- };
-
- static
- KEY T11[2] = {
- { ' ', 2, NULL },
- { 'd', 0, T12 }
- };
-
- static
- KEY T10[2] = {
- { ' ', 2, NULL },
- { 'a', 0, T11 }
- };
-
- static
- KEY Tf[2] = {
- { ' ', 2, NULL },
- { 'e', 0, T10 }
- };
-
- static
- KEY T18[2] = {
- { ' ', 2, NULL },
- { 'e', T_IGNORE, NULL }
- };
-
- static
- KEY T17[2] = {
- { ' ', 2, NULL },
- { 'r', 0, T18 }
- };
-
- static
- KEY T16[2] = {
- { ' ', 2, NULL },
- { 'o', 0, T17 }
- };
-
- static
- KEY T15[2] = {
- { ' ', 2, NULL },
- { 'n', 0, T16 }
- };
-
- static
- KEY T14[3] = {
- { ' ', 3, NULL },
- { 'd', T_ID, NULL },
- { 'g', 0, T15 }
- };
-
- static
- KEY T1d[2] = {
- { ' ', 2, NULL },
- { 'r', T_NUMBER, NULL }
- };
-
- static
- KEY T1c[2] = {
- { ' ', 2, NULL },
- { 'e', 0, T1d }
- };
-
- static
- KEY T1b[2] = {
- { ' ', 2, NULL },
- { 'b', 0, T1c }
- };
-
- static
- KEY T1a[2] = {
- { ' ', 2, NULL },
- { 'm', 0, T1b }
- };
-
- static
- KEY T19[2] = {
- { ' ', 2, NULL },
- { 'u', 0, T1a }
- };
-
- static
- KEY T20[2] = {
- { ' ', 2, NULL },
- { 't', T_PART, NULL }
- };
-
- static
- KEY T1f[2] = {
- { ' ', 2, NULL },
- { 'r', 0, T20 }
- };
-
- static
- KEY T1e[2] = {
- { ' ', 2, NULL },
- { 'a', 0, T1f }
- };
-
- static
- KEY T27[2] = {
- { ' ', 2, NULL },
- { 's', T_SEGMENTS, NULL }
- };
-
- static
- KEY T26[2] = {
- { ' ', 2, NULL },
- { 't', T_SEGMENT, T27 }
- };
-
- static
- KEY T25[2] = {
- { ' ', 2, NULL },
- { 'n', 0, T26 }
- };
-
- static
- KEY T24[2] = {
- { ' ', 2, NULL },
- { 'e', 0, T25 }
- };
-
- static
- KEY T23[2] = {
- { ' ', 2, NULL },
- { 'm', 0, T24 }
- };
-
- static
- KEY T2d[2] = {
- { ' ', 2, NULL },
- { 'e', T_SENSITIVE, NULL }
- };
-
- static
- KEY T2c[2] = {
- { ' ', 2, NULL },
- { 'v', 0, T2d }
- };
-
- static
- KEY T2b[2] = {
- { ' ', 2, NULL },
- { 'i', 0, T2c }
- };
-
- static
- KEY T2a[2] = {
- { ' ', 2, NULL },
- { 't', 0, T2b }
- };
-
- static
- KEY T29[2] = {
- { ' ', 2, NULL },
- { 'i', 0, T2a }
- };
-
- static
- KEY T28[2] = {
- { ' ', 2, NULL },
- { 's', 0, T29 }
- };
-
- static
- KEY T22[3] = {
- { ' ', 3, NULL },
- { 'g', 0, T23 },
- { 'n', 0, T28 }
- };
-
- static
- KEY T31[2] = {
- { ' ', 2, NULL },
- { 'g', T_STRING, NULL }
- };
-
- static
- KEY T30[2] = {
- { ' ', 2, NULL },
- { 'n', 0, T31 }
- };
-
- static
- KEY T2f[2] = {
- { ' ', 2, NULL },
- { 'i', 0, T30 }
- };
-
- static
- KEY T2e[2] = {
- { ' ', 2, NULL },
- { 'r', 0, T2f }
- };
-
- static
- KEY T21[3] = {
- { ' ', 3, NULL },
- { 'e', 0, T22 },
- { 't', 0, T2e }
- };
-
- static
- KEY T35[2] = {
- { ' ', 2, NULL },
- { 'l', T_TOTAL, NULL }
- };
-
- static
- KEY T34[2] = {
- { ' ', 2, NULL },
- { 'a', 0, T35 }
- };
-
- static
- KEY T33[2] = {
- { ' ', 2, NULL },
- { 't', 0, T34 }
- };
-
- static
- KEY T32[2] = {
- { ' ', 2, NULL },
- { 'o', 0, T33 }
- };
-
- static
- KEY T0[12] = {
- { ' ', 12, NULL },
- { 'a', 0, T1 },
- { 'b', 0, T9 },
- { 'c', 0, Tc },
- { 'h', 0, Tf },
- { 'i', 0, T14 },
- { 'n', 0, T19 },
- { 'p', 0, T1e },
- { 's', 0, T21 },
- { 't', 0, T32 },
- { '{', T_L_BRACE, NULL },
- { '}', T_R_BRACE, NULL }
- };
-
- /*-----------------------------------------------------------------------------
- | Routine : TrieSrch() --- Search the trie for a token.
- |
- | Inputs : Keys - The trie level pointer.
- | ch - The current character to search for.
- | WordPtr - The pointer to the current byte of the word buffer.
- | Outputs : The token number or TKN_NOT_FND for not found.
- -----------------------------------------------------------------------------*/
-
- static
- int TrieSrch(KEY *Keys,
- int ch,
- char *WordPtr)
- {
- register int mid; /* Mid point of array piece. */
- register TKNS ret; /* Return value of comparison. */
-
- auto int lo; /* Limits of current array piece. */
- auto int hi;
-
- /* Make sure that input is lower case. */
- ch = tolower( ch );
-
- /* Search for a token. */
- hi = Keys[0].val - 1;
- lo = 1;
- do
- {
- /* Find mid point of current array piece. */
- mid = (lo + hi) >> 1;
-
- /* Do character comparison. */
- ret = ch - Keys[mid].c;
-
- /* Fix the array limits. */
- if (ret <= 0)
- hi = mid - 1;
- if (ret >= 0)
- lo = mid + 1;
-
- } while (hi >= lo);
-
- /* If the character matches one of the entries in this level and this
- * entry has a child, recurse. If a match is found but the matching
- * entry has no child, return the token value associated with the
- * match. If the return value from the recursive call indicates that
- * no match was found at a lower level, return the token value
- * associated with the match at this level of the trie.
- */
- if (ret == 0)
- {
- /* Save the current character. */
- *WordPtr++ = ch;
-
- /* Is this the last character in the string? */
- if ( Keys[mid].branch )
- {
- /* Get the next character. */
- if ((ch = fgetc( PrgFl )) == EOF)
- return( EOF );
-
- /* Search next level. */
- if ((ret = TrieSrch(Keys[mid].branch, ch, WordPtr)) == T_NOT_FND)
- {
- ungetc(ch, PrgFl);
- return( Keys[mid].val );
- }
- return( ret );
- }
- else
- {
- *WordPtr = '\0';
- return( Keys[mid].val );
- }
- }
-
- /* Return not found. */
- *WordPtr = '\0';
- return( T_NOT_FND );
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : Lex() --- Get the next key word from the input file.
- |
- | Outputs : sym - The symbolic data read from the file.
- |
- | Return : Returns the token read or EOF.
- -----------------------------------------------------------------------------*/
-
- int Lex(TOKEN *sym)
- {
- register int tkn;
- auto int ch;
- extern FILE *ErrFile;
-
- /* Strip comments and white space. If the character read is a '#',
- * every thing to the end of the line is a comment.
- */
- ch = fgetc( PrgFl );
- while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '#')
- {
- /* Process the special characters '#' and '\n'. */
- if (ch == '\n')
- LnNo++;
- else if (ch == '#')
- {
- while (fgetc( PrgFl ) != '\n')
- ;
- LnNo++;
- }
-
- /* Get the next character. */
- ch = fgetc( PrgFl );
- }
-
- /* Get strings, etc. */
- if (ch == '"')
- {
- auto char *bf;
-
- /* Get contents of string. */
- bf = sym->str;
- while ((ch = fgetc( PrgFl )) != '"' && ch != EOF)
- *bf++ = ch;
- *bf = '\0';
-
- /* Return string token. */
- return( T_DBL_QUOTE );
- }
- else if (ch >= '0' && ch <= '9')
- {
- /* Get the number. */
- sym->no = 0;
- do
- {
- sym->no = sym->no * 10 + (ch - '0');
- } while ((ch = fgetc( PrgFl )) >= '0' && ch <= '9');
-
- /* Return the unused character. */
- ungetc(ch, PrgFl);
- return( T_INT_NO );
- }
- else if (ch == EOF)
- return( EOF );
-
- /* Call the trie search routine to return the next token, EOF
- * or NOT_FND. If not found, print an error and quit.
- */
- if ((tkn = TrieSrch(T0, ch, word)) == T_NOT_FND || tkn == 0)
- {
- fprintf(ErrFile,
- "%s %d : Error - cannot identify string '%s' ",
- __FILE__,
- __LINE__,
- word);
- fprintf(ErrFile,
- "in line %d\n",
- LnNo + 1);
- exit( 1 );
- }
-
- /* Return the token found. */
- return( tkn );
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : OpenCfg() --- Open the ASCII text file that contains the
- | configuration data.
- -----------------------------------------------------------------------------*/
-
- void OpenCfg(char *FileNm)
- {
- extern FILE *ErrFile;
-
- /* Open the program script file. */
- if ((PrgFl = fopen(FileNm, TXT_READ)) == NULL)
- {
- fprintf(ErrFile,
- "%s %d : Error - %s\n",
- __FILE__,
- __LINE__,
- sys_errlist[errno]);
- fprintf(ErrFile,
- "\tFile Name: '%s'\n",
- FileNm);
- exit( 1 );
- }
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : CloseCfg() --- Close the ASCII text file that contains the
- | configuration data.
- -----------------------------------------------------------------------------*/
-
- void CloseCfg(void)
- {
- fclose( PrgFl );
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : ParseErr() --- Report a parse error.
- |
- | Inputs : ErrStr - The error string.
- -----------------------------------------------------------------------------*/
-
- void ParseErr(char *ErrStr)
- {
- extern FILE *ErrFile;
-
- fprintf(ErrFile,
- "%s %d : Error - %s\n",
- __FILE__,
- __LINE__,
- ErrStr);
- fprintf(ErrFile,
- "\tLine %d, word '%s'\n",
- LnNo + 1,
- word);
- exit( 1 );
- }
-