Files
harbour-core/harbour/source/compiler/simplex.c
Przemyslaw Czerpak ef0883bf02 2004-10-11 21:40 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/Makefile
  + harbour/make_bsd.sh
  + harbour/make_drw.sh
  * harbour/make_tgz.sh
  + harbour/bin/hb-func.sh
  * harbour/bin/pack_src.sh
  + harbour/bin/postinst.bat
  + harbour/bin/postinst.sh
  * harbour/config/dir.cf
  * harbour/config/bsd/gcc.cf
  * harbour/config/bsd/global.cf
  + harbour/config/darwin/dir.cf
  + harbour/config/darwin/gcc.cf
  + harbour/config/darwin/global.cf
  + harbour/config/darwin/install.cf
  * harbour/config/dos/dir.cf
  * harbour/config/dos/global.cf
  * harbour/config/dos/install.cf
  * harbour/config/dos/owatcom.cf
  * harbour/config/dos/watcom.cf
  * harbour/config/linux/gcc.cf
  * harbour/config/linux/global.cf
  * harbour/contrib/Makefile
  * harbour/contrib/dot/pp_harb.ch
  * harbour/contrib/libct/Makefile
  * harbour/contrib/libct/bit1.c
  * harbour/contrib/libct/bit2.c
  * harbour/contrib/libct/bit3.c
  * harbour/contrib/libct/files.c
  * harbour/contrib/libct/ftoc.c
  - harbour/contrib/libct/invertwin.prg
  + harbour/contrib/libct/invrtwin.prg
  * harbour/contrib/libct/keyset.c
  * harbour/contrib/libct/makefile.bc
  * harbour/contrib/libmisc/dates2.c
  * harbour/contrib/rdd_ads/ads1.c
  * harbour/contrib/rdd_ads/adsfunc.c
  * harbour/contrib/samples/date.c
  * harbour/include/dbinfo.ch
  * harbour/include/hbapi.h
  * harbour/include/hbapicdp.h
  * harbour/include/hbapifs.h
  * harbour/include/hbapigt.h
  * harbour/include/hbapiitm.h
  * harbour/include/hbcomp.h
  * harbour/include/hbdate.h
  * harbour/include/hbdbf.h
  * harbour/include/hbdbferr.h
  * harbour/include/hbdefs.h
  * harbour/include/hbexprb.c
  * harbour/include/hbexprc.c
  * harbour/include/hbexprop.h
  * harbour/include/hbmacro.h
  * harbour/include/hbmath.h
  * harbour/include/hbpcode.h
  * harbour/include/hbrddcdx.h
  * harbour/include/hbrdddbf.h
  * harbour/include/hbrdddbt.h
  * harbour/include/hbrddfpt.h
  * harbour/include/hbrddntx.h
  * harbour/include/hbset.h
  * harbour/include/hbsetup.h
  * harbour/include/set.ch
  * harbour/source/common/Makefile
  * harbour/source/common/expropt1.c
  * harbour/source/common/expropt2.c
  - harbour/source/common/hbffind.c
  * harbour/source/common/hbfsapi.c
  * harbour/source/common/hbstr.c
  * harbour/source/common/hbver.c
  + harbour/source/common/hbverdsp.c
  * harbour/source/compiler/genc.c
  * harbour/source/compiler/gencli.c
  * harbour/source/compiler/harbour.c
  * harbour/source/compiler/harbour.l
  * harbour/source/compiler/harbour.slx
  * harbour/source/compiler/harbour.sly
  * harbour/source/compiler/harbour.y
  * harbour/source/compiler/hbfix.c
  * harbour/source/compiler/hbpcode.c
  * harbour/source/compiler/hbusage.c
  * harbour/source/compiler/simplex.c
  * harbour/source/macro/macro.l
  * harbour/source/macro/macro.slx
  * harbour/source/macro/macro.y
  * harbour/source/pp/ppcore.c
  * harbour/source/rdd/dbcmd.c
  * harbour/source/rdd/dbf1.c
  * harbour/source/rdd/dbfcdx/dbfcdx1.c
  - harbour/source/rdd/dbfcdx/dbfcdx1.h
  * harbour/source/rdd/dbffpt/dbffpt1.c
  * harbour/source/rdd/dbfntx/dbfntx1.c
  * harbour/source/rtl/Makefile
  * harbour/source/rtl/abs.c
  * harbour/source/rtl/at.c
  * harbour/source/rtl/datec.c
  * harbour/source/rtl/dates.c
  * harbour/source/rtl/dateshb.c
  * harbour/source/rtl/datesx.c
  * harbour/source/rtl/empty.c
  * harbour/source/rtl/errorapi.c
  * harbour/source/rtl/errorint.c
  * harbour/source/rtl/filesys.c
  * harbour/source/rtl/fstemp.c
  + harbour/source/rtl/hbffind.c
  * harbour/source/rtl/hbrandom.c
  * harbour/source/rtl/idle.c
  * harbour/source/rtl/inkey.c
  * harbour/source/rtl/math.c
  * harbour/source/rtl/minmax.c
  * harbour/source/rtl/pad.c
  * harbour/source/rtl/padc.c
  * harbour/source/rtl/padl.c
  * harbour/source/rtl/padr.c
  * harbour/source/rtl/philes.c
  * harbour/source/rtl/round.c
  * harbour/source/rtl/soundex.c
  * harbour/source/rtl/str.c
  * harbour/source/rtl/strcase.c
  * harbour/source/rtl/strmatch.c
  * harbour/source/rtl/strtran.c
  * harbour/source/rtl/strzero.c
  * harbour/source/rtl/substr.c
  * harbour/source/rtl/val.c
  * harbour/source/rtl/gtcrs/gtcrs.c
  * harbour/source/rtl/gtcrs/kbdcrs.c
  * harbour/source/rtl/gtdos/gtdos.c
  * harbour/source/rtl/gtsln/gtsln.c
  * harbour/source/rtl/gtsln/kbsln.c
  * harbour/source/rtl/gtsln/keytrans.c
  * harbour/source/vm/arrays.c
  * harbour/source/vm/codebloc.c
  * harbour/source/vm/estack.c
  * harbour/source/vm/eval.c
  * harbour/source/vm/extend.c
  * harbour/source/vm/hvm.c
  * harbour/source/vm/itemapi.c
  * harbour/source/vm/macro.c
  * harbour/source/vm/memvars.c
  * harbour/source/vm/runner.c
  * harbour/tests/bldtest/bldtest.c
  * harbour/utils/hbtest/hbtest.prg
  * harbour/utils/hbtest/rt_misc.prg
  * harbour/utils/hbtest/rt_str.prg
   * Sorry but it's too much modification for full description
     cvs diff gives file 785982 bytes length. So I only count the
     main things:
   ! cleand the code (no more warning messages under Linux and GCC and
     DOS OpenWatcom) - some of them were real bugs
   ! cleaned all endian dependend code I've found - now Harbour can be
     compiled on LITLE and BIG endian machines - for some other like
     PDP ENDIAN it's enough to define proper macros in hbdefs.h
   + added macros for to get/put values in chosen byte order:
         HB_GET_LE_[U]INT{16,24,32,64}( pPtr )
         HB_GET_BE_[U]INT{16,24,32,64}( pPtr )
         HB_PUT_LE_[U]INT{16,24,32,64}( pPtr, nVal )
         HB_PUT_BE_[U]INT{16,24,32,64}( pPtr, nVal )
   + added macro HB_CAST_BYTE_NUMBERS_OFF which disables casting in
     HB_{GET|PUT}_{LE|BE}_* macros - it's necessary for some platforms
     like ALPHA DEC.
   ! cleaned the code for 64bit machines
   * changed all parameters in hb_date* functions (day, month, year, week)
     from LONG to int - it doesn't change binary compatibility for 32bit
     machines but can cause troubles with compiling the old source
   + changed HB_IT_LONG type to HB_LONG which is mapped to long long
     by default for 32 bit machines.
   + change HB_IT_INTEGER to be real 'int' C type not 'short int'
   + added HB_IS_NUMINT() macro
   + added hb_parnll, hb_stornll, hb_retnll, hbretnlllen, hb_itemPutNLL,
     hb_itemPutNLLLen, hb_itemGetNLL which operates on LONGLONG
   + added hb_parnint, hb_stornint, hb_retnint, hb_retnintlen,
     hb_itemPutNInt, hb_itemPutNIntLen, hb_itemGetNInt which operates on
     HB_LONG
   + added HB_PUSHLONGLONG pcode
   + changed compiler and optimizer to use HB_LONG numbers and reduce
     conversion from to double which may damage the 64bit number.
   + common functions for string to number conversions for compiler, RTL
     and RDD to reduce problems with differ FL values for the same number:
     hb_compStrToNum(), hb_valStrnToNum(), hb_strToNum(), hb_strnToNum()
   + common function hb_numRoun() which uses exactly the same algorithms
     as string to number conversion for the same reason - please keep
     this functions together.
   + hack inside hb_numRound() similar to the one used by CL5.3
   + hb_numInt() which uses uses the same hack as hb_numRound()
   + rewritten number to string conversion
   + some new string manipulation functions hb_strncpy(), hb_strncat(), ...
     They works differ the the C one - always set 0 at the end, the buffer
     has to be n+1 bytes length, the n is total size of buffer not the
     left free space.
   ! cleaned some code which operates on ASCIIZ string to avoid potential
     buffer overflow
   + updated RDD code - it's the first part - in few days I plan to change
     workarea structure in both projects - it will break any 3rd party RDDs
     so they have to be updated. I want to add SUPERTABLE into workarea
     to allow creating new RDD on-line.
   ! cleaned the bugs with negating integers - on most machines (like x86)
     the integers are not 0 symmetric - it means that x = -x does not work
     for {INT,LONG,LONGLONG}_MIN (hb_vmNegate, ABS())
   + cleaned error messages to be Clipper compatible.
   + updated build process for .DEB packages - now hb* scripts and shared
     libs are created by standard make install
   * added new .prg #defines: __PLATFORM__<cPlatfrom>,
     __ARCH{16|32|64}BIT__, __LITTLE_ENDIAN__|__BIG_ENDIAN__|__PDP_ENDIAN__
     !!! cPlatfrom can have lower letters (for xHarbour compatibility)
     If you do not like it please change it.
   * others ...
2004-10-11 20:44:30 +00:00

1582 lines
45 KiB
C

/*
* $Id$
*/
/*
* Copyright 2000 Ron Pinkas <ron@profit-master.com>
* www - http://www.Profit-Master.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
*
* As a special exception, the Harbour Project gives permission for
* additional uses of the text contained in its release of Harbour.
*
* The exception is that, if you link the Harbour libraries with other
* files to produce an executable, this does not by itself cause the
* resulting executable to be covered by the GNU General Public License.
* Your use of that executable is in no way restricted on account of
* linking the Harbour library code into it.
*
* This exception does not however invalidate any other reasons why
* the executable file might be covered by the GNU General Public License.
*
* This exception applies only to the code released by the Harbour
* Project under the name Harbour. If you copy code from other
* Harbour Project or Free Software Foundation releases into a copy of
* Harbour, as the General Public License permits, the exception does
* not apply to the code that you add in this way. To avoid misleading
* anyone as to the status of such modified files, you must delete
* this exception notice from them.
*
* If you write modifications of your own for Harbour, it is your choice
* whether to permit this exception to apply to your modifications.
* If you do not wish that, delete this exception notice.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
/* NOT overidable (yet). */
#define MAX_MATCH 4
#ifndef TOKEN_SIZE
#define TOKEN_SIZE 64
#endif
/* Language Definitions Readability. */
#define SELF_CONTAINED_WORDS_ARE static LEX_WORD aSelfs[] =
#define LANGUAGE_KEY_WORDS_ARE static LEX_WORD aKeys[] =
#define LANGUAGE_WORDS_ARE static LEX_WORD aWords[] =
#define LANGUAGE_RULES_ARE static int aiRules[][ MAX_MATCH + 2 ] =
#define ACCEPT_TOKEN_AND_DROP_DELIMITER_IF_ONE_OF_THESE(x) static char *szOmmit = x
#define ACCEPT_TOKEN_AND_RETURN_DELIMITERS static LEX_DELIMITER aDelimiters[] =
#define DELIMITER_BELONGS_TO_TOKEN_IF_ONE_OF_THESE(x) static char *szAppend = x
#define START_NEW_LINE_IF_ONE_OF_THESE(x) static char *szNewLine = x
#define IF_SEQUENCE_IS(a, b, c, d) {a, b, c, d
#define REDUCE_TO(x, y) ,x, y }
#define PASS_THROUGH() ,0, 0 }
#define LEX_DELIMITER(x) {x
#define LEX_WORD(x) {x
#define AS_TOKEN(x) ,x }
/* Streams ("Pairs"). */
#define DEFINE_STREAM_AS_ONE_OF_THESE LEX_PAIR aPairs[] =
#define START_WITH(x) { x,
#define END_WITH(x) x,
#define STOP_IF_ONE_OF_THESE(x) x,
#define TEST_LEFT(x) x,
#define AS_PAIR_TOKEN(x) x }
#define STREAM_EXCEPTION( sPair, chrPair) \
if( chrPair ) \
{ \
printf( "Exception: %c for stream at: \"%s\"\n", chrPair, sPair ); \
} \
else \
{ \
printf( "Exception: <EOF> for stream at: \"%s\"\n", chrPair, sPair ); \
} \
/* Pairs. */
#ifndef MAX_STREAM
#define MAX_STREAM 2048
#endif
#ifndef MAX_STREAM_STARTER
#define MAX_STREAM_STARTER 2
#endif
#ifndef MAX_STREAM_TERMINATOR
#define MAX_STREAM_TERMINATOR 2
#endif
#ifndef MAX_STREAM_EXCLUSIONS
#define MAX_STREAM_EXCLUSIONS 2
#endif
static char sPair[ MAX_STREAM ];
static char * sStart, * sTerm;
static char * sExclude;
static BOOL bTestLeft;
static int iPairToken = 0;
/* Self Contained Words. */
static char sSelf[ TOKEN_SIZE ];
typedef struct _LEX_DELIMITER
{
char cDelimiter;
int iToken;
} LEX_DELIMITER; /* support structure for KEYS and WORDS. */
typedef struct _LEX_WORD
{
char sWord[ TOKEN_SIZE ];
int iToken;
} LEX_WORD; /* support structure for KEYS and WORDS. */
typedef struct _LEX_PAIR
{
char sStart[MAX_STREAM_STARTER];
char sTerm[MAX_STREAM_TERMINATOR];
char sExclude[MAX_STREAM_EXCLUSIONS];
BOOL bTestLeft;
int iToken;
} LEX_PAIR; /* support structure for Streams (Pairs). */
#ifdef __cplusplus
typedef struct yy_buffer_state *YY_BUFFER_STATE;
#endif
/* Above are NOT overidable !!! Need to precede the Language Definitions. */
/* --------------------------------------------------------------------------------- */
/* Overidables. */
#define LEX_CUSTOM_ACTION -65
#define DONT_REDUCE 1024
#define YY_BUF_SIZE 16384
#define MAX_RULES 1024
#define YY_INPUT( a, b, c )
/* Optional User Macros. */
#define LEX_USER_SETUP()
#define INIT_ACTION()
#define INTERCEPT_ACTION(x)
#define CUSTOM_ACTION(x)
#define NEW_LINE_ACTION()
#define ELEMENT_TOKEN(x,y) -1
#define DEBUG_INFO(x)
#define LEX_CASE(x)
#define STREAM_OPEN(x)
#define STREAM_APPEND(x) sPair[ iPairLen++ ] = x
#include SLX_RULES
/* Declarations. */
FILE *yyin; /* currently yacc parsed file */
extern void yyerror( char * ); /* parsing error management function */
#ifdef __cplusplus
extern "C" int yywrap( void );
#else
extern int yywrap( void ); /* manages the EOF of current processed file */
#endif
/* Use prototypes in function declarations. */
#define YY_USE_PROTOS
#ifdef YY_USE_PROTOS
#define YY_PROTO(proto) proto
#else
#define YY_PROTO(proto) ()
#endif
/* ---------------------------------------------------------------------------------------------- */
#define LEX_RULE_SIZE ( sizeof( (int) iRet ) * ( MAX_MATCH + 2 ) )
#define LEX_WORD_SIZE ( sizeof( LEX_WORD ) )
#define LEX_PAIR_SIZE ( sizeof( LEX_PAIR ) )
#define LEX_DELIMITER_SIZE ( sizeof( LEX_DELIMITER ) )
/* Using statics when we could use locals to eliminate Allocations and Deallocations each time yylex is called and returns. */
/* Look ahead Tokens. */
static int iHold = 0;
static int aiHold[4];
/* Pre-Checked Tokens. */
static int iReturn = 0;
static int aiReturn[4];
/* yylex */
static char * tmpPtr;
static char sToken[TOKEN_SIZE];
static unsigned int iLen = 0;
static char chr, cPrev = 0;
static unsigned int iLastToken = 0;
static char szLexBuffer[ YY_BUF_SIZE ];
static char * s_szBuffer;
static unsigned int iSize = 0;
static int iRet;
static BOOL bTmp, bIgnoreWords = FALSE, bRecursive = FALSE;
/* Lex emulation */
char * yytext = (char *) sToken;
int yyleng;
/* NewLine Support. */
static BOOL bNewLine = TRUE, bStart = TRUE;
#ifdef USE_KEYWORDS
static unsigned int iKeys = (int) ( sizeof( aKeys ) / LEX_WORD_SIZE );
#endif
static unsigned int iWords = (int) ( sizeof( aWords ) / LEX_WORD_SIZE );
static unsigned int iSelfs = (int) ( sizeof( aSelfs ) / LEX_WORD_SIZE );
static unsigned int iPairs = (int) ( sizeof( aPairs ) / LEX_PAIR_SIZE );
static unsigned int iDelimiters = (int) ( sizeof( aDelimiters ) / LEX_DELIMITER_SIZE );
static unsigned int iRules = (int) ( sizeof( aiRules ) / LEX_RULE_SIZE );
typedef struct _TREE_NODE
{
int iMin;
int iMax;
} TREE_NODE; /* support structure for Streams (Pairs). */
/* Indexing System. */
static TREE_NODE aPairNodes[256], aSelfNodes[256], aKeyNodes[256], aWordNodes[256], aRuleNodes[MAX_RULES];
static char acOmmit[256], acNewLine[256];
static int acReturn[256];
static int Reduce( int iToken );
int SimpLex_GetNextToken( void );
int SimpLex_CheckToken( void );
void SimpLex_CheckWords( void );
/* Indexing System. */
static void GenTrees( void );
static int rulecmp( const void * pLeft, const void * pRight );
/* --------------------------------------------------------------------------------- */
/* MACROS. */
/* Readability Macros. */
#define LEX_RULE_SIZE ( sizeof( (int) iRet ) * ( MAX_MATCH + 2 ) )
#define LEX_WORD_SIZE ( sizeof( LEX_WORD ) )
#define LEX_PAIR_SIZE ( sizeof( LEX_PAIR ) )
#define IF_TOKEN_READY() if( iReturn )
#define IF_TOKEN_ON_HOLD() if( iHold )
#define RESET_LEX() { iLen = 0; iHold = 0; iReturn = 0; bNewLine = TRUE; bStart = TRUE; }
#define FORCE_REDUCE() Reduce( 0 )
#define HOLD_TOKEN(x) PUSH_TOKEN(x)
#define IF_BEGIN_PAIR(chr) \
if( aPairNodes[(int)chr].iMin == -1 ) \
{ \
bTmp = FALSE; \
} \
else \
{ \
register unsigned int i = aPairNodes[(int)chr].iMin, iMax = aPairNodes[(int)chr].iMax + 1, iStartLen; \
register unsigned char chrStart; \
unsigned int iLastPair = 0, iLastLen = 0; \
\
DEBUG_INFO( printf( "Checking %i Streams for %c At: >%s<\n", iPairs, chr, szBuffer - 1 ) ); \
\
while( i < iMax ) \
{ \
iStartLen = 1; \
\
chrStart = LEX_CASE( *szBuffer ); \
\
while( aPairs[i].sStart[iStartLen] ) \
{ \
if( chrStart != aPairs[i].sStart[iStartLen] ) \
{ \
break; \
} \
\
iStartLen++; \
\
chrStart = LEX_CASE( *( szBuffer + iStartLen - 1 ) ); \
} \
\
/* Match */ \
if( aPairs[i].sStart[iStartLen] == '\0' ) \
{ \
if( iStartLen > iLastLen ) \
{ \
iLastPair = i + 1; \
iLastLen = iStartLen; \
} \
} \
i++; \
} \
\
bTmp = FALSE; \
\
if( iLastPair ) \
{ \
iLastPair--; \
STREAM_OPEN( aPairs[iLastPair].sStart )\
{ \
bTmp = TRUE; \
\
/* Last charcter read. */\
if( iStartLen > 1 ) chr = chrStart; \
\
/* Moving to next postion after the Stream Start position. */ \
szBuffer += ( iLastLen - 1 ); \
\
sStart = (char *) aPairs[iLastPair].sStart; \
sTerm = (char *) aPairs[iLastPair].sTerm; \
sExclude = (char *) aPairs[iLastPair].sExclude; \
bTestLeft = aPairs[iLastPair].bTestLeft; \
iPairToken = aPairs[iLastPair].iToken; \
\
DEBUG_INFO( printf( "Looking for Stream Terminator: >%s< Exclusions >%s<\n", sTerm, sExclude ) ); \
} \
} \
} \
/* Begin New Pair. */ \
if( bTmp )
#define CHECK_SELF_CONTAINED(chr) \
if( aSelfNodes[(int)chr].iMin != -1 ) \
{ \
register unsigned int i = aSelfNodes[(int)chr].iMin, iMax = aSelfNodes[(int)chr].iMax + 1, iSelfLen; \
register unsigned char chrSelf; \
\
DEBUG_INFO( printf( "Checking %i Selfs for %c At: >%s<\n", iSelfs, chr, szBuffer - 1 ) ); \
\
while( i < iMax ) \
{ \
sSelf[0] = chr; \
iSelfLen = 1; \
chrSelf = LEX_CASE( *szBuffer ); \
\
while( aSelfs[i].sWord[iSelfLen] ) \
{ \
if( aSelfs[i].sWord[iSelfLen] == chrSelf ) \
{ \
sSelf[ iSelfLen ] = chrSelf; \
} \
else \
{ \
break; \
} \
\
iSelfLen++; \
\
chrSelf = LEX_CASE( *( szBuffer + iSelfLen - 1 ) ); \
} \
\
/* Match */ \
if( aSelfs[i].sWord[iSelfLen] == '\0' ) \
{ \
/* Moving to next postion after the Self Contained Word. */ \
szBuffer += ( iSelfLen - 1 ); \
s_szBuffer = szBuffer; \
\
sSelf[ iSelfLen ] = '\0'; \
iRet = aSelfs[i].iToken; \
\
if( iLen ) \
{ \
DEBUG_INFO( printf( "Holding Self >%s<\n", sSelf ) ); \
\
HOLD_TOKEN( iRet ); \
\
/* Terminate current token and check it. */ \
sToken[ iLen ] = '\0'; \
\
/* Last charcter read. */\
chr = chrSelf;\
\
return SimpLex_CheckToken(); \
} \
else \
{ \
DEBUG_INFO( printf( "Reducing Self >%s<\n", sSelf ) ); \
bIgnoreWords = FALSE;\
\
if( bNewLine )\
{\
bNewLine = FALSE;\
NEW_LINE_ACTION();\
}\
\
/* Last charcter read. */\
if( iSelfLen > 1 ) chr = chrSelf;\
\
return iRet; \
} \
} \
\
i++; \
} \
}
#define IF_ABORT_PAIR(chrPair) \
tmpPtr = sExclude; \
while ( *tmpPtr && chrPair != *tmpPtr ) \
{ \
tmpPtr++; \
} \
\
/* Exception. */ \
if( *tmpPtr )
#define IF_APPEND_DELIMITER(chr) \
/* Delimiter to Append? */ \
tmpPtr = (char*) szAppend; \
while ( *tmpPtr && chr != *tmpPtr ) tmpPtr++; \
\
/* Delimiter to Append found. */ \
if( *tmpPtr )
#ifndef IF_BELONG_LEFT
#define IF_BELONG_LEFT(chr) \
/* Give precedence to associate rules */ \
DEBUG_INFO( printf( "Checking Left for: '%c' cPrev: '%c'\n", chr, cPrev ) ); \
\
if( 0 )
#endif
#define RETURN_READY_TOKEN() \
\
iReturn--; \
iRet = aiReturn[iReturn]; \
\
DEBUG_INFO( printf( "Returning Ready: %i\n", iRet ) ); \
\
INTERCEPT_ACTION(iRet); \
return iRet; \
#define RELEASE_TOKEN() \
\
/* Last in First Out. */ \
iHold--; \
iRet = aiHold[iHold]; \
\
DEBUG_INFO( printf( "Released %i Now Holding %i Tokens: %i %i %i %i\n", iRet, iHold, aiHold[0], aiHold[1], aiHold[2], aiHold[3] ) ); \
bIgnoreWords = FALSE;\
\
if( iRet < 256 ) \
{ \
if( acNewLine[iRet] ) bNewLine = TRUE; \
} \
\
DEBUG_INFO( printf( "Reducing Held: %i Pos: %i\n", iRet, iHold ) ); \
LEX_RETURN( Reduce( iRet ) );
#define LEX_RETURN(x) \
\
iRet = x;\
\
if( iRet < LEX_CUSTOM_ACTION ) \
{ \
iRet = CUSTOM_ACTION(iRet); \
} \
\
if( iRet ) \
{ \
DEBUG_INFO( printf( "Returning: %i\n", iRet ) ); \
\
INTERCEPT_ACTION(iRet); \
\
return iRet; \
} \
else \
{ \
goto Start; \
}
#define PUSH_TOKEN( iPushToken )\
{\
aiHold[ iHold++ ] = iPushToken;\
DEBUG_INFO( printf("Now Holding %i Tokens: %i %i %i %i\n", iHold, aiHold[0], aiHold[1], aiHold[2], aiHold[3] ) ); \
}
#ifndef YY_DECL
#define YY_DECL int yylex YY_PROTO(( void ))
#endif
YY_DECL
{
LEX_USER_SETUP();
Start :
IF_TOKEN_READY()
{
RETURN_READY_TOKEN();
}
IF_TOKEN_ON_HOLD()
{
RELEASE_TOKEN();
}
if( iSize == 0 )
{
if( bStart )
{
bStart = FALSE;
GenTrees();
INIT_ACTION();
}
YY_INPUT( (char*) szLexBuffer, iSize, YY_BUF_SIZE );
if( iSize )
{
s_szBuffer = (char*) szLexBuffer;
DEBUG_INFO( printf( "New Buffer: >%s<\n", szLexBuffer ) );
}
else
{
RESET_LEX();
DEBUG_INFO( printf( "Returning: <EOF>\n" ) );
return -1; \
}
}
LEX_RETURN( Reduce( SimpLex_GetNextToken() ) )
}
int SimpLex_GetNextToken( void )
{
register char * szBuffer = s_szBuffer;
iLen = 0;
while ( 1 )
{
if ( iSize && *szBuffer )
{
if( iPairToken )
{
goto ProcessStream;
}
cPrev = chr;
/* Get next character. */
iSize--;
chr = (*szBuffer++);
/* Not using LEX_CASE() yet (white space)!!! */
if( acOmmit[(int)chr] )
{
while( acOmmit[(int)(*szBuffer)] )
{
iSize--; szBuffer++;
}
if ( iLen )
{
/* Terminate current token and check it. */
sToken[ iLen ] = '\0';
s_szBuffer = szBuffer;
DEBUG_INFO( printf( "Token: \"%s\" Ommited: \'%c\'\n", sToken, chr ) );
return SimpLex_CheckToken();
}
else
{
continue;
}
}
chr = LEX_CASE(chr);
CHECK_SELF_CONTAINED(chr);
/* New Pair ? */
IF_BEGIN_PAIR( chr )
{
if( iLen )
{
DEBUG_INFO( printf( "Holding Stream Mode: '%c' Buffer = >%s<\n", chr, szBuffer ) );
/* Terminate and Check Token to the left. */
sToken[ iLen ] = '\0';
s_szBuffer = szBuffer;
DEBUG_INFO( printf( "Token: \"%s\" before New Pair at: \'%c\'\n", sToken, chr ) );
return SimpLex_CheckToken();
}
ProcessStream :
bIgnoreWords = FALSE;
if( bTestLeft )
{
IF_BELONG_LEFT( chr )
{
/* Resetting. */
iPairToken = 0;
s_szBuffer = szBuffer;
DEBUG_INFO( printf( "Reducing Left '%c'\n", chr ) );
return (int) chr ;
}
}
{ register int iPairLen = 0;
register char chrPair;
/* Look for the terminator. */
while ( *szBuffer )
{
/* Next Character. */
chrPair = *szBuffer++ ;
/* Terminator ? */
if( chrPair == sTerm[0] )
{
register int iTermLen = 1;
if( sTerm[1] )
{
register char chrTerm = *szBuffer; /* Not using LEX_CASE() here !!! */
while( sTerm[iTermLen] )
{
if( chrTerm != sTerm[iTermLen] )
{
/* Last charcter read. */
chr = chrTerm;
break;
}
iTermLen++;
chrTerm = *( szBuffer + iTermLen - 1 ); /* Not using LEX_CASE() here !!! */
}
}
/* Match */ \
if( sTerm[iTermLen] == '\0' ) \
{ \
/* Moving to next postion after the Stream Terminator. */ \
szBuffer += ( iTermLen - 1 ); \
sPair[ iPairLen ] = '\0';
if( bNewLine )
{
bNewLine = FALSE;
NEW_LINE_ACTION();
}
iRet = iPairToken;
/* Resetting. */
iPairToken = 0;
s_szBuffer = szBuffer;
DEBUG_INFO( printf( "Returning Pair = >%s<\n", sPair ) );
return iRet;
}
}
/* Check if exception. */
IF_ABORT_PAIR( chrPair )
{
sPair[ iPairLen ] = '\0';
/* Resetting. */
iPairToken = 0;
/* Last charcter read. */
chr = chrPair;
STREAM_EXCEPTION( sPair, chrPair );
s_szBuffer = szBuffer;
return iPairToken;
}
else
{
STREAM_APPEND( chrPair );
}
}
}
/* Resetting. */
iPairToken = 0;
/* EOF */
STREAM_EXCEPTION( sPair, NULL );
s_szBuffer = szBuffer;
return iPairToken;
}
/* End Pairs. */
/* NewLine ? */
if( acNewLine[(int)chr] )
{
while( acNewLine[(int)(*szBuffer)] )
{
iSize--; szBuffer++;
}
s_szBuffer = szBuffer;
if( iLen )
{
/* Will return NewLine on next call. */
HOLD_TOKEN( chr );
/* Terminate current token and check it. */
sToken[ iLen ] = '\0';
DEBUG_INFO( printf( "Token: \"%s\" at <NewLine> Holding: \'%c\'\n", sToken, chr ) );
return SimpLex_CheckToken();
}
else
{
DEBUG_INFO( printf( "Reducing NewLine '%c'\n", chr ) );
bIgnoreWords = FALSE;
bNewLine = TRUE;
return (int) chr;
}
}
#ifdef USE_BELONGS
IF_APPEND_DELIMITER( chr )
{
/* Append and Terminate current token and check it. */
sToken[ iLen++ ] = chr;
sToken[ iLen ] = '\0';
s_szBuffer = szBuffer;
DEBUG_INFO( printf( "Token: \"%s\" Appended: \'%c\'\n", sToken, chr ) );
return SimpLex_CheckToken();
}
#endif
if( acReturn[(int)chr] )
{
s_szBuffer = szBuffer;
if( iLen )
{
/* Will be returned on next cycle. */
HOLD_TOKEN( acReturn[(int)chr] );
/* Terminate current token and check it. */
sToken[ iLen ] = '\0';
DEBUG_INFO( printf( "Token: \"%s\" Holding: \'%c\' As: %i \n", sToken, chr, iRet ) );
return SimpLex_CheckToken();
}
else
{
bIgnoreWords = FALSE;
if( bNewLine )
{
bNewLine = FALSE;
NEW_LINE_ACTION();
}
DEBUG_INFO( printf( "Reducing Delimiter: '%c' As: %i\n", chr, acReturn[(int)chr] ) );
return acReturn[(int)chr];
}
}
/* Acumulate and scan next Charcter. */
sToken[ iLen++ ] = chr;
continue;
}
else
{
YY_INPUT( (char*) szLexBuffer, iSize, YY_BUF_SIZE );
if( iSize )
{
szBuffer = (char*) szLexBuffer;
continue;
}
else
{
if( iLen )
{
/* <EOF> */
HOLD_TOKEN( -1 );
/* Terminate current token and check it. */
sToken[ iLen ] = '\0';
s_szBuffer = szBuffer;
DEBUG_INFO( printf( "Token: \"%s\" at: \'<EOF>\'\n", sToken ) );
return SimpLex_CheckToken();
}
else
{
s_szBuffer = szBuffer;
DEBUG_INFO( printf( "Returning: <EOF>\n", iRet ) ); \
return -1; \
}
}
}
}
}
int SimpLex_CheckToken( void )
{
if( bRecursive )
{
return 0;
}
else
{
bRecursive = TRUE;
}
if( bNewLine )
{
bIgnoreWords = FALSE;
NEW_LINE_ACTION();
#ifdef USE_KEYWORDS
SimpLex_CheckWords();
if( iRet )
{
bRecursive = FALSE;
/* bIgnoreWords and bNewLine were handled by SimpLex_CheckWords(). */
return iRet;
}
#endif
}
if( bIgnoreWords )
{
DEBUG_INFO( printf( "Skiped Words for Word: %s\n", (char*) sToken ) );
bIgnoreWords = FALSE;
}
else
{
SimpLex_CheckWords();
if( iRet )
{
bRecursive = FALSE;
return iRet;
}
}
DEBUG_INFO( printf( "Reducing Element: \"%s\"\n", (char*) sToken ) );
iRet = ELEMENT_TOKEN( (char*)sToken, iLen );
bRecursive = FALSE;
return iRet;
}
int Reduce( int iToken )
{
BeginReduce :
if( iToken < LEX_CUSTOM_ACTION )
{
iToken = CUSTOM_ACTION( iToken ); \
}
if( iToken > DONT_REDUCE )
{
iLastToken = ( iToken - DONT_REDUCE );
DEBUG_INFO( printf( "Returning Dont Reduce %i\n", iLastToken ) );
return iLastToken;
}
else if( iToken <= 0 || iToken >= MAX_RULES )
{
DEBUG_INFO( printf( "Passing through (out of range): %i\n", iToken ) );
return iToken;
}
iLastToken = iToken;
/* No Rules for this token. */
if( aRuleNodes[ iToken ].iMin == -1 )
{
DEBUG_INFO( printf( "Passing through: %i\n", iToken ) );
return iToken;
}
else
{
register unsigned int i = (unsigned int)(aRuleNodes[ iToken ].iMin), iMax = (unsigned int)(aRuleNodes[ iToken ].iMax);
register unsigned int iTentative = 0, iMatched = 1;
DEBUG_INFO( printf( "Scaning Prospects %i-%i at Pos: 0 for Token: %i\n", i, iMax -1, iToken ) );
{
FoundProspect :
DEBUG_INFO( printf( "Prospect of %i Tokens - Testing Token: %i\n", iMatched, iToken ) );
if( iMatched == MAX_MATCH || aiRules[i][iMatched] == 0 )
{
DEBUG_INFO( printf( "Saving Tentative %i - Found match of %i Tokens at Token: %i\n", i, iMatched, iToken ) );
iTentative = i;
}
else
{
DEBUG_INFO( printf( "Partial Match - Get next Token after Token: %i\n", iToken ) );
if( iHold )
{
iHold--;
iToken = aiHold[ iHold ];
bIgnoreWords = FALSE;
if( iToken < 256 )
{
if( acNewLine[iToken] ) bNewLine = TRUE;
}
}
else
{
iToken = SimpLex_GetNextToken();
}
if( iToken < LEX_CUSTOM_ACTION )
{
iToken = CUSTOM_ACTION( iToken ); \
}
if( iToken > DONT_REDUCE )
{
DEBUG_INFO( printf( "Reduce Forced for Token: %i\n", iToken - DONT_REDUCE ) );
aiHold[iHold++] = iToken;
goto AfterScanRules;
}
else
{
iLastToken = iToken;
}
if( aiRules[i][iMatched] == iToken )
{
/* Continue... Still a prospect. */
DEBUG_INFO( printf( "Accepted Token: %i - Continue with this Rule...\n", iToken ) );
iMatched++;
goto FoundProspect;
}
else if( aiRules[i][iMatched] > iToken )
{
DEBUG_INFO( printf( "Rejected Token: %i - Giving up...\n", iToken ) );
aiHold[iHold++] = iToken;
goto AfterScanRules;
}
else
{
DEBUG_INFO( printf( "Rejected Token: %i - Continue with next Rule...\n", iToken ) );
aiHold[iHold++] = iToken;
}
}
if( i < iMax )
{
register unsigned int j = 1;
DEBUG_INFO( printf( "Checking if next rule is extension of last Rule\n" ) );
while( j < iMatched )
{
if( aiRules[i][j] != aiRules[i+1][j] )
{
break;
}
j++;
}
if( j < iMatched )
{
DEBUG_INFO( printf( "Rejected Rule - Not an extension of previous - Giving up...\n" ) );
}
else
{
DEBUG_INFO( printf( "Accepted Next Rule...\n" ) );
i++;
goto FoundProspect;
}
}
else
{
DEBUG_INFO( printf( "No More prospects...\n" ) );
}
}
AfterScanRules :
if( iTentative )
{
DEBUG_INFO( printf( "Processing Tentative: %i\n", iTentative ) );
while( iMatched > 1 && aiRules[i][iMatched - 1] && aiRules[iTentative][iMatched - 1] == 0 )
{
DEBUG_INFO( printf( "Reclaimed Token: %i\n", aiRules[i][iMatched - 1] ) );
aiHold[iHold++] = aiRules[i][iMatched - 1];
iMatched--;
}
if( aiRules[iTentative][MAX_MATCH] )
{
DEBUG_INFO( printf( "Reducing Rule: %i Found %i Tokens\n", iTentative, iMatched ) );
if( aiRules[iTentative][MAX_MATCH + 1] )
{
DEBUG_INFO( printf( "Pushing Reduction: %i\n", aiRules[iTentative][MAX_MATCH + 1] ) );
aiHold[iHold++] = aiRules[iTentative][MAX_MATCH + 1];
}
DEBUG_INFO( printf( "Recycling Reduction: %i\n", aiRules[iTentative][MAX_MATCH] ) );
iToken = aiRules[iTentative][MAX_MATCH];
goto BeginReduce;
}
else
{
DEBUG_INFO( printf( "Passing Through %i Tokens\n", iMatched ) );
while( iMatched > 1 )
{
iMatched--;
DEBUG_INFO( printf( "Stacking Return: %i\n", aiRules[iTentative][iMatched] ) );
aiReturn[iReturn++] = aiRules[iTentative][iMatched];
}
DEBUG_INFO( printf( "Returning: %i\n", aiRules[iTentative][0] ) );
return aiRules[iTentative][0];
}
}
else
{
while( iMatched > 1 )
{
iMatched--;
DEBUG_INFO( printf( "Pushing: %i\n", aiRules[i][iMatched] ) );
aiHold[iHold++] = aiRules[i][iMatched];
}
DEBUG_INFO( printf( "Returning Shifted Left: %i\n", aiRules[i][0] ) );
return aiRules[i][0];
}
}
}
void SimpLex_CheckWords( void )
{
int iTentative = -1, iCompare;
unsigned int i, iMax, iLenMatched, iBaseSize, iKeyLen;
char *pNextSpacer, *sKeys2Match = NULL, *szBaseBuffer = s_szBuffer, cSpacer = chr;
LEX_WORD *aCheck;
#ifdef DEBUG_LEX
char sKeyDesc[] = "Key", sWordDesc[] = "Word", *sDesc;
#endif
#ifdef LEX_ABBREVIATE
unsigned int iLen2Match;
#endif
#ifdef USE_KEYWORDS
if( bNewLine )
{
i = aKeyNodes[ (int)(sToken[0]) ].iMin;
iMax = aKeyNodes[ (int)(sToken[0]) ].iMax + 1;
aCheck = (LEX_WORD*) ( &(aKeys[0]) );
#ifdef DEBUG_LEX
sDesc = (char*) sKeyDesc;
#endif
}
else
#endif
{
i = aWordNodes[ (int)(sToken[0]) ].iMin;
iMax = aWordNodes[ (int)(sToken[0]) ].iMax + 1;
aCheck = (LEX_WORD*) ( &( aWords[0] ) );
#ifdef DEBUG_LEX
sDesc = (char*) sWordDesc;
#endif
}
bNewLine = FALSE;
DEBUG_INFO( printf( "Pre-Scaning %ss for Token: %s at Positions: %i-%i\n", sDesc, (char*) sToken, i, iMax -1 ) );
while( i < iMax )
{
if( sToken[1] < aCheck[i].sWord[1] )
{
DEBUG_INFO( printf( "Gave-Up! Token [%s] < Pattern [%s]\n", sToken, aCheck[i].sWord ) );
iRet = 0;
return;
}
else if( sToken[1] > aCheck[i].sWord[1] )
{
DEBUG_INFO( printf( "Skip... %s [%s] < [%s]\n", sDesc, aCheck[i].sWord, sToken ) );
i++;
DEBUG_INFO( printf( "Continue with larger: [%s]\n", aCheck[i].sWord ) );
continue;
}
else
{
break;
}
}
while( i < iMax )
{
if( sKeys2Match )
{
pNextSpacer = strstr( sKeys2Match, "{WS}" );
}
else
{
sKeys2Match = aCheck[ i ].sWord;
pNextSpacer = strstr( sKeys2Match, "{WS}" );
}
if( sToken[0] < sKeys2Match[0] )
{
DEBUG_INFO( printf( "Gave-Up! Token [%s] < Pattern [%s]\n", sToken, sKeys2Match ) );
break;
}
else if( sToken[0] > sKeys2Match[0] )
{
DEBUG_INFO( printf( "Skip... %s [%s] < [%s]\n", sDesc, sKeys2Match, sToken ) );
i++;
if( ( iLenMatched = ( sKeys2Match - aCheck[i - 1].sWord ) ) == 0 )
{
sKeys2Match = NULL;
DEBUG_INFO( printf( "Continue with larger: [%s]\n", aCheck[i].sWord ) );
continue;
}
/* Is there a next potential Pattern. */
if( i < iMax && strncmp( aCheck[i - 1].sWord, aCheck[i].sWord, iLenMatched ) == 0 )
{
/* Same relative position, in the next Pattern. */
sKeys2Match = aCheck[i].sWord + iLenMatched;
DEBUG_INFO( printf( "Continue with larger: [%s] at: [%s]\n", aCheck[i].sWord, sKeys2Match ) );
continue;
}
else
{
DEBUG_INFO( printf( "Gave-Up! %i !< %i or Pattern [%s] not compatible with last match\n", i, iMax, aCheck[i].sWord ) );
break;
}
}
if( pNextSpacer )
{
/* Token not followed by white space - can't match this [or any latter] pattern! */
if( ! acOmmit[(int)cSpacer] )
{
DEBUG_INFO( printf( "Skip... Pattern [%s] requires {WS}, cSpacer: %c\n", sKeys2Match, cSpacer ) );
i++;
if( ( iLenMatched = ( sKeys2Match - aCheck[i - 1].sWord ) ) == 0 )
{
sKeys2Match = NULL;
DEBUG_INFO( printf( "Continue with: [%s]\n", aCheck[i].sWord ) );
continue;
}
/* Is there a next potential Pattern. */
if( i < iMax && strncmp( aCheck[i - 1].sWord, aCheck[i].sWord, iLenMatched ) == 0 )
{
/* Same relative position, in the next Pattern. */
sKeys2Match = aCheck[i].sWord + iLenMatched;
DEBUG_INFO( printf( "Continue with: [%s] at: [%s]\n", aCheck[i].sWord, sKeys2Match ) );
continue;
}
else
{
DEBUG_INFO( printf( "Gave-Up! %i !< %i or Pattern [%s] not compatible with last match\n", i, iMax, aCheck[i].sWord ) );
break;
}
}
iKeyLen = pNextSpacer - sKeys2Match;
}
else
{
iKeyLen = strlen( sKeys2Match );
}
#ifdef LEX_ABBREVIATE
iLen2Match = iLen;
if( iLen2Match < LEX_ABBREVIATE && iLen2Match < iKeyLen )
{
iLen2Match = ( LEX_ABBREVIATE < iKeyLen ) ? LEX_ABBREVIATE : iKeyLen ;
}
if( iLen2Match > iKeyLen && i < iMax - 1 )
{
DEBUG_INFO( printf( "Trying Next... length mismatch - iKeyLen: %i iLen2Match: %i comparing: [%s] with: [%s]\n", iKeyLen, iLen2Match, sToken, sKeys2Match ) );
i++;
if( ( iLenMatched = ( sKeys2Match - aCheck[i - 1].sWord ) ) == 0 )
{
sKeys2Match = NULL;
DEBUG_INFO( printf( "Continue with: [%s]\n", aCheck[i].sWord ) );
continue;
}
/* Is there a next potential Pattern. */
if( i < iMax && strncmp( aCheck[i - 1].sWord, aCheck[i].sWord, iLenMatched ) == 0 )
{
/* Same relative position, in the next Pattern. */
sKeys2Match = aCheck[i].sWord + iLenMatched;
DEBUG_INFO( printf( "Continue with: [%s] at: [%s]\n", aCheck[i].sWord, sKeys2Match ) );
continue;
}
else
{
DEBUG_INFO( printf( "Gave-Up! %i !< %i or Pattern [%s] not compatible with last match\n", i, iMax, aCheck[i].sWord ) );
break;
}
}
DEBUG_INFO( printf( "iKeyLen: %i iLen2Match: %i comparing: [%s] with: [%s]\n", iKeyLen, iLen2Match, sToken, sKeys2Match ) );
iCompare = strncmp( (char*) sToken, sKeys2Match, iLen2Match );
#else
iCompare = strcmp( (char*) sToken, sKeys2Match );
#endif
if( iCompare == 0 ) /* Match found */
{
if( pNextSpacer == NULL ) /* Full Match! */
{
DEBUG_INFO( printf( "Saving Tentative %s [%s] == [%s]\n", sDesc, sToken, sKeys2Match ) );
iTentative = i;
iLenMatched = strlen( aCheck[i].sWord );
/* Saving this pointer of the input stream, we might have to get here again. */
szBaseBuffer = s_szBuffer; iBaseSize = iSize;
DEBUG_INFO( printf( "Saved Buffer Postion: %i at: [%s]\n", iBaseSize, szBaseBuffer ) );
/* No White Space after last Token! */
if( iHold || iPairToken )
{
DEBUG_INFO( printf( "No White space after [%s] Holding: %i\n", sToken, aiHold[0] ) );
break;
}
IsExtendedMatch :
i++;
/* Is there a next potential Pattern, that is an extended version of the current Pattern. */
if( i < iMax && strncmp( aCheck[i - 1].sWord, aCheck[i].sWord, iLenMatched ) == 0 )
{
if( strlen( aCheck[i].sWord ) > ( iLenMatched + 4 ) && ( pNextSpacer = strstr( aCheck[i].sWord + iLenMatched, "{WS}" ) ) != NULL )
{
/* Same relative position, in the next Pattern. */
sKeys2Match = pNextSpacer + 4;
DEBUG_INFO( printf( "Continue with: [%s] at: [%s]\n", aCheck[i].sWord, sKeys2Match ) );
}
else
{
DEBUG_INFO( printf( "Skip... - Not Extended: [%s]\n", aCheck[i].sWord ) );
goto IsExtendedMatch;
}
}
else
{
DEBUG_INFO( printf( "Gave-Up! %i !< %i or Pattern [%s] not extension of Pattern [%s]\n", i, iMax, aCheck[i].sWord, aCheck[iTentative].sWord ) );
break;
}
}
else
{
sKeys2Match = pNextSpacer + 4;
DEBUG_INFO( printf( "Partial %s Match! [%s] == [%s] - Looking for: [%s]\n", sDesc, sToken, aCheck[i].sWord, sKeys2Match ) );
/* Saving this pointer of the input stream, we might have to get here again. */
szBaseBuffer = s_szBuffer; iBaseSize = iSize;
DEBUG_INFO( printf( "Saved Buffer Postion: %i at: [%s]\n", iBaseSize, szBaseBuffer ) );
}
/* i may have been increased above - don't want to read next token if it won't get used! */
if( i < iMax )
{
bRecursive = TRUE;
cSpacer = chr;
DEBUG_INFO( printf( "Getting next Token...\n" ) );
SimpLex_GetNextToken();
continue;
}
}
else if( iCompare > 0 )
{
DEBUG_INFO( printf( "Trying Next %s Pattern... [%s] > [%s]\n", sDesc, sToken, sKeys2Match ) );
i++;
if( ( iLenMatched = ( sKeys2Match - aCheck[i - 1].sWord ) ) == 0 )
{
sKeys2Match = NULL;
DEBUG_INFO( printf( "Continue with: [%s]\n", aCheck[i].sWord ) );
continue;
}
/* Is there a next potential Pattern. */
if( i < iMax && strncmp( aCheck[i - 1].sWord, aCheck[i].sWord, iLenMatched ) == 0 )
{
/* Same relative position, in the next Pattern. */
sKeys2Match = aCheck[i].sWord + iLenMatched;
DEBUG_INFO( printf( "Continue with: [%s] at: [%s]\n", aCheck[i].sWord, sKeys2Match ) );
continue;
}
else
{
DEBUG_INFO( printf( "Gave-Up! %i !< %i or Pattern [%s] not compatible with previous match.\n", i, iMax, aCheck[i].sWord ) );
break;
}
}
else
{
DEBUG_INFO( printf( "Gave-Up! [%s] < [%s]\n", sToken, sKeys2Match ) );
break;
}
}
if( s_szBuffer != szBaseBuffer )
{
s_szBuffer = szBaseBuffer; iSize = iBaseSize; iHold = 0; iReturn = 0; iPairToken = 0;
DEBUG_INFO( printf( "Partial Match - Restored position: %i at: [%s]\n", iSize, s_szBuffer ) );
}
if( iTentative > -1 )
{
DEBUG_INFO( printf( "Reducing %s Pattern: %i [%s]\n", sDesc, iTentative, aCheck[iTentative].sWord ) );
bIgnoreWords = TRUE;
iRet = aCheck[ iTentative ].iToken;
if( iRet < LEX_CUSTOM_ACTION )
{
iRet = CUSTOM_ACTION( iRet );
}
}
else
{
iRet = 0;
}
}
#ifdef __cplusplus
YY_BUFFER_STATE yy_create_buffer( FILE * pFile, int iBufSize )
#else
void * yy_create_buffer( FILE * pFile, int iBufSize )
#endif
{
/* Avoid warning of unused symbols. */
(void) pFile;
(void) iBufSize;
iSize = 0;
#ifdef __cplusplus
return (YY_BUFFER_STATE) szLexBuffer;
#else
return (void*) szLexBuffer;
#endif
}
#ifdef __cplusplus
void yy_switch_to_buffer( YY_BUFFER_STATE pBuffer )
#else
void yy_switch_to_buffer( void * pBuffer )
#endif
{
/* Avoid warning of unused symbols. */
(void) pBuffer;
FORCE_REDUCE();
iSize = 0;
}
#ifdef __cplusplus
void yy_delete_buffer( YY_BUFFER_STATE pBuffer )
#else
void yy_delete_buffer( void * pBuffer )
#endif
{
/* Avoid warning of unused symbols. */
(void) pBuffer;
FORCE_REDUCE();
iSize = 0;
}
void * yy_bytes_buffer( char * pBuffer, int iBufSize )
{
s_szBuffer = pBuffer;
iSize = iBufSize;
if( bStart )
{
bStart = FALSE;
GenTrees();
INIT_ACTION();
}
return s_szBuffer;
}
static void GenTrees( void )
{
register unsigned int i;
register unsigned int iIndex;
i = 0;
while( i < 256 )
{
acOmmit[i] = 0;
acNewLine[i] = 0;
acReturn[i] = 0;
aPairNodes[i].iMin = -1;
aPairNodes[i].iMax = -1;
aSelfNodes[i].iMin = -1;
aSelfNodes[i].iMax = -1;
aKeyNodes[i].iMin = -1;
aKeyNodes[i].iMax = -1;
aWordNodes[i].iMin = -1;
aWordNodes[i].iMax = -1;
aRuleNodes[i].iMin = -1;
aRuleNodes[i].iMax = -1;
i++;
}
while( i < MAX_RULES )
{
aRuleNodes[i].iMin = -1;
aRuleNodes[i].iMax = -1;
i++;
}
i = 0;
while ( szOmmit[i] )
{
acOmmit[ (int)(szOmmit[i]) ] = 1;
i++;
}
i = 0;
while ( szNewLine[i] )
{
acNewLine[ (int)(szNewLine[i]) ] = 1;
i++;
}
i = 0;
while ( i < iDelimiters )
{
acReturn[ (int)(aDelimiters[i].cDelimiter) ] = aDelimiters[i].iToken;
i++;
}
i = 0;
while ( i < iPairs )
{
iIndex = aPairs[i].sStart[0];
if( aPairNodes[ iIndex ].iMin == -1 )
{
aPairNodes[ iIndex ].iMin = i;
}
aPairNodes[ iIndex ].iMax = i;
i++;
}
i = 0;
while ( i < iSelfs )
{
iIndex = aSelfs[i].sWord[0];
if( aSelfNodes[ iIndex ].iMin == -1 )
{
aSelfNodes[ iIndex ].iMin = i;
}
aSelfNodes[ iIndex ].iMax = i;
i++;
}
#ifdef USE_KEYWORDS
i = 0;
while ( i < iKeys )
{
iIndex = aKeys[i].sWord[0];
if( aKeyNodes[ iIndex ].iMin == -1 )
{
aKeyNodes[ iIndex ].iMin = i;
}
aKeyNodes[ iIndex ].iMax = i;
i++;
}
#endif
i = 0;
while ( i < iWords )
{
iIndex = aWords[i].sWord[0];
if( aWordNodes[ iIndex ].iMin == -1 )
{
aWordNodes[ iIndex ].iMin = i;
}
aWordNodes[ iIndex ].iMax = i;
i++;
}
/* Reduce logic excpects the Rules to be sorted. */
qsort( ( void * ) aiRules, iRules, LEX_RULE_SIZE, rulecmp );
i = 0;
while ( i < iRules )
{
iIndex = (unsigned int) aiRules[i][0];
if( iIndex > 1023 )
{
printf( "ERROR! Primary Token: %i out of range.\n", (int) iIndex );
exit( EXIT_FAILURE );
}
if( aRuleNodes[ iIndex ].iMin == -1 )
{
aRuleNodes[ iIndex ].iMin = i;
}
aRuleNodes[ iIndex ].iMax = i;
i++;
}
}
static int rulecmp( const void * pLeft, const void * pRight )
{
int *iLeftRule = (int*)( pLeft );
int *iRightRule = (int*)( pRight );
register unsigned int i = 0;
while( iLeftRule[i] == iRightRule[i] )
{
i++;
}
if( iLeftRule[i] < iRightRule[i] )
{
return -1;
}
else
{
return 1;
}
}