G:/ScriptBasic/source/lexer.c

Go to the documentation of this file.
00001 /*
00002 FILE:   lexer.c
00003 HEADER: lexer.h
00004 
00005 --GNU LGPL
00006 This library is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU Lesser General Public
00008 License as published by the Free Software Foundation; either
00009 version 2.1 of the License, or (at your option) any later version.
00010 
00011 This library is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 Lesser General Public License for more details.
00015 
00016 You should have received a copy of the GNU Lesser General Public
00017 License along with this library; if not, write to the Free Software
00018 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 TO_HEADER:
00021 
00022 enum LexemeType {
00023   LEX_T_DOUBLE = 1,
00024   LEX_T_LONG,
00025   LEX_T_STRING,
00026   LEX_T_ASYMBOL,
00027   LEX_T_NSYMBOL,
00028   LEX_T_CHARACTER,
00029 
00030   LEX_T_SKIP,   //special type that a preprocessor 
00031                 //may set to tell the lexical analyzer to ignore the lexical element
00032   LEX_T_SKIP_SYMBOL,
00033 
00034   LEX_T_DUMMY
00035   };
00036 
00037 
00038 typedef struct _Lexeme {
00039   enum LexemeType type;   // type of the lexeme
00040   union {
00041     double dValue;        // double value
00042     long   lValue;        // long value
00043     char  *sValue;        // string or symbol value
00044     } value;
00045   long sLen;              //length of string or symbol
00046   char *szFileName;       // where the lexeme is
00047   long lLineNumber;       // where the lexeme is
00048   struct _Lexeme *next;   // link to the next lexeme
00049   }Lexeme, *pLexeme;
00050 
00051 typedef struct _LexNASymbol {
00052   char *Symbol;
00053   int Code;
00054   } LexNASymbol, *pLexNASymbol;
00055 
00056 typedef struct _LexObject {
00057   int (*pfGetCharacter)(void *); // returns the next character from the input stream
00058   char * (*pfFileName)(void *);  // returns a pointer to the file name that the last character came from
00059   long (*pfLineNumber)(void *);  // returns the line number of the line that the last character came from
00060   void *pvInput;
00061   void *(*memory_allocating_function)(size_t, void *);
00062   void (*memory_releasing_function)(void *, void *);
00063   void *pMemorySegment; // This variable is always passed to the memory functions
00064 
00065   char *SSC;  // Start Symbol Character
00066   char *SCC;  // Symbol Continuation Character
00067   char *SFC;  // Symbol Final Character
00068   char *SStC; // Start String Character
00069   char *SKIP; // characters to be skipped
00070               // (though they are symbol terminators and valid in strings)
00071               // this is usually space and tab
00072 // Escape replacements. The first character is the escape character and
00073 // for each odd n the nth character is the replacement for the (n-1)th character
00074   char *ESCS;
00075   long fFlag;
00076 
00077   pReportFunction report;
00078   void *reportptr; // this pointer is passed to the report function. The caller should set it.
00079   int iErrorCounter;
00080   unsigned long fErrorFlags;
00081 
00082   char *buffer;  // should point to a buffer of size
00083   long cbBuffer; //                     this number of bytes
00084 
00085   pLexNASymbol pNASymbols; // Array of non alpha symbols
00086   int cbNASymbolLength;    // the longest Non Alpha Symbol length including the final zchar
00087 
00088   pLexNASymbol pASymbols;  // Array of tokenizable alpha symbols
00089 
00090   pLexNASymbol pCSymbols;  // Array of command symbols for debug purposes (used by ex_pprint via lex_SymbolicName)
00091 
00092   pLexeme pLexResult;      // list of tokens
00093   pLexeme pLexCurrentLexeme; // the actual lexeme
00094   struct _PreprocObject *pPREP;
00095   }LexObject, *pLexObject;
00096 
00097 #define LEX_PROCESS_STRING_NUMBER         0x01
00098 #define LEX_PROCESS_STRING_OCTAL_NUMBER   0x02
00099 #define LEX_ASYMBOL_CASE_SENSITIVE        0x04
00100 #define LEX_PROCESS_STRING_HEX_NUMBER     0x08
00101 */
00102 
00103 #include <stdio.h>
00104 #include <stdlib.h>
00105 #include <ctype.h>
00106 #include <string.h>
00107 
00108 #include "errcodes.h"
00109 #include "report.h"
00110 
00111 /* if you do not have this file use headerer.pl to extract from this one */
00112 #include "lexer.h"
00113 #include "ipreproc.h"
00114 
00115 /*POD
00116 
00117 This module contains the functions and structures that are used by ScriptBasic to perform
00118 lexical analysis of the source code. The module was originally developed for ScriptBasic
00119 but was developed to be general enough to be used in other projects.
00120 
00121 CUT*/
00122 #define BUFFERINCREASE 1024
00123 
00124 #if (!defined(_WIN32) && !defined(__MACOS__))
00125 int stricmp(char *,char*);
00126 #endif
00127 
00128 #define REPORT(x1,x2,x3,x4) if( pLex->report )pLex->report(pLex->reportptr,x1,x2,x3,REPORT_ERROR,&(pLex->iErrorCounter),x4,&(pLex->fErrorFlags))
00129 
00130 #define CALL_PREPROCESSOR(X,Y) if( pLex->pPREP && pLex->pPREP->n )ipreproc_Process(pLex->pPREP,X,Y)
00131 
00132 static isinset(int ch,char *string){
00133    while( ch != *string && *++string );
00134    return *string;
00135 }
00136 
00137 static double pow10(double a)
00138 {
00139    int j,i;
00140    double pro,k;
00141 
00142    for( (i= a<0.0) && (a = -a) , j=(int)a , pro=1.0 , k=10; j ;
00143        j%2 && (pro *=k) , j /= 2 , k *= k )
00144       continue;
00145    i && (pro=1.0/pro);
00146    return pro;
00147 }
00148 
00149 static int __GETC(int (*pfGetCharacter)(void *),
00150                 void *pvInput,
00151                 int *UngetBuffer,
00152                 int *UngetCounter
00153                ){
00154   if( *UngetCounter ){
00155     (*UngetCounter) --;
00156     return UngetBuffer[*UngetCounter];
00157     }
00158   return pfGetCharacter(pvInput);
00159   }
00160 
00161 static void __UNGETC(int *UngetBuffer,
00162               int *UngetCounter,
00163               int ch
00164              ){
00165   UngetBuffer[(*UngetCounter)++] = ch;
00166   }
00167 
00168 /* these macroes help to call the local get and unget functions */
00169 /* note that these macros are safe and should be (i.e.: UNGETC(buffer[i--]) )*/
00170 #define GETC() __GETC(pLex->pfGetCharacter,pLex->pvInput,UngetBuffer,&UngetCounter)
00171 #define UNGETC(x) __UNGETC(UngetBuffer,&UngetCounter,x)
00172 #define UNGET_BUFFER_LENGTH 10 /* more than enough */
00173 
00174 #define lexALLOC(x) (pLex->memory_allocating_function((x),pLex->pMemorySegment))
00175 #define lexFREE(x) (pLex->memory_releasing_function((x),pLex->pMemorySegment),(x)=NULL)
00176 
00177 /* allocate a new lexeme safely initialized */
00178 static pLexeme _NewLexeme(pLexObject pLex){
00179   pLexeme p;
00180   p = (pLexeme)lexALLOC(sizeof(Lexeme));
00181   if( p ){
00182     p->sLen = 0;
00183     p->value.lValue = 0;
00184     p->szFileName = NULL;
00185     p->lLineNumber = 0;
00186     p->next = NULL;
00187     }
00188   return p;
00189   }
00190 #define NewLexeme() _NewLexeme(pLex)
00191 
00192 /*POD
00193 =H lex_SymbolicName()
00194 
00195 This function usually is for debug purposes. This searches the
00196 table of the predefined symbols and returns the string which is
00197 the predefined symbols for which the code was passsed.
00198 /*FUNCTION*/
00199 char *lex_SymbolicName(pLexObject pLex,
00200                        long OpCode
00201   ){
00202 /*noverbatim
00203 CUT*/
00204   pLexNASymbol p;
00205 
00206   p = pLex->pNASymbols;
00207   while( p->Symbol && p->Code != OpCode )
00208     p++;
00209   if( p->Symbol )return p->Symbol;
00210 
00211   p = pLex->pASymbols;
00212   while( p->Symbol && p->Code != OpCode )
00213     p++;
00214   if( p->Symbol )return p->Symbol;
00215 
00216   p = pLex->pCSymbols;
00217   while( p->Symbol && p->Code != OpCode )
00218     p++;
00219   if( p->Symbol )return p->Symbol;
00220 
00221   return "INTERNAL ERROR";
00222   }
00223 
00224 /*POD
00225 =H lex_HandleContinuationLines()
00226 
00227 This function is called from the main function before syntax analysis is started. 
00228 This function handles the usual basic continuation lines. If the last character on a 
00229 line is a _ character, which is either recognised during lexical analysis as a 
00230 character or as a symbol then this lexical element and the following new-line character
00231 token is removed from the list of tokens.
00232 
00233 /*FUNCTION*/
00234 void lex_HandleContinuationLines(pLexObject pLex
00235   ){
00236 /*noverbatim
00237 CUT*/
00238   pLexeme *p,r;
00239 
00240   p = &(pLex->pLexResult);
00241   while( *p ){
00242     if( *p && (
00243         ((*p)->type == LEX_T_CHARACTER && (*p)->value.lValue == '_')
00244                            ||
00245         ((*p)->type == LEX_T_ASYMBOL && *(*p)->value.sValue == '_' && (*p)->value.sValue[1] == (char)0)
00246         )
00247         && (*p)->next && (*p)->next->type == LEX_T_CHARACTER && (*p)->next->value.lValue == '\n' ){
00248       r = *p;
00249       *p = (*p)->next->next;
00250       lexFREE(r->next);
00251       lexFREE(r);
00252       }else
00253       p = &((*p)->next);
00254     }
00255   }
00256 
00257 /*POD
00258 =H lex_RemoveSkipSymbols()
00259 
00260 This function is called from R<lex_DoLexicalAnalysis()> to remove the lexical elements
00261 from the list of tokens that were denoted by the preprocessors to be deleted.
00262 
00263 Some lexical elements are used to give information to some of the preprocessors. These
00264 tokens should be deleted, because later processing can not deal with them and confuses syntax
00265 analysis.
00266 
00267 In those cases the preprocessor should set the type of the token to be LT<LEX_T_SKIP> or
00268 T<LEX_T_SKIP_SYMBOL>. The type T<LEX_T_SKIP> should be used in case the token is handled due to
00269 T<ProcessLexSymbol> preprocessor command and T<LEX_T_SKIP> otherwise.
00270 
00271 When the type is set T<LEX_T_SKIP_SYMBOL> the lexical analyzer knows to release the string holding
00272 the symbol. If the type is T<LEX_T_SKIP> only the token record is released.
00273 
00274 If the symbol string is not released due to erroneously setting the type to T<LEX_T_SKIP> instead
00275 T<LEX_T_SKIP_SYMBOL> the memory will not be released until the interpreter finishes pre execution
00276 steps. So usually if you do not know how to set the type to skip a token T<LEX_T_SKIP> is safe.
00277 
00278 /*FUNCTION*/
00279 void lex_RemoveSkipSymbols(pLexObject pLex
00280   ){
00281 /*noverbatim
00282 CUT*/
00283   pLexeme *p,r;
00284 
00285   p = &(pLex->pLexResult);
00286   while( *p ){
00287     if( *p && ((*p)->type == LEX_T_SKIP || (*p)->type == LEX_T_SKIP_SYMBOL)){
00288       r = *p;
00289       *p = (*p)->next;
00290       if( (*p)->type == LEX_T_SKIP_SYMBOL )lexFREE(r->value.sValue);
00291       lexFREE(r);
00292       }else
00293       p = &((*p)->next);
00294     }
00295   }
00296 
00297 /*POD
00298 =H lex_RemoveComments()
00299 
00300 This function called from the function R<lex_DoLexicalAnalysis()> function to remove the comments before the 
00301 syntax analysis starts.
00302 
00303 It should be called before calling the continuation line handling because usually REM
00304 lines are not continuable
00305 /*FUNCTION*/
00306 void lex_RemoveComments(pLexObject pLex
00307   ){
00308 /*noverbatim
00309 CUT*/
00310   pLexeme *p,r,q,*w;
00311 
00312   p = &(pLex->pLexResult);
00313   while( *p ){
00314     if( ((*p)->type == LEX_T_ASYMBOL && !stricmp((*p)->value.sValue,"rem") )   ||
00315         ((*p)->type == LEX_T_CHARACTER && (*p)->value.lValue == '\''       )   ||
00316         ((*p)->type == LEX_T_ASYMBOL && *(*p)->value.sValue == '\'' && (*p)->value.sValue[1] == (char)0)
00317       ){
00318       r = (*p);
00319       w = p;
00320       while( (*p) && ( (*p)->type != LEX_T_CHARACTER || (*p)->value.lValue != '\n') )
00321         p=&((*p)->next);
00322       if( *p )p=&((*p)->next);
00323       *w = *p;
00324       p = w;
00325       while( r && r->next && (r->next->type != LEX_T_CHARACTER || r->next->value.lValue != '\n') ){
00326         q=r;
00327         r = r->next;
00328         lexFREE(q);
00329         }
00330       }else{
00331       while( (*p) && (*p)->type != LEX_T_CHARACTER && (*p)->value.lValue != '\n' )p=&((*p)->next);
00332       if( *p )p=&((*p)->next);
00333       }
00334     }
00335   }
00336 
00337 /*POD
00338 =H lex_NextLexeme()
00339 
00340 Use this function during iteration to get the next lexeme from the list of lexemes.
00341 
00342 /*FUNCTION*/
00343 void lex_NextLexeme(pLexObject pLex
00344   ){
00345 /*noverbatim
00346 CUT*/
00347   if( pLex->pLexCurrentLexeme )/* allow sloppy call at the end of the file */
00348     pLex->pLexCurrentLexeme = pLex->pLexCurrentLexeme->next;
00349   }
00350 
00351 /*POD
00352 =H lex_SavePosition()
00353 
00354 Use this function to save the current position of the iteration. This is neccessary during
00355 syntactical analysis to return to a certain position when syntactical analysis fails and
00356 the program has to go back and try a different command syntax.
00357 
00358 /*FUNCTION*/
00359 void lex_SavePosition(pLexObject pLex,
00360                       pLexeme *ppPosition
00361   ){
00362 /*noverbatim
00363 
00364 The second argument is a T<pLexeme *> type variable that holds the position and should be passed
00365 as argument to the function R<lex_RestorePosition()>.
00366 CUT*/
00367   *ppPosition = pLex->pLexCurrentLexeme;
00368   }
00369 
00370 /*POD
00371 =H lex_RestorePosition()
00372 
00373 Use this function to restore the lexeme position that was saved calling the function R<lex_SavePosition()>
00374 
00375 /*FUNCTION*/
00376 void lex_RestorePosition(pLexObject pLex,
00377                          pLexeme *ppPosition
00378   ){
00379 /*noverbatim
00380 CUT*/
00381   pLex->pLexCurrentLexeme = *ppPosition;
00382   }
00383 
00384 /*POD
00385 =H lex_StartIteration()
00386 
00387 You should call this function when the list of lexemes was built up before starting the iteration
00388 of the syntax analyzer. This function sets the iteration pointer to the first lexeme.
00389 
00390 /*FUNCTION*/
00391 void lex_StartIteration(pLexObject pLex
00392   ){
00393 /*noverbatim
00394 CUT*/
00395   pLex->pLexCurrentLexeme = pLex->pLexResult;
00396   }
00397 
00398 /*POD
00399 =H lex_EOF()
00400 
00401 Call this function to check if the iteration has reached the last lexeme.
00402 
00403 /*FUNCTION*/
00404 int lex_EOF(pLexObject pLex
00405   ){
00406 /*noverbatim
00407 CUT*/
00408   return pLex->pLexCurrentLexeme == NULL;
00409   }
00410 
00411 /*POD
00412 =H lex_Type()
00413 
00414 During lexeme iteration this function can be used to retrieve the typeof the current lexeme. The
00415 type of a lexeme can be:
00416 
00417 =itemize
00418 =item T<LEX_T_DOUBLE> a double value. A number which is not integer.
00419 =item T<LEX_T_LONG> an long value. A number which is integer.
00420 =item T<LEX_T_STRING> a string.
00421 =item T<LEX_T_ASYMBOL> an alpha symbol, like a variable. This symbol is not predefined. The value
00422 of the lexeme is the string of the symbol.
00423 =item T<LEX_T_NSYMBOL> a predefined symbol. The actual value of the lexeme is the token value
00424 of the symbol. If you wan to get the actual string of the symbol you have to call the function
00425 R<lex_SymbolicName()>.
00426 =item T<LEX_T_CHARACTER> A character that is not a predefined symbol and does not fit into any string.
00427 =noitemize
00428 
00429 /*FUNCTION*/
00430 int lex_Type(pLexObject pLex
00431   ){
00432 /*noverbatim
00433 CUT*/
00434   return pLex->pLexCurrentLexeme->type;
00435   }
00436 
00437 /*POD
00438 =H lex_Double()
00439 
00440 When the type of the current lexeme is T<LEX_T_DOUBLE> during the lexeme iteration
00441 this function should be used to retrieve the actual value of the current lexeme.
00442 
00443 /*FUNCTION*/
00444 double lex_Double(pLexObject pLex
00445 /*noverbatim
00446 CUT*/
00447   ){
00448   return pLex->pLexCurrentLexeme->value.dValue;
00449   }
00450 
00451 /*POD
00452 =H lex_String()
00453 
00454 When the type of the current lexeme is T<LEX_T_STRING> during the lexeme iteration
00455 this function should be used to retrieve the actual value of the current lexeme.
00456 /*FUNCTION*/
00457 char *lex_String(pLexObject pLex
00458   ){
00459 /*noverbatim
00460 CUT*/
00461   return pLex->pLexCurrentLexeme->value.sValue;
00462   }
00463 
00464 /*POD
00465 =H lex_StrLen()
00466 
00467 When the type of the current lexeme is T<LEX_T_STRING> during the lexeme iteration
00468 this function should be used to retrieve the length of the current lexeme. This is
00469 more accurate than calling T<strlen> on the actual string because the string itself may
00470 contain zero characters.
00471 /*FUNCTION*/
00472 long lex_StrLen(pLexObject pLex
00473   ){
00474 /*noverbatim
00475 CUT*/
00476   return pLex->pLexCurrentLexeme->sLen;
00477   }
00478 
00479 /*POD
00480 =H lex_Long()
00481 
00482 When the type of the current lexeme is T<LEX_T_LONG> during the lexeme iteration
00483 this function should be used to retrieve the actual value of the current lexeme.
00484 
00485 /*FUNCTION*/
00486 long lex_Long(pLexObject pLex
00487   ){
00488 /*noverbatim
00489 CUT*/
00490   return pLex->pLexCurrentLexeme->value.lValue;
00491   }
00492 
00493 /*POD
00494 =H lex_LineNumber()
00495 
00496 This function returns the line number that the actual lexeme is in the source file.
00497 This function is needed to print out syntax and lexical error messages.
00498 
00499 See also R<lex_FileName()>.
00500 /*FUNCTION*/
00501 long lex_LineNumber(pLexObject pLex
00502   ){
00503 /*noverbatim
00504 CUT*/
00505   if( pLex->pLexCurrentLexeme )
00506     return pLex->pLexCurrentLexeme->lLineNumber;
00507   return 0L;
00508   }
00509 
00510 /*POD
00511 =H lex_FileName()
00512 
00513 This function returns a pointer to a constant string which is the file name
00514 that the lexeme was read from. Use this function to print out error messages when
00515 syntax or lexical error occures.
00516 
00517 See also R<lex_LineNumber()>.
00518 /*FUNCTION*/
00519 char *lex_FileName(pLexObject pLex
00520   ){
00521 /*noverbatim
00522 CUT*/
00523   if( pLex->pLexCurrentLexeme )
00524     return pLex->pLexCurrentLexeme->szFileName;
00525   return "";
00526   }
00527 
00528 /*POD
00529 =H lex_XXX()
00530 
00531 These access functions are implemented as macros and are put into <lexer.h> by the program T<headerer.pl>
00532 
00533 The macros access T<Int>, T<Symbol>, T<Float> etc values of the current lexeme. However these are strored
00534 in a location which is named a bit different. For example the string of a symbol is stored in the string
00535 field of the lexeme. To be readable and to be compatible with future versions use these macros to access
00536 lexeme values when lexeme has any of these types.
00537 
00538 =verbatim
00539 /*
00540 TO_HEADER:
00541 #define lex_Int(x) lex_Long(x)
00542 #define lex_Symbol(x) lex_String(x)
00543 #define lex_Float(x) lex_Double(x)
00544 #define lex_Char(x) lex_Long(x)
00545 #define lex_Token(x) lex_Long(x)
00546 #define lex_Code(x) lex_Long(x)
00547 */
00548 /*
00549 =noverbatim
00550 CUT*/
00551 
00552 /*POD
00553 =H lex_Finish()
00554 
00555 Call this functionto release all memory allocated by the lexical analyzer.
00556 
00557 /*FUNCTION*/
00558 void lex_Finish(pLexObject pLex
00559   ){
00560 /*noverbatim
00561 CUT*/
00562   pLexeme p,r;
00563 
00564   p = pLex->pLexResult;
00565   while( p ){
00566     r = p->next;
00567     switch( p->type ){
00568       case LEX_T_STRING:
00569       case LEX_T_ASYMBOL:
00570         lexFREE(p->value.sValue);
00571       case LEX_T_DOUBLE:
00572       case LEX_T_NSYMBOL:
00573       case LEX_T_CHARACTER:
00574       case LEX_T_LONG:
00575         lexFREE(p);
00576       }
00577     p = r;
00578     }
00579   }
00580 
00581 /*POD
00582 =H lex_DumpLexemes()
00583 
00584 Us this function for debugging. This function dumps the list of lexemes to the file T<psDump>.
00585 
00586 /*FUNCTION*/
00587 void lex_DumpLexemes(pLexObject pLex,
00588                      FILE *psDump
00589   ){
00590 /*noverbatim
00591 CUT*/
00592 
00593   lex_StartIteration(pLex);
00594   while( !lex_EOF(pLex) ){
00595     fprintf(psDump,"%s(%ld) ",pLex->pLexCurrentLexeme->szFileName,pLex->pLexCurrentLexeme->lLineNumber);
00596     switch( lex_Type(pLex) ){
00597       case LEX_T_DOUBLE:
00598         fprintf(psDump,"Double %f\n",lex_Double(pLex));
00599         break;
00600       case LEX_T_LONG:
00601         fprintf(psDump,"Long %d\n",lex_Long(pLex));
00602         break;
00603       case LEX_T_STRING:
00604         fprintf(psDump,"String %s\n",lex_String(pLex));
00605         break;
00606       case LEX_T_ASYMBOL:
00607         fprintf(psDump,"Symbol %s\n",lex_Symbol(pLex));
00608         break;
00609       case LEX_T_NSYMBOL:
00610         fprintf(psDump,"NAsymb %d\n",lex_Token(pLex));
00611         break;
00612       case LEX_T_CHARACTER:
00613         if( lex_Char(pLex) == '\n' ){
00614           fprintf(psDump,"Charac NewLine\n");
00615           break;
00616           }
00617         if( lex_Char(pLex) == '\t' ){
00618           fprintf(psDump,"Charac Tab\n");
00619           break;
00620           }
00621         if( lex_Char(pLex) == '\r' ){
00622           fprintf(psDump,"Charac CR\n");
00623           break;
00624           }
00625         fprintf(psDump,"Charac %c\n",lex_Char(pLex));
00626         break;
00627        }
00628     lex_NextLexeme(pLex);
00629     }
00630   }
00631 
00632 static void lex_StoreCharacter(pLexObject pLex, int ch, int i){
00633   char *s,*r;
00634   int NewBufferSize;
00635 
00636   while( i >= pLex->cbBuffer-1 ){
00637     NewBufferSize = BUFFERINCREASE + pLex->cbBuffer;
00638     s = lexALLOC(NewBufferSize*sizeof(char));
00639     if( s == NULL ){
00640       pLex->report(pLex->reportptr,
00641                    pLex->pfFileName(pLex->pvInput),
00642                    pLex->pfLineNumber(pLex->pvInput),
00643                    LEX_ERROR_MEMORY_LOW,
00644                    REPORT_ERROR,&(pLex->iErrorCounter),
00645                    pLex->buffer,&(pLex->fErrorFlags));
00646     return;
00647     }
00648     memcpy(s,pLex->buffer,pLex->cbBuffer);
00649     pLex->cbBuffer = NewBufferSize;
00650     r = pLex->buffer;
00651     pLex->buffer = s;
00652     lexFREE(r);
00653     }
00654   pLex->buffer[i] = ch;
00655   }
00656 
00657 /*POD
00658 =H lex_ReadInput()
00659 
00660 Call this function after proper initialization to read the input file. This function performs the laxical analysis and
00661 builds up an internal linked list that contains the lexemes.
00662 
00663 /*FUNCTION*/
00664 int lex_ReadInput(pLexObject pLex
00665   ){
00666 /*noverbatim
00667 CUT*/
00668   double intpart,fracpart,exppart,man;
00669   long hintpart; /* for hexadecimal calculation */
00670   int esig,ibase;
00671   int nch,ch,i,cStringStartCharacter,iErrorWasReported;
00672   pLexeme *plexLastLexeme;
00673   int UngetCounter,StringIsBinary;
00674   int *UngetBuffer;
00675   char *s;
00676   char *pszFileName;
00677   long lLineNumber;
00678   pLexNASymbol pNA;
00679   int iResult;
00680 
00681   UngetCounter = 0; /* init the local unget counter */
00682   /* allocate unget size which is capable ungetting all symbol characters if a "symbol" contains only
00683      characters that can not be final character */
00684   UngetBuffer = (int *)lexALLOC(pLex->cbBuffer*sizeof(int));
00685 
00686   pNA = pLex->pNASymbols;
00687 
00688   if( ! pNA )pLex->cbNASymbolLength = 1;
00689 
00690   /* calculate the length of the longest non-alphanumeric symbol length */
00691   if ( !pLex->cbNASymbolLength )
00692     while( pNA->Symbol ){
00693       if( (i=strlen(pNA->Symbol)) > pLex->cbNASymbolLength )
00694         pLex->cbNASymbolLength = i;
00695       pNA++;
00696       }
00697 
00698   pLex->cbNASymbolLength++; /* count the trailing zchar */
00699 
00700 /* for readability  we define this 'variable' */
00701 #define pfLexeme (*plexLastLexeme)
00702 
00703   pLex->pLexResult = NULL;
00704   plexLastLexeme = &(pLex->pLexResult);
00705   while( (ch = GETC()) != EOF ){
00706 
00707     /*** Skip spaces if we do not care spaces ***/
00708     while( isinset(ch,pLex->SKIP) )ch = GETC();
00709 
00710     pszFileName = pLex->pfFileName(pLex->pvInput);
00711     lLineNumber = pLex->pfLineNumber(pLex->pvInput);
00712 
00713     /*** PROCESS A SYMBOL ***/
00714 
00715     if( isinset(ch,pLex->SSC) ){
00716       for( i = 0 ; i < pLex->cbBuffer-1 && isinset(ch,pLex->SCC) ;i++ )
00717         (pLex->buffer[i] = ch) , (ch = GETC());
00718       if( i == pLex->cbBuffer-1 ){
00719          pLex->buffer[pLex->cbBuffer-1] = (char)0;
00720          while( isinset(ch,pLex->SCC) )ch = GETC();
00721          REPORT(pszFileName,lLineNumber,LEX_ERROR_TOO_LONG_SYMBOL,pLex->buffer);
00722          }
00723       UNGETC(ch);
00724       while( i && ! isinset(pLex->buffer[i-1],pLex->SFC) ){
00725         i--;
00726         UNGETC(pLex->buffer[i]);
00727         }
00728       if( i ){/* if there remained at least one characters in the symbol after
00729                  ungetching the final characters that should not appear
00730                  as final character */
00731         pLex->buffer[i++]=(char)0;
00732 
00733         /* try to look up the symbol in the alpha symbol list */
00734         if( pNA = pLex->pASymbols ){
00735           while( pNA->Symbol && 
00736                   ( (pLex->fFlag&LEX_ASYMBOL_CASE_SENSITIVE) ? 
00737                                      strcmp(pLex->buffer,pNA->Symbol) : 
00738                                      stricmp(pLex->buffer,pNA->Symbol) )
00739             ) pNA++;
00740           if( pNA->Symbol ){/* symbol is found */
00741             if( (pfLexeme = NewLexeme()) == NULL ){
00742               lexFREE(UngetBuffer);
00743               return LEX_ERROR_MEMORY_LOW;
00744               }
00745             pfLexeme->type = LEX_T_NSYMBOL;
00746             pfLexeme->value.lValue = pNA->Code;
00747             pfLexeme->lLineNumber = lLineNumber;
00748             pfLexeme->szFileName = pszFileName;
00749             if( pLex->pPREP && pLex->pPREP->n ){
00750               iResult = ipreproc_Process(pLex->pPREP,PreprocessorLexASymbol,&plexLastLexeme);
00751               if( iResult )return iResult;
00752               }
00753             plexLastLexeme = &(pfLexeme->next);
00754             continue;
00755             }
00756           }
00757 
00758         if( (pfLexeme = NewLexeme()) == NULL ){
00759           lexFREE(UngetBuffer);
00760           return LEX_ERROR_MEMORY_LOW;
00761           }
00762         pfLexeme->next = NULL;
00763         pfLexeme->type = LEX_T_ASYMBOL;
00764         pfLexeme->lLineNumber = lLineNumber;
00765         pfLexeme->szFileName = pszFileName;
00766         if( (pfLexeme->value.sValue = (char *)lexALLOC(i)) == NULL ){
00767           lexFREE(UngetBuffer);
00768           return LEX_ERROR_MEMORY_LOW;
00769           }
00770         strcpy(pfLexeme->value.sValue,pLex->buffer);
00771         if( pLex->pPREP && pLex->pPREP->n ){
00772           iResult = ipreproc_Process(pLex->pPREP,PreprocessorLexSymbol,&plexLastLexeme);
00773           if( iResult )return iResult;
00774           }
00775         plexLastLexeme = &(pfLexeme->next);
00776         continue;
00777         }else{
00778         ch = GETC(); /* we have ungetched the last character when we checked the last character of the symbol */
00779         }
00780       }
00781 /* Store a string if there is space and report error at first occasion when string is too long. */
00782 #define STORE_CH(x) lex_StoreCharacter(pLex,x,i)
00783 
00784     /*** PROCESS A STRING ***/
00785 
00786     if( isinset(ch,pLex->SStC) ){
00787       cStringStartCharacter = ch;
00788       ch = GETC();
00789       if( ch != cStringStartCharacter ){
00790         UNGETC(ch);
00791         ch = cStringStartCharacter;
00792         goto SimpleString;
00793         }
00794       nch = GETC();
00795       if( nch != cStringStartCharacter ){
00796         UNGETC(nch);
00797         UNGETC(ch);
00798         ch = cStringStartCharacter;
00799         goto SimpleString;
00800         }
00801       /* PROCESS A MULTILINE STRING */
00802       i = 1;
00803       ch = GETC();
00804       if( StringIsBinary = (ch == '&') )ch = GETC();
00805       iErrorWasReported = 0;
00806       for( i = 0 ; ch != EOF ; i++ ){
00807         while( StringIsBinary && ch == '\n' && ch != EOF )ch = GETC();
00808         if( ch == EOF )break;
00809         if( ch == cStringStartCharacter ){
00810           ch = GETC();
00811           if( ch == cStringStartCharacter ){
00812             nch = GETC();
00813             if( nch == cStringStartCharacter )break;
00814             UNGETC(nch);
00815             }
00816           UNGETC(ch);
00817           ch = cStringStartCharacter;
00818           }
00819         if( ch == *(pLex->ESCS) ){
00820           ch = GETC();
00821           
00822           if( ((pLex->fFlag&LEX_PROCESS_STRING_NUMBER) && isdigit(ch)) ||
00823               ((pLex->fFlag&LEX_PROCESS_STRING_NUMBER) &&  (pLex->fFlag&LEX_PROCESS_STRING_HEX_NUMBER) && ch == 'x') ){
00824             esig = 0;
00825             /* choose the radix */
00826             if( ch == 'x' ){ch = GETC();ibase = 16; }else
00827               if( (pLex->fFlag&LEX_PROCESS_STRING_OCTAL_NUMBER) && ch == '0' )ibase = 8; 
00828                 else ibase = 10;
00829 
00830             while( isdigit(ch) || (ibase == 16 && isinset(ch,"0123456789ABCDEFabcdef")) ){
00831               esig = ibase*esig + ch;
00832               if( isdigit(ch) )
00833                 esig -= '0';
00834               else
00835                 if( islower(ch) )
00836                   esig -= 'a'-10;
00837                 else
00838                   esig -= 'A'-10;
00839 
00840               ch = GETC();
00841               }
00842             STORE_CH(esig);
00843             continue;
00844             }
00845 
00846           s = pLex->ESCS+1;
00847           while( *s && *s != ch )s+=2;
00848           if( *s ){
00849             /* if there is a replacement character use that */
00850             s++;
00851             STORE_CH(*s);
00852             ch = GETC();
00853             continue;
00854             }else{
00855             /* if there is no other character for this to be replaced use the original */
00856             STORE_CH(ch);
00857             ch = GETC();
00858             continue;
00859             }
00860           }/* End handling escape character. */
00861         STORE_CH(ch);
00862         ch = GETC();
00863         }/* End of string building. */
00864       if( ch == EOF ){/* string was not terminated before EOF */
00865         REPORT(pszFileName,
00866                lLineNumber,
00867                LEX_ERROR_STRING_NOT_TERMINATED,
00868                pLex->buffer);
00869         }
00870       /* to be safe we store the terminating zero character */
00871       STORE_CH( (char)0 );
00872       i++;
00873       if( (pfLexeme = NewLexeme()) == NULL ){
00874         lexFREE(UngetBuffer);
00875         return LEX_ERROR_MEMORY_LOW;
00876         }
00877       pfLexeme->next = NULL;
00878       pfLexeme->type = LEX_T_STRING;
00879       pfLexeme->lLineNumber = lLineNumber;
00880       pfLexeme->szFileName = pszFileName;
00881       pfLexeme->sLen = i-1; /* do not count the terminating zero */
00882       if( (pfLexeme->value.sValue = (char *)lexALLOC(i)) == NULL ){
00883         lexFREE(UngetBuffer);
00884         return LEX_ERROR_MEMORY_LOW;
00885         }
00886       memcpy(pfLexeme->value.sValue,pLex->buffer,i);
00887       if( pLex->pPREP && pLex->pPREP->n ){
00888         iResult = ipreproc_Process(pLex->pPREP,PreprocessorLexString,&plexLastLexeme);
00889         if( iResult )return iResult;
00890         }
00891       plexLastLexeme = &(pfLexeme->next);
00892       continue;
00893       }
00894 
00895 SimpleString:
00896     if( isinset(ch,pLex->SStC) ){
00897       cStringStartCharacter = ch;
00898       i = 1;
00899       ch = GETC();
00900       iErrorWasReported = 0;
00901       for( i = 0 ; ch != cStringStartCharacter && ch != EOF ; i++ ){
00902         if( ch == '\n' ){
00903           REPORT(pszFileName,
00904                  lLineNumber,
00905                  LEX_ERROR_STRING_NEW_LINE,
00906                  pLex->buffer);
00907           break;
00908           }
00909         if( ch == *(pLex->ESCS) ){
00910           ch = GETC();
00911           
00912           if( ((pLex->fFlag&LEX_PROCESS_STRING_NUMBER) && isdigit(ch)) ||
00913               ((pLex->fFlag&LEX_PROCESS_STRING_NUMBER) &&  (pLex->fFlag&LEX_PROCESS_STRING_HEX_NUMBER) && ch == 'x') ){
00914             esig = 0;
00915             /* choose the radix */
00916             if( ch == 'x' ){ch = GETC();ibase = 16; }else
00917               if( (pLex->fFlag&LEX_PROCESS_STRING_OCTAL_NUMBER) && ch == '0' )ibase = 8; 
00918                 else ibase = 10;
00919 
00920             while( isdigit(ch) || (ibase == 16 && isinset(ch,"0123456789ABCDEFabcdef")) ){
00921               esig = ibase*esig + ch;
00922               if( isdigit(ch) )
00923                 esig -= '0';
00924               else
00925                 if( islower(ch) )
00926                   esig -= 'a'-10;
00927                 else
00928                   esig -= 'A'-10;
00929 
00930               ch = GETC();
00931               }
00932             STORE_CH(esig);
00933             continue;
00934             }
00935 
00936           s = pLex->ESCS+1;
00937           while( *s && *s != ch )s+=2;
00938           if( *s ){
00939             /* if there is a replacement character use that */
00940             s++;
00941             STORE_CH(*s);
00942             ch = GETC();
00943             continue;
00944             }else{
00945             /* if there is no other character for this to be replaced use the original */
00946             STORE_CH(ch);
00947             ch = GETC();
00948             continue;
00949             }
00950           }/* End handling escape character. */
00951         STORE_CH(ch);
00952         ch = GETC();
00953         }/* End of string building. */
00954       if( ch == EOF ){/* string was not terminated before EOF */
00955         REPORT(pszFileName,
00956                lLineNumber,
00957                LEX_ERROR_STRING_NOT_TERMINATED,
00958                pLex->buffer);
00959         }
00960       STORE_CH( (char)0 );
00961       i++;
00962       if( (pfLexeme = NewLexeme()) == NULL ){
00963         lexFREE(UngetBuffer);
00964         return LEX_ERROR_MEMORY_LOW;
00965         }
00966       pfLexeme->next = NULL;
00967       pfLexeme->type = LEX_T_STRING;
00968       pfLexeme->lLineNumber = lLineNumber;
00969       pfLexeme->szFileName = pszFileName;
00970       pfLexeme->sLen = i-1; /* do not coun the terminating zero */
00971       if( (pfLexeme->value.sValue = (char *)lexALLOC(i)) == NULL ){
00972         lexFREE(UngetBuffer);
00973         return LEX_ERROR_MEMORY_LOW;
00974         }
00975       memcpy(pfLexeme->value.sValue,pLex->buffer,i);
00976       if( pLex->pPREP && pLex->pPREP->n ){
00977         iResult = ipreproc_Process(pLex->pPREP,PreprocessorLexMString,&plexLastLexeme);
00978         if( iResult )return iResult;
00979         }
00980       plexLastLexeme = &(pfLexeme->next);
00981       continue;
00982       }
00983 #undef STORE_CH
00984 
00985     /*** PROCESS A NUMBER ***/
00986 
00987     nch = GETC();
00988     UNGETC(nch);
00989     if( (ch == '0' && ( nch == 'x' || nch == 'X' )) ||
00990         (ch == '&' && ( nch == 'h' || nch == 'H' )) ){
00992       GETC();ch = GETC();
00993       for( hintpart = 0 ; isinset(ch,"0123456789ABCDEFabcdef") ; ch = GETC() ){
00994         hintpart = 16* hintpart + ch;
00995         if( isdigit(ch) )
00996           hintpart -= '0';
00997         else
00998           if( islower(ch) )
00999             hintpart -= 'a'-10;
01000           else
01001             hintpart -= 'A'-10;
01002         }
01003       if( (pfLexeme = NewLexeme()) == NULL ){
01004         lexFREE(UngetBuffer);
01005         return LEX_ERROR_MEMORY_LOW;
01006         }
01007       pfLexeme->next = NULL;
01008       pfLexeme->type = LEX_T_LONG;
01009       pfLexeme->value.lValue = hintpart;
01010       pfLexeme->lLineNumber = lLineNumber;
01011       pfLexeme->szFileName = pszFileName;
01012       if( pLex->pPREP && pLex->pPREP->n ){
01013         iResult = ipreproc_Process(pLex->pPREP,PreprocessorLexInteger,&plexLastLexeme);
01014         if( iResult )return iResult;
01015         }
01016       plexLastLexeme = &(pfLexeme->next);
01017       UNGETC(ch);
01018       continue;
01019       }
01020 
01021     /* We can in no way handle -nnn or +nn as numbers. The are
01022        unary operators followed by an expression consiting of a single number.
01023        If we say at this level that -nnn is a number then for the expression
01024        eg: 6-3 becomes meaning less, a number 6 followed by another number -3
01025        without operator. Wherever higher level of syntax analysis accept a
01026        number they should also accept a whole expression. Even though there is a pseudo
01027        terminal called number in the file synrax.def, but we never use it. */
01028     if( isdigit(ch) || ch == '.' ){
01029       for( intpart = 0 ; isdigit(ch) ; ch = GETC() ){
01030         intpart *= 10;
01031         intpart += ch-'0';
01032         }
01033       i = 1; /* this is an integer so far */
01034       if( ch == '#' ){
01035         /* in this case this was the base of the number and the number comes now */
01036         if( intpart < 2 || intpart > 36 )return LEX_ERROR_BAD_RADIX;
01037         ibase = (int)intpart;
01038         ch = GETC();
01039         if( ! isinset(ch,"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz") )return LEX_ERROR_INVALID_NUMBER;
01040         hintpart = 0;
01041         while( isinset(ch,"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz") ){
01042           nch = ch;
01043           if( isdigit(nch) )
01044             nch -= '0';
01045           else
01046             if( islower(nch) )
01047               nch -= 'a'-10;
01048             else
01049               nch -= 'A'-10;
01050           if( nch >= ibase )break;
01051           hintpart = ibase * hintpart + nch;
01052           ch = GETC();
01053           }
01054         if( (pfLexeme = NewLexeme()) == NULL ){
01055           lexFREE(UngetBuffer);
01056           return LEX_ERROR_MEMORY_LOW;
01057           }
01058         pfLexeme->next = NULL;
01059         pfLexeme->type = LEX_T_LONG;
01060         pfLexeme->value.lValue = hintpart;
01061         pfLexeme->lLineNumber = lLineNumber;
01062         pfLexeme->szFileName = pszFileName;
01063         if( pLex->pPREP && pLex->pPREP->n ){
01064           iResult = ipreproc_Process(pLex->pPREP,PreprocessorLexInteger,&plexLastLexeme);
01065           if( iResult )return iResult;
01066           }
01067         plexLastLexeme = &(pfLexeme->next);
01068         UNGETC(ch);
01069         continue;
01070         }
01071       fracpart = 0.0; /* fractional part */
01072       if( ch == '.' ){
01073         i = 0; /* this is not an integer anymore */
01074         man = 1.0;      /* actual mantissa */
01075         for( ch = GETC() ; isdigit(ch) ; ch = GETC() )
01076           fracpart += (man *= 0.1) * (ch-'0');
01077         }
01078       exppart = 0.0; /* In case there is no E part then we need this value. */
01079       esig = 1; /* this is not really interesting because exppart is set to zero anyway but here it is */
01080       if( ch == 'E' || ch == 'e' ){
01081         i = 0; /* this is not an integer anymore if it has exponential part */
01082         ch = GETC(); /* step over the character E */
01083         if( ch == '-' )esig=-1; else esig = 1;
01084         if( ch == '+' || ch == '-')ch = GETC(); /* step over the exponential sign */
01085         for( exppart=0.0 , i = 0 ; isdigit(ch) ; ch = GETC() )
01086           exppart = 10*exppart + ch-'0';
01087         }
01088       if( (pfLexeme = NewLexeme()) == NULL ){
01089         lexFREE(UngetBuffer);
01090         return LEX_ERROR_MEMORY_LOW;
01091         }
01092       pfLexeme->next = NULL;
01093       if( i ){/* finally this is an integer */
01094         pfLexeme->type = LEX_T_LONG;
01095         pfLexeme->value.lValue = (long)intpart;
01096         }else{
01097         pfLexeme->type = LEX_T_DOUBLE;
01098         pfLexeme->value.dValue = (intpart + fracpart)*pow10(esig*exppart);
01099         }
01100       pfLexeme->lLineNumber = lLineNumber;
01101       pfLexeme->szFileName = pszFileName;
01102       if( pLex->pPREP && pLex->pPREP->n ){
01103         iResult = ipreproc_Process(pLex->pPREP,
01104                                    pfLexeme->type == LEX_T_DOUBLE ? PreprocessorLexReal : PreprocessorLexInteger,
01105                                    &plexLastLexeme);
01106         if( iResult )return iResult;
01107         }
01108       plexLastLexeme = &(pfLexeme->next);
01109       UNGETC(ch);
01110       continue;
01111       }
01112     
01113     /*** PROCESS A NON ALPHA SYMBOL ***/
01114     if( pNA = pLex->pNASymbols ){
01115       pLex->buffer[0] = ch;
01116       for( i = 1 ; i < pLex->cbNASymbolLength-1 ; i++ )
01117          pLex->buffer[i] = GETC();
01118       while( pNA->Symbol && strncmp(pLex->buffer,pNA->Symbol,ibase=strlen(pNA->Symbol)) )
01119         pNA ++;
01120       if( pNA->Symbol ){/* symbol is found */
01121         while( i > ibase )UNGETC(pLex->buffer[--i]);
01122         if( (pfLexeme = NewLexeme()) == NULL ){
01123           lexFREE(UngetBuffer);
01124           return LEX_ERROR_MEMORY_LOW;
01125           }
01126         pfLexeme->next = NULL;
01127         pfLexeme->type = LEX_T_NSYMBOL;
01128         pfLexeme->value.lValue = pNA->Code;
01129         pfLexeme->lLineNumber = lLineNumber;
01130         pfLexeme->szFileName = pszFileName;
01131         if( pLex->pPREP && pLex->pPREP->n ){
01132           iResult = ipreproc_Process(pLex->pPREP,PreprocessorLexNASymbol,&plexLastLexeme);
01133           if( iResult )return iResult;
01134           }
01135         plexLastLexeme = &(pfLexeme->next);
01136         continue;
01137         }
01138       /* Symbol was not found. */
01139       i--;
01140       while( i )UNGETC(pLex->buffer[i--]);/* unget all but one character */
01141       if( (pfLexeme = NewLexeme()) == NULL ){
01142         lexFREE(UngetBuffer);
01143         return LEX_ERROR_MEMORY_LOW;
01144         }
01145       pfLexeme->next = NULL;
01146       pfLexeme->type = LEX_T_CHARACTER;
01147       pfLexeme->value.lValue = *(pLex->buffer);
01148       pfLexeme->lLineNumber = lLineNumber;
01149       pfLexeme->szFileName = pszFileName;
01150       if( pLex->pPREP && pLex->pPREP->n ){
01151         iResult = ipreproc_Process(pLex->pPREP,PreprocessorLexCharacter,&plexLastLexeme);
01152         if( iResult )return iResult;
01153         }
01154       plexLastLexeme = &(pfLexeme->next);
01155       continue;
01156       }
01157     }
01158   lexFREE(UngetBuffer);
01159   if( pLex->pPREP && pLex->pPREP->n ){
01160     iResult = ipreproc_Process(pLex->pPREP,PreprocessorLexDone,pLex);
01161     if( iResult )return iResult;
01162     }
01163   return LEX_ERROR_SUCCESS;
01164   }
01165 
01166 static void *lex_malloc(size_t n, void *pMemorySegment){
01167   return malloc(n);
01168   }
01169 static void lex_free(void *p, void *pMemorySegment){
01170   free(p);
01171   }
01172 static long _MyLineNumber(void *p){
01173   return 0L;
01174   }
01175 static char * _MyFileName(void *p){
01176   return "No-File";
01177   }
01178 
01179 /*POD
01180 =H lex_InitStructure()
01181 
01182 You may but need not call this function to initialize a T<LexObject>. You may
01183 also call this function to use the settings of the function and set some
01184 variables to different values after the function returns.
01185 
01186 /*FUNCTION*/
01187 void lex_InitStructure(pLexObject pLex
01188   ){
01189 /*noverbatim
01190 CUT*/
01191   pLex->pfGetCharacter = NULL;
01192   pLex->pfFileName = _MyFileName;
01193   pLex->pfLineNumber = _MyLineNumber;
01194   pLex->SSC = "QWERTZUIOPASDFGHJKLYXCVBNMqwertzuiopasdfghjklyxcvbnm_:$";
01195   pLex->SCC = "QWERTZUIOPASDFGHJKLYXCVBNMqwertzuiopasdfghjklyxcvbnm_1234567890:$";
01196   pLex->SFC = "QWERTZUIOPASDFGHJKLYXCVBNMqwertzuiopasdfghjklyxcvbnm_1234567890$";
01197   pLex->SStC = "\"";
01198   pLex->ESCS = "\\n\nt\tr\r\"\"\'\'";
01199   pLex->fFlag = LEX_PROCESS_STRING_NUMBER       |
01200                 LEX_PROCESS_STRING_OCTAL_NUMBER |
01201                 LEX_PROCESS_STRING_HEX_NUMBER   |
01202                 0;
01203   pLex->SKIP = " \t\r"; /* spaces to skip 
01204                            \r is included to ease compilation of DOS edited 
01205                            binary transfered files to run on UNIX */
01206   pLex->pNASymbols = NULL;
01207   pLex->pASymbols  = NULL;
01208   pLex->pCSymbols  = NULL;
01209   pLex->cbNASymbolLength = 0; /* it is to be calculated */
01210 
01211   pLex->buffer = lexALLOC(BUFFERINCREASE*sizeof(char));
01212   if( pLex->buffer )
01213     pLex->cbBuffer = BUFFERINCREASE;
01214   else
01215     pLex->cbBuffer = 0;
01216 
01217   CALL_PREPROCESSOR(PreprocessorLexInit,pLex);
01218   }

Generated on Sun Mar 12 23:56:31 2006 for ScriptBasic by  doxygen 1.4.6-NO