/tags/build45/harbour/source/compiler/simplex.c

# · C · 1581 lines · 1248 code · 215 blank · 118 comment · 194 complexity · e928d46ea9c8955fabbb6078df2641b9 MD5 · raw file

  1. /*
  2. * $Id: simplex.c 6424 2004-10-11 20:44:30Z druzus $
  3. */
  4. /*
  5. * Copyright 2000 Ron Pinkas <ron@profit-master.com>
  6. * www - http://www.Profit-Master.com
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2, or (at your option)
  11. * any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this software; see the file COPYING. If not, write to
  20. * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  21. * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
  22. *
  23. * As a special exception, the Harbour Project gives permission for
  24. * additional uses of the text contained in its release of Harbour.
  25. *
  26. * The exception is that, if you link the Harbour libraries with other
  27. * files to produce an executable, this does not by itself cause the
  28. * resulting executable to be covered by the GNU General Public License.
  29. * Your use of that executable is in no way restricted on account of
  30. * linking the Harbour library code into it.
  31. *
  32. * This exception does not however invalidate any other reasons why
  33. * the executable file might be covered by the GNU General Public License.
  34. *
  35. * This exception applies only to the code released by the Harbour
  36. * Project under the name Harbour. If you copy code from other
  37. * Harbour Project or Free Software Foundation releases into a copy of
  38. * Harbour, as the General Public License permits, the exception does
  39. * not apply to the code that you add in this way. To avoid misleading
  40. * anyone as to the status of such modified files, you must delete
  41. * this exception notice from them.
  42. *
  43. * If you write modifications of your own for Harbour, it is your choice
  44. * whether to permit this exception to apply to your modifications.
  45. * If you do not wish that, delete this exception notice.
  46. *
  47. */
  48. #include <stdio.h>
  49. #include <stdlib.h>
  50. #include <string.h>
  51. #include <limits.h>
  52. /* NOT overidable (yet). */
  53. #define MAX_MATCH 4
  54. #ifndef TOKEN_SIZE
  55. #define TOKEN_SIZE 64
  56. #endif
  57. /* Language Definitions Readability. */
  58. #define SELF_CONTAINED_WORDS_ARE static LEX_WORD aSelfs[] =
  59. #define LANGUAGE_KEY_WORDS_ARE static LEX_WORD aKeys[] =
  60. #define LANGUAGE_WORDS_ARE static LEX_WORD aWords[] =
  61. #define LANGUAGE_RULES_ARE static int aiRules[][ MAX_MATCH + 2 ] =
  62. #define ACCEPT_TOKEN_AND_DROP_DELIMITER_IF_ONE_OF_THESE(x) static char *szOmmit = x
  63. #define ACCEPT_TOKEN_AND_RETURN_DELIMITERS static LEX_DELIMITER aDelimiters[] =
  64. #define DELIMITER_BELONGS_TO_TOKEN_IF_ONE_OF_THESE(x) static char *szAppend = x
  65. #define START_NEW_LINE_IF_ONE_OF_THESE(x) static char *szNewLine = x
  66. #define IF_SEQUENCE_IS(a, b, c, d) {a, b, c, d
  67. #define REDUCE_TO(x, y) ,x, y }
  68. #define PASS_THROUGH() ,0, 0 }
  69. #define LEX_DELIMITER(x) {x
  70. #define LEX_WORD(x) {x
  71. #define AS_TOKEN(x) ,x }
  72. /* Streams ("Pairs"). */
  73. #define DEFINE_STREAM_AS_ONE_OF_THESE LEX_PAIR aPairs[] =
  74. #define START_WITH(x) { x,
  75. #define END_WITH(x) x,
  76. #define STOP_IF_ONE_OF_THESE(x) x,
  77. #define TEST_LEFT(x) x,
  78. #define AS_PAIR_TOKEN(x) x }
  79. #define STREAM_EXCEPTION( sPair, chrPair) \
  80. if( chrPair ) \
  81. { \
  82. printf( "Exception: %c for stream at: \"%s\"\n", chrPair, sPair ); \
  83. } \
  84. else \
  85. { \
  86. printf( "Exception: <EOF> for stream at: \"%s\"\n", chrPair, sPair ); \
  87. } \
  88. /* Pairs. */
  89. #ifndef MAX_STREAM
  90. #define MAX_STREAM 2048
  91. #endif
  92. #ifndef MAX_STREAM_STARTER
  93. #define MAX_STREAM_STARTER 2
  94. #endif
  95. #ifndef MAX_STREAM_TERMINATOR
  96. #define MAX_STREAM_TERMINATOR 2
  97. #endif
  98. #ifndef MAX_STREAM_EXCLUSIONS
  99. #define MAX_STREAM_EXCLUSIONS 2
  100. #endif
  101. static char sPair[ MAX_STREAM ];
  102. static char * sStart, * sTerm;
  103. static char * sExclude;
  104. static BOOL bTestLeft;
  105. static int iPairToken = 0;
  106. /* Self Contained Words. */
  107. static char sSelf[ TOKEN_SIZE ];
  108. typedef struct _LEX_DELIMITER
  109. {
  110. char cDelimiter;
  111. int iToken;
  112. } LEX_DELIMITER; /* support structure for KEYS and WORDS. */
  113. typedef struct _LEX_WORD
  114. {
  115. char sWord[ TOKEN_SIZE ];
  116. int iToken;
  117. } LEX_WORD; /* support structure for KEYS and WORDS. */
  118. typedef struct _LEX_PAIR
  119. {
  120. char sStart[MAX_STREAM_STARTER];
  121. char sTerm[MAX_STREAM_TERMINATOR];
  122. char sExclude[MAX_STREAM_EXCLUSIONS];
  123. BOOL bTestLeft;
  124. int iToken;
  125. } LEX_PAIR; /* support structure for Streams (Pairs). */
  126. #ifdef __cplusplus
  127. typedef struct yy_buffer_state *YY_BUFFER_STATE;
  128. #endif
  129. /* Above are NOT overidable !!! Need to precede the Language Definitions. */
  130. /* --------------------------------------------------------------------------------- */
  131. /* Overidables. */
  132. #define LEX_CUSTOM_ACTION -65
  133. #define DONT_REDUCE 1024
  134. #define YY_BUF_SIZE 16384
  135. #define MAX_RULES 1024
  136. #define YY_INPUT( a, b, c )
  137. /* Optional User Macros. */
  138. #define LEX_USER_SETUP()
  139. #define INIT_ACTION()
  140. #define INTERCEPT_ACTION(x)
  141. #define CUSTOM_ACTION(x)
  142. #define NEW_LINE_ACTION()
  143. #define ELEMENT_TOKEN(x,y) -1
  144. #define DEBUG_INFO(x)
  145. #define LEX_CASE(x)
  146. #define STREAM_OPEN(x)
  147. #define STREAM_APPEND(x) sPair[ iPairLen++ ] = x
  148. #include SLX_RULES
  149. /* Declarations. */
  150. FILE *yyin; /* currently yacc parsed file */
  151. extern void yyerror( char * ); /* parsing error management function */
  152. #ifdef __cplusplus
  153. extern "C" int yywrap( void );
  154. #else
  155. extern int yywrap( void ); /* manages the EOF of current processed file */
  156. #endif
  157. /* Use prototypes in function declarations. */
  158. #define YY_USE_PROTOS
  159. #ifdef YY_USE_PROTOS
  160. #define YY_PROTO(proto) proto
  161. #else
  162. #define YY_PROTO(proto) ()
  163. #endif
  164. /* ---------------------------------------------------------------------------------------------- */
  165. #define LEX_RULE_SIZE ( sizeof( (int) iRet ) * ( MAX_MATCH + 2 ) )
  166. #define LEX_WORD_SIZE ( sizeof( LEX_WORD ) )
  167. #define LEX_PAIR_SIZE ( sizeof( LEX_PAIR ) )
  168. #define LEX_DELIMITER_SIZE ( sizeof( LEX_DELIMITER ) )
  169. /* Using statics when we could use locals to eliminate Allocations and Deallocations each time yylex is called and returns. */
  170. /* Look ahead Tokens. */
  171. static int iHold = 0;
  172. static int aiHold[4];
  173. /* Pre-Checked Tokens. */
  174. static int iReturn = 0;
  175. static int aiReturn[4];
  176. /* yylex */
  177. static char * tmpPtr;
  178. static char sToken[TOKEN_SIZE];
  179. static unsigned int iLen = 0;
  180. static char chr, cPrev = 0;
  181. static unsigned int iLastToken = 0;
  182. static char szLexBuffer[ YY_BUF_SIZE ];
  183. static char * s_szBuffer;
  184. static unsigned int iSize = 0;
  185. static int iRet;
  186. static BOOL bTmp, bIgnoreWords = FALSE, bRecursive = FALSE;
  187. /* Lex emulation */
  188. char * yytext = (char *) sToken;
  189. int yyleng;
  190. /* NewLine Support. */
  191. static BOOL bNewLine = TRUE, bStart = TRUE;
  192. #ifdef USE_KEYWORDS
  193. static unsigned int iKeys = (int) ( sizeof( aKeys ) / LEX_WORD_SIZE );
  194. #endif
  195. static unsigned int iWords = (int) ( sizeof( aWords ) / LEX_WORD_SIZE );
  196. static unsigned int iSelfs = (int) ( sizeof( aSelfs ) / LEX_WORD_SIZE );
  197. static unsigned int iPairs = (int) ( sizeof( aPairs ) / LEX_PAIR_SIZE );
  198. static unsigned int iDelimiters = (int) ( sizeof( aDelimiters ) / LEX_DELIMITER_SIZE );
  199. static unsigned int iRules = (int) ( sizeof( aiRules ) / LEX_RULE_SIZE );
  200. typedef struct _TREE_NODE
  201. {
  202. int iMin;
  203. int iMax;
  204. } TREE_NODE; /* support structure for Streams (Pairs). */
  205. /* Indexing System. */
  206. static TREE_NODE aPairNodes[256], aSelfNodes[256], aKeyNodes[256], aWordNodes[256], aRuleNodes[MAX_RULES];
  207. static char acOmmit[256], acNewLine[256];
  208. static int acReturn[256];
  209. static int Reduce( int iToken );
  210. int SimpLex_GetNextToken( void );
  211. int SimpLex_CheckToken( void );
  212. void SimpLex_CheckWords( void );
  213. /* Indexing System. */
  214. static void GenTrees( void );
  215. static int rulecmp( const void * pLeft, const void * pRight );
  216. /* --------------------------------------------------------------------------------- */
  217. /* MACROS. */
  218. /* Readability Macros. */
  219. #define LEX_RULE_SIZE ( sizeof( (int) iRet ) * ( MAX_MATCH + 2 ) )
  220. #define LEX_WORD_SIZE ( sizeof( LEX_WORD ) )
  221. #define LEX_PAIR_SIZE ( sizeof( LEX_PAIR ) )
  222. #define IF_TOKEN_READY() if( iReturn )
  223. #define IF_TOKEN_ON_HOLD() if( iHold )
  224. #define RESET_LEX() { iLen = 0; iHold = 0; iReturn = 0; bNewLine = TRUE; bStart = TRUE; }
  225. #define FORCE_REDUCE() Reduce( 0 )
  226. #define HOLD_TOKEN(x) PUSH_TOKEN(x)
  227. #define IF_BEGIN_PAIR(chr) \
  228. if( aPairNodes[(int)chr].iMin == -1 ) \
  229. { \
  230. bTmp = FALSE; \
  231. } \
  232. else \
  233. { \
  234. register unsigned int i = aPairNodes[(int)chr].iMin, iMax = aPairNodes[(int)chr].iMax + 1, iStartLen; \
  235. register unsigned char chrStart; \
  236. unsigned int iLastPair = 0, iLastLen = 0; \
  237. \
  238. DEBUG_INFO( printf( "Checking %i Streams for %c At: >%s<\n", iPairs, chr, szBuffer - 1 ) ); \
  239. \
  240. while( i < iMax ) \
  241. { \
  242. iStartLen = 1; \
  243. \
  244. chrStart = LEX_CASE( *szBuffer ); \
  245. \
  246. while( aPairs[i].sStart[iStartLen] ) \
  247. { \
  248. if( chrStart != aPairs[i].sStart[iStartLen] ) \
  249. { \
  250. break; \
  251. } \
  252. \
  253. iStartLen++; \
  254. \
  255. chrStart = LEX_CASE( *( szBuffer + iStartLen - 1 ) ); \
  256. } \
  257. \
  258. /* Match */ \
  259. if( aPairs[i].sStart[iStartLen] == '\0' ) \
  260. { \
  261. if( iStartLen > iLastLen ) \
  262. { \
  263. iLastPair = i + 1; \
  264. iLastLen = iStartLen; \
  265. } \
  266. } \
  267. i++; \
  268. } \
  269. \
  270. bTmp = FALSE; \
  271. \
  272. if( iLastPair ) \
  273. { \
  274. iLastPair--; \
  275. STREAM_OPEN( aPairs[iLastPair].sStart )\
  276. { \
  277. bTmp = TRUE; \
  278. \
  279. /* Last charcter read. */\
  280. if( iStartLen > 1 ) chr = chrStart; \
  281. \
  282. /* Moving to next postion after the Stream Start position. */ \
  283. szBuffer += ( iLastLen - 1 ); \
  284. \
  285. sStart = (char *) aPairs[iLastPair].sStart; \
  286. sTerm = (char *) aPairs[iLastPair].sTerm; \
  287. sExclude = (char *) aPairs[iLastPair].sExclude; \
  288. bTestLeft = aPairs[iLastPair].bTestLeft; \
  289. iPairToken = aPairs[iLastPair].iToken; \
  290. \
  291. DEBUG_INFO( printf( "Looking for Stream Terminator: >%s< Exclusions >%s<\n", sTerm, sExclude ) ); \
  292. } \
  293. } \
  294. } \
  295. /* Begin New Pair. */ \
  296. if( bTmp )
  297. #define CHECK_SELF_CONTAINED(chr) \
  298. if( aSelfNodes[(int)chr].iMin != -1 ) \
  299. { \
  300. register unsigned int i = aSelfNodes[(int)chr].iMin, iMax = aSelfNodes[(int)chr].iMax + 1, iSelfLen; \
  301. register unsigned char chrSelf; \
  302. \
  303. DEBUG_INFO( printf( "Checking %i Selfs for %c At: >%s<\n", iSelfs, chr, szBuffer - 1 ) ); \
  304. \
  305. while( i < iMax ) \
  306. { \
  307. sSelf[0] = chr; \
  308. iSelfLen = 1; \
  309. chrSelf = LEX_CASE( *szBuffer ); \
  310. \
  311. while( aSelfs[i].sWord[iSelfLen] ) \
  312. { \
  313. if( aSelfs[i].sWord[iSelfLen] == chrSelf ) \
  314. { \
  315. sSelf[ iSelfLen ] = chrSelf; \
  316. } \
  317. else \
  318. { \
  319. break; \
  320. } \
  321. \
  322. iSelfLen++; \
  323. \
  324. chrSelf = LEX_CASE( *( szBuffer + iSelfLen - 1 ) ); \
  325. } \
  326. \
  327. /* Match */ \
  328. if( aSelfs[i].sWord[iSelfLen] == '\0' ) \
  329. { \
  330. /* Moving to next postion after the Self Contained Word. */ \
  331. szBuffer += ( iSelfLen - 1 ); \
  332. s_szBuffer = szBuffer; \
  333. \
  334. sSelf[ iSelfLen ] = '\0'; \
  335. iRet = aSelfs[i].iToken; \
  336. \
  337. if( iLen ) \
  338. { \
  339. DEBUG_INFO( printf( "Holding Self >%s<\n", sSelf ) ); \
  340. \
  341. HOLD_TOKEN( iRet ); \
  342. \
  343. /* Terminate current token and check it. */ \
  344. sToken[ iLen ] = '\0'; \
  345. \
  346. /* Last charcter read. */\
  347. chr = chrSelf;\
  348. \
  349. return SimpLex_CheckToken(); \
  350. } \
  351. else \
  352. { \
  353. DEBUG_INFO( printf( "Reducing Self >%s<\n", sSelf ) ); \
  354. bIgnoreWords = FALSE;\
  355. \
  356. if( bNewLine )\
  357. {\
  358. bNewLine = FALSE;\
  359. NEW_LINE_ACTION();\
  360. }\
  361. \
  362. /* Last charcter read. */\
  363. if( iSelfLen > 1 ) chr = chrSelf;\
  364. \
  365. return iRet; \
  366. } \
  367. } \
  368. \
  369. i++; \
  370. } \
  371. }
  372. #define IF_ABORT_PAIR(chrPair) \
  373. tmpPtr = sExclude; \
  374. while ( *tmpPtr && chrPair != *tmpPtr ) \
  375. { \
  376. tmpPtr++; \
  377. } \
  378. \
  379. /* Exception. */ \
  380. if( *tmpPtr )
  381. #define IF_APPEND_DELIMITER(chr) \
  382. /* Delimiter to Append? */ \
  383. tmpPtr = (char*) szAppend; \
  384. while ( *tmpPtr && chr != *tmpPtr ) tmpPtr++; \
  385. \
  386. /* Delimiter to Append found. */ \
  387. if( *tmpPtr )
  388. #ifndef IF_BELONG_LEFT
  389. #define IF_BELONG_LEFT(chr) \
  390. /* Give precedence to associate rules */ \
  391. DEBUG_INFO( printf( "Checking Left for: '%c' cPrev: '%c'\n", chr, cPrev ) ); \
  392. \
  393. if( 0 )
  394. #endif
  395. #define RETURN_READY_TOKEN() \
  396. \
  397. iReturn--; \
  398. iRet = aiReturn[iReturn]; \
  399. \
  400. DEBUG_INFO( printf( "Returning Ready: %i\n", iRet ) ); \
  401. \
  402. INTERCEPT_ACTION(iRet); \
  403. return iRet; \
  404. #define RELEASE_TOKEN() \
  405. \
  406. /* Last in First Out. */ \
  407. iHold--; \
  408. iRet = aiHold[iHold]; \
  409. \
  410. DEBUG_INFO( printf( "Released %i Now Holding %i Tokens: %i %i %i %i\n", iRet, iHold, aiHold[0], aiHold[1], aiHold[2], aiHold[3] ) ); \
  411. bIgnoreWords = FALSE;\
  412. \
  413. if( iRet < 256 ) \
  414. { \
  415. if( acNewLine[iRet] ) bNewLine = TRUE; \
  416. } \
  417. \
  418. DEBUG_INFO( printf( "Reducing Held: %i Pos: %i\n", iRet, iHold ) ); \
  419. LEX_RETURN( Reduce( iRet ) );
  420. #define LEX_RETURN(x) \
  421. \
  422. iRet = x;\
  423. \
  424. if( iRet < LEX_CUSTOM_ACTION ) \
  425. { \
  426. iRet = CUSTOM_ACTION(iRet); \
  427. } \
  428. \
  429. if( iRet ) \
  430. { \
  431. DEBUG_INFO( printf( "Returning: %i\n", iRet ) ); \
  432. \
  433. INTERCEPT_ACTION(iRet); \
  434. \
  435. return iRet; \
  436. } \
  437. else \
  438. { \
  439. goto Start; \
  440. }
  441. #define PUSH_TOKEN( iPushToken )\
  442. {\
  443. aiHold[ iHold++ ] = iPushToken;\
  444. DEBUG_INFO( printf("Now Holding %i Tokens: %i %i %i %i\n", iHold, aiHold[0], aiHold[1], aiHold[2], aiHold[3] ) ); \
  445. }
  446. #ifndef YY_DECL
  447. #define YY_DECL int yylex YY_PROTO(( void ))
  448. #endif
  449. YY_DECL
  450. {
  451. LEX_USER_SETUP();
  452. Start :
  453. IF_TOKEN_READY()
  454. {
  455. RETURN_READY_TOKEN();
  456. }
  457. IF_TOKEN_ON_HOLD()
  458. {
  459. RELEASE_TOKEN();
  460. }
  461. if( iSize == 0 )
  462. {
  463. if( bStart )
  464. {
  465. bStart = FALSE;
  466. GenTrees();
  467. INIT_ACTION();
  468. }
  469. YY_INPUT( (char*) szLexBuffer, iSize, YY_BUF_SIZE );
  470. if( iSize )
  471. {
  472. s_szBuffer = (char*) szLexBuffer;
  473. DEBUG_INFO( printf( "New Buffer: >%s<\n", szLexBuffer ) );
  474. }
  475. else
  476. {
  477. RESET_LEX();
  478. DEBUG_INFO( printf( "Returning: <EOF>\n" ) );
  479. return -1; \
  480. }
  481. }
  482. LEX_RETURN( Reduce( SimpLex_GetNextToken() ) )
  483. }
  484. int SimpLex_GetNextToken( void )
  485. {
  486. register char * szBuffer = s_szBuffer;
  487. iLen = 0;
  488. while ( 1 )
  489. {
  490. if ( iSize && *szBuffer )
  491. {
  492. if( iPairToken )
  493. {
  494. goto ProcessStream;
  495. }
  496. cPrev = chr;
  497. /* Get next character. */
  498. iSize--;
  499. chr = (*szBuffer++);
  500. /* Not using LEX_CASE() yet (white space)!!! */
  501. if( acOmmit[(int)chr] )
  502. {
  503. while( acOmmit[(int)(*szBuffer)] )
  504. {
  505. iSize--; szBuffer++;
  506. }
  507. if ( iLen )
  508. {
  509. /* Terminate current token and check it. */
  510. sToken[ iLen ] = '\0';
  511. s_szBuffer = szBuffer;
  512. DEBUG_INFO( printf( "Token: \"%s\" Ommited: \'%c\'\n", sToken, chr ) );
  513. return SimpLex_CheckToken();
  514. }
  515. else
  516. {
  517. continue;
  518. }
  519. }
  520. chr = LEX_CASE(chr);
  521. CHECK_SELF_CONTAINED(chr);
  522. /* New Pair ? */
  523. IF_BEGIN_PAIR( chr )
  524. {
  525. if( iLen )
  526. {
  527. DEBUG_INFO( printf( "Holding Stream Mode: '%c' Buffer = >%s<\n", chr, szBuffer ) );
  528. /* Terminate and Check Token to the left. */
  529. sToken[ iLen ] = '\0';
  530. s_szBuffer = szBuffer;
  531. DEBUG_INFO( printf( "Token: \"%s\" before New Pair at: \'%c\'\n", sToken, chr ) );
  532. return SimpLex_CheckToken();
  533. }
  534. ProcessStream :
  535. bIgnoreWords = FALSE;
  536. if( bTestLeft )
  537. {
  538. IF_BELONG_LEFT( chr )
  539. {
  540. /* Resetting. */
  541. iPairToken = 0;
  542. s_szBuffer = szBuffer;
  543. DEBUG_INFO( printf( "Reducing Left '%c'\n", chr ) );
  544. return (int) chr ;
  545. }
  546. }
  547. { register int iPairLen = 0;
  548. register char chrPair;
  549. /* Look for the terminator. */
  550. while ( *szBuffer )
  551. {
  552. /* Next Character. */
  553. chrPair = *szBuffer++ ;
  554. /* Terminator ? */
  555. if( chrPair == sTerm[0] )
  556. {
  557. register int iTermLen = 1;
  558. if( sTerm[1] )
  559. {
  560. register char chrTerm = *szBuffer; /* Not using LEX_CASE() here !!! */
  561. while( sTerm[iTermLen] )
  562. {
  563. if( chrTerm != sTerm[iTermLen] )
  564. {
  565. /* Last charcter read. */
  566. chr = chrTerm;
  567. break;
  568. }
  569. iTermLen++;
  570. chrTerm = *( szBuffer + iTermLen - 1 ); /* Not using LEX_CASE() here !!! */
  571. }
  572. }
  573. /* Match */ \
  574. if( sTerm[iTermLen] == '\0' ) \
  575. { \
  576. /* Moving to next postion after the Stream Terminator. */ \
  577. szBuffer += ( iTermLen - 1 ); \
  578. sPair[ iPairLen ] = '\0';
  579. if( bNewLine )
  580. {
  581. bNewLine = FALSE;
  582. NEW_LINE_ACTION();
  583. }
  584. iRet = iPairToken;
  585. /* Resetting. */
  586. iPairToken = 0;
  587. s_szBuffer = szBuffer;
  588. DEBUG_INFO( printf( "Returning Pair = >%s<\n", sPair ) );
  589. return iRet;
  590. }
  591. }
  592. /* Check if exception. */
  593. IF_ABORT_PAIR( chrPair )
  594. {
  595. sPair[ iPairLen ] = '\0';
  596. /* Resetting. */
  597. iPairToken = 0;
  598. /* Last charcter read. */
  599. chr = chrPair;
  600. STREAM_EXCEPTION( sPair, chrPair );
  601. s_szBuffer = szBuffer;
  602. return iPairToken;
  603. }
  604. else
  605. {
  606. STREAM_APPEND( chrPair );
  607. }
  608. }
  609. }
  610. /* Resetting. */
  611. iPairToken = 0;
  612. /* EOF */
  613. STREAM_EXCEPTION( sPair, NULL );
  614. s_szBuffer = szBuffer;
  615. return iPairToken;
  616. }
  617. /* End Pairs. */
  618. /* NewLine ? */
  619. if( acNewLine[(int)chr] )
  620. {
  621. while( acNewLine[(int)(*szBuffer)] )
  622. {
  623. iSize--; szBuffer++;
  624. }
  625. s_szBuffer = szBuffer;
  626. if( iLen )
  627. {
  628. /* Will return NewLine on next call. */
  629. HOLD_TOKEN( chr );
  630. /* Terminate current token and check it. */
  631. sToken[ iLen ] = '\0';
  632. DEBUG_INFO( printf( "Token: \"%s\" at <NewLine> Holding: \'%c\'\n", sToken, chr ) );
  633. return SimpLex_CheckToken();
  634. }
  635. else
  636. {
  637. DEBUG_INFO( printf( "Reducing NewLine '%c'\n", chr ) );
  638. bIgnoreWords = FALSE;
  639. bNewLine = TRUE;
  640. return (int) chr;
  641. }
  642. }
  643. #ifdef USE_BELONGS
  644. IF_APPEND_DELIMITER( chr )
  645. {
  646. /* Append and Terminate current token and check it. */
  647. sToken[ iLen++ ] = chr;
  648. sToken[ iLen ] = '\0';
  649. s_szBuffer = szBuffer;
  650. DEBUG_INFO( printf( "Token: \"%s\" Appended: \'%c\'\n", sToken, chr ) );
  651. return SimpLex_CheckToken();
  652. }
  653. #endif
  654. if( acReturn[(int)chr] )
  655. {
  656. s_szBuffer = szBuffer;
  657. if( iLen )
  658. {
  659. /* Will be returned on next cycle. */
  660. HOLD_TOKEN( acReturn[(int)chr] );
  661. /* Terminate current token and check it. */
  662. sToken[ iLen ] = '\0';
  663. DEBUG_INFO( printf( "Token: \"%s\" Holding: \'%c\' As: %i \n", sToken, chr, iRet ) );
  664. return SimpLex_CheckToken();
  665. }
  666. else
  667. {
  668. bIgnoreWords = FALSE;
  669. if( bNewLine )
  670. {
  671. bNewLine = FALSE;
  672. NEW_LINE_ACTION();
  673. }
  674. DEBUG_INFO( printf( "Reducing Delimiter: '%c' As: %i\n", chr, acReturn[(int)chr] ) );
  675. return acReturn[(int)chr];
  676. }
  677. }
  678. /* Acumulate and scan next Charcter. */
  679. sToken[ iLen++ ] = chr;
  680. continue;
  681. }
  682. else
  683. {
  684. YY_INPUT( (char*) szLexBuffer, iSize, YY_BUF_SIZE );
  685. if( iSize )
  686. {
  687. szBuffer = (char*) szLexBuffer;
  688. continue;
  689. }
  690. else
  691. {
  692. if( iLen )
  693. {
  694. /* <EOF> */
  695. HOLD_TOKEN( -1 );
  696. /* Terminate current token and check it. */
  697. sToken[ iLen ] = '\0';
  698. s_szBuffer = szBuffer;
  699. DEBUG_INFO( printf( "Token: \"%s\" at: \'<EOF>\'\n", sToken ) );
  700. return SimpLex_CheckToken();
  701. }
  702. else
  703. {
  704. s_szBuffer = szBuffer;
  705. DEBUG_INFO( printf( "Returning: <EOF>\n", iRet ) ); \
  706. return -1; \
  707. }
  708. }
  709. }
  710. }
  711. }
  712. int SimpLex_CheckToken( void )
  713. {
  714. if( bRecursive )
  715. {
  716. return 0;
  717. }
  718. else
  719. {
  720. bRecursive = TRUE;
  721. }
  722. if( bNewLine )
  723. {
  724. bIgnoreWords = FALSE;
  725. NEW_LINE_ACTION();
  726. #ifdef USE_KEYWORDS
  727. SimpLex_CheckWords();
  728. if( iRet )
  729. {
  730. bRecursive = FALSE;
  731. /* bIgnoreWords and bNewLine were handled by SimpLex_CheckWords(). */
  732. return iRet;
  733. }
  734. #endif
  735. }
  736. if( bIgnoreWords )
  737. {
  738. DEBUG_INFO( printf( "Skiped Words for Word: %s\n", (char*) sToken ) );
  739. bIgnoreWords = FALSE;
  740. }
  741. else
  742. {
  743. SimpLex_CheckWords();
  744. if( iRet )
  745. {
  746. bRecursive = FALSE;
  747. return iRet;
  748. }
  749. }
  750. DEBUG_INFO( printf( "Reducing Element: \"%s\"\n", (char*) sToken ) );
  751. iRet = ELEMENT_TOKEN( (char*)sToken, iLen );
  752. bRecursive = FALSE;
  753. return iRet;
  754. }
  755. int Reduce( int iToken )
  756. {
  757. BeginReduce :
  758. if( iToken < LEX_CUSTOM_ACTION )
  759. {
  760. iToken = CUSTOM_ACTION( iToken ); \
  761. }
  762. if( iToken > DONT_REDUCE )
  763. {
  764. iLastToken = ( iToken - DONT_REDUCE );
  765. DEBUG_INFO( printf( "Returning Dont Reduce %i\n", iLastToken ) );
  766. return iLastToken;
  767. }
  768. else if( iToken <= 0 || iToken >= MAX_RULES )
  769. {
  770. DEBUG_INFO( printf( "Passing through (out of range): %i\n", iToken ) );
  771. return iToken;
  772. }
  773. iLastToken = iToken;
  774. /* No Rules for this token. */
  775. if( aRuleNodes[ iToken ].iMin == -1 )
  776. {
  777. DEBUG_INFO( printf( "Passing through: %i\n", iToken ) );
  778. return iToken;
  779. }
  780. else
  781. {
  782. register unsigned int i = (unsigned int)(aRuleNodes[ iToken ].iMin), iMax = (unsigned int)(aRuleNodes[ iToken ].iMax);
  783. register unsigned int iTentative = 0, iMatched = 1;
  784. DEBUG_INFO( printf( "Scaning Prospects %i-%i at Pos: 0 for Token: %i\n", i, iMax -1, iToken ) );
  785. {
  786. FoundProspect :
  787. DEBUG_INFO( printf( "Prospect of %i Tokens - Testing Token: %i\n", iMatched, iToken ) );
  788. if( iMatched == MAX_MATCH || aiRules[i][iMatched] == 0 )
  789. {
  790. DEBUG_INFO( printf( "Saving Tentative %i - Found match of %i Tokens at Token: %i\n", i, iMatched, iToken ) );
  791. iTentative = i;
  792. }
  793. else
  794. {
  795. DEBUG_INFO( printf( "Partial Match - Get next Token after Token: %i\n", iToken ) );
  796. if( iHold )
  797. {
  798. iHold--;
  799. iToken = aiHold[ iHold ];
  800. bIgnoreWords = FALSE;
  801. if( iToken < 256 )
  802. {
  803. if( acNewLine[iToken] ) bNewLine = TRUE;
  804. }
  805. }
  806. else
  807. {
  808. iToken = SimpLex_GetNextToken();
  809. }
  810. if( iToken < LEX_CUSTOM_ACTION )
  811. {
  812. iToken = CUSTOM_ACTION( iToken ); \
  813. }
  814. if( iToken > DONT_REDUCE )
  815. {
  816. DEBUG_INFO( printf( "Reduce Forced for Token: %i\n", iToken - DONT_REDUCE ) );
  817. aiHold[iHold++] = iToken;
  818. goto AfterScanRules;
  819. }
  820. else
  821. {
  822. iLastToken = iToken;
  823. }
  824. if( aiRules[i][iMatched] == iToken )
  825. {
  826. /* Continue... Still a prospect. */
  827. DEBUG_INFO( printf( "Accepted Token: %i - Continue with this Rule...\n", iToken ) );
  828. iMatched++;
  829. goto FoundProspect;
  830. }
  831. else if( aiRules[i][iMatched] > iToken )
  832. {
  833. DEBUG_INFO( printf( "Rejected Token: %i - Giving up...\n", iToken ) );
  834. aiHold[iHold++] = iToken;
  835. goto AfterScanRules;
  836. }
  837. else
  838. {
  839. DEBUG_INFO( printf( "Rejected Token: %i - Continue with next Rule...\n", iToken ) );
  840. aiHold[iHold++] = iToken;
  841. }
  842. }
  843. if( i < iMax )
  844. {
  845. register unsigned int j = 1;
  846. DEBUG_INFO( printf( "Checking if next rule is extension of last Rule\n" ) );
  847. while( j < iMatched )
  848. {
  849. if( aiRules[i][j] != aiRules[i+1][j] )
  850. {
  851. break;
  852. }
  853. j++;
  854. }
  855. if( j < iMatched )
  856. {
  857. DEBUG_INFO( printf( "Rejected Rule - Not an extension of previous - Giving up...\n" ) );
  858. }
  859. else
  860. {
  861. DEBUG_INFO( printf( "Accepted Next Rule...\n" ) );
  862. i++;
  863. goto FoundProspect;
  864. }
  865. }
  866. else
  867. {
  868. DEBUG_INFO( printf( "No More prospects...\n" ) );
  869. }
  870. }
  871. AfterScanRules :
  872. if( iTentative )
  873. {
  874. DEBUG_INFO( printf( "Processing Tentative: %i\n", iTentative ) );
  875. while( iMatched > 1 && aiRules[i][iMatched - 1] && aiRules[iTentative][iMatched - 1] == 0 )
  876. {
  877. DEBUG_INFO( printf( "Reclaimed Token: %i\n", aiRules[i][iMatched - 1] ) );
  878. aiHold[iHold++] = aiRules[i][iMatched - 1];
  879. iMatched--;
  880. }
  881. if( aiRules[iTentative][MAX_MATCH] )
  882. {
  883. DEBUG_INFO( printf( "Reducing Rule: %i Found %i Tokens\n", iTentative, iMatched ) );
  884. if( aiRules[iTentative][MAX_MATCH + 1] )
  885. {
  886. DEBUG_INFO( printf( "Pushing Reduction: %i\n", aiRules[iTentative][MAX_MATCH + 1] ) );
  887. aiHold[iHold++] = aiRules[iTentative][MAX_MATCH + 1];
  888. }
  889. DEBUG_INFO( printf( "Recycling Reduction: %i\n", aiRules[iTentative][MAX_MATCH] ) );
  890. iToken = aiRules[iTentative][MAX_MATCH];
  891. goto BeginReduce;
  892. }
  893. else
  894. {
  895. DEBUG_INFO( printf( "Passing Through %i Tokens\n", iMatched ) );
  896. while( iMatched > 1 )
  897. {
  898. iMatched--;
  899. DEBUG_INFO( printf( "Stacking Return: %i\n", aiRules[iTentative][iMatched] ) );
  900. aiReturn[iReturn++] = aiRules[iTentative][iMatched];
  901. }
  902. DEBUG_INFO( printf( "Returning: %i\n", aiRules[iTentative][0] ) );
  903. return aiRules[iTentative][0];
  904. }
  905. }
  906. else
  907. {
  908. while( iMatched > 1 )
  909. {
  910. iMatched--;
  911. DEBUG_INFO( printf( "Pushing: %i\n", aiRules[i][iMatched] ) );
  912. aiHold[iHold++] = aiRules[i][iMatched];
  913. }
  914. DEBUG_INFO( printf( "Returning Shifted Left: %i\n", aiRules[i][0] ) );
  915. return aiRules[i][0];
  916. }
  917. }
  918. }
  919. void SimpLex_CheckWords( void )
  920. {
  921. int iTentative = -1, iCompare;
  922. unsigned int i, iMax, iLenMatched, iBaseSize, iKeyLen;
  923. char *pNextSpacer, *sKeys2Match = NULL, *szBaseBuffer = s_szBuffer, cSpacer = chr;
  924. LEX_WORD *aCheck;
  925. #ifdef DEBUG_LEX
  926. char sKeyDesc[] = "Key", sWordDesc[] = "Word", *sDesc;
  927. #endif
  928. #ifdef LEX_ABBREVIATE
  929. unsigned int iLen2Match;
  930. #endif
  931. #ifdef USE_KEYWORDS
  932. if( bNewLine )
  933. {
  934. i = aKeyNodes[ (int)(sToken[0]) ].iMin;
  935. iMax = aKeyNodes[ (int)(sToken[0]) ].iMax + 1;
  936. aCheck = (LEX_WORD*) ( &(aKeys[0]) );
  937. #ifdef DEBUG_LEX
  938. sDesc = (char*) sKeyDesc;
  939. #endif
  940. }
  941. else
  942. #endif
  943. {
  944. i = aWordNodes[ (int)(sToken[0]) ].iMin;
  945. iMax = aWordNodes[ (int)(sToken[0]) ].iMax + 1;
  946. aCheck = (LEX_WORD*) ( &( aWords[0] ) );
  947. #ifdef DEBUG_LEX
  948. sDesc = (char*) sWordDesc;
  949. #endif
  950. }
  951. bNewLine = FALSE;
  952. DEBUG_INFO( printf( "Pre-Scaning %ss for Token: %s at Positions: %i-%i\n", sDesc, (char*) sToken, i, iMax -1 ) );
  953. while( i < iMax )
  954. {
  955. if( sToken[1] < aCheck[i].sWord[1] )
  956. {
  957. DEBUG_INFO( printf( "Gave-Up! Token [%s] < Pattern [%s]\n", sToken, aCheck[i].sWord ) );
  958. iRet = 0;
  959. return;
  960. }
  961. else if( sToken[1] > aCheck[i].sWord[1] )
  962. {
  963. DEBUG_INFO( printf( "Skip... %s [%s] < [%s]\n", sDesc, aCheck[i].sWord, sToken ) );
  964. i++;
  965. DEBUG_INFO( printf( "Continue with larger: [%s]\n", aCheck[i].sWord ) );
  966. continue;
  967. }
  968. else
  969. {
  970. break;
  971. }
  972. }
  973. while( i < iMax )
  974. {
  975. if( sKeys2Match )
  976. {
  977. pNextSpacer = strstr( sKeys2Match, "{WS}" );
  978. }
  979. else
  980. {
  981. sKeys2Match = aCheck[ i ].sWord;
  982. pNextSpacer = strstr( sKeys2Match, "{WS}" );
  983. }
  984. if( sToken[0] < sKeys2Match[0] )
  985. {
  986. DEBUG_INFO( printf( "Gave-Up! Token [%s] < Pattern [%s]\n", sToken, sKeys2Match ) );
  987. break;
  988. }
  989. else if( sToken[0] > sKeys2Match[0] )
  990. {
  991. DEBUG_INFO( printf( "Skip... %s [%s] < [%s]\n", sDesc, sKeys2Match, sToken ) );
  992. i++;
  993. if( ( iLenMatched = ( sKeys2Match - aCheck[i - 1].sWord ) ) == 0 )
  994. {
  995. sKeys2Match = NULL;
  996. DEBUG_INFO( printf( "Continue with larger: [%s]\n", aCheck[i].sWord ) );
  997. continue;
  998. }
  999. /* Is there a next potential Pattern. */
  1000. if( i < iMax && strncmp( aCheck[i - 1].sWord, aCheck[i].sWord, iLenMatched ) == 0 )
  1001. {
  1002. /* Same relative position, in the next Pattern. */
  1003. sKeys2Match = aCheck[i].sWord + iLenMatched;
  1004. DEBUG_INFO( printf( "Continue with larger: [%s] at: [%s]\n", aCheck[i].sWord, sKeys2Match ) );
  1005. continue;
  1006. }
  1007. else
  1008. {
  1009. DEBUG_INFO( printf( "Gave-Up! %i !< %i or Pattern [%s] not compatible with last match\n", i, iMax, aCheck[i].sWord ) );
  1010. break;
  1011. }
  1012. }
  1013. if( pNextSpacer )
  1014. {
  1015. /* Token not followed by white space - can't match this [or any latter] pattern! */
  1016. if( ! acOmmit[(int)cSpacer] )
  1017. {
  1018. DEBUG_INFO( printf( "Skip... Pattern [%s] requires {WS}, cSpacer: %c\n", sKeys2Match, cSpacer ) );
  1019. i++;
  1020. if( ( iLenMatched = ( sKeys2Match - aCheck[i - 1].sWord ) ) == 0 )
  1021. {
  1022. sKeys2Match = NULL;
  1023. DEBUG_INFO( printf( "Continue with: [%s]\n", aCheck[i].sWord ) );
  1024. continue;
  1025. }
  1026. /* Is there a next potential Pattern. */
  1027. if( i < iMax && strncmp( aCheck[i - 1].sWord, aCheck[i].sWord, iLenMatched ) == 0 )
  1028. {
  1029. /* Same relative position, in the next Pattern. */
  1030. sKeys2Match = aCheck[i].sWord + iLenMatched;
  1031. DEBUG_INFO( printf( "Continue with: [%s] at: [%s]\n", aCheck[i].sWord, sKeys2Match ) );
  1032. continue;
  1033. }
  1034. else
  1035. {
  1036. DEBUG_INFO( printf( "Gave-Up! %i !< %i or Pattern [%s] not compatible with last match\n", i, iMax, aCheck[i].sWord ) );
  1037. break;
  1038. }
  1039. }
  1040. iKeyLen = pNextSpacer - sKeys2Match;
  1041. }
  1042. else
  1043. {
  1044. iKeyLen = strlen( sKeys2Match );
  1045. }
  1046. #ifdef LEX_ABBREVIATE
  1047. iLen2Match = iLen;
  1048. if( iLen2Match < LEX_ABBREVIATE && iLen2Match < iKeyLen )
  1049. {
  1050. iLen2Match = ( LEX_ABBREVIATE < iKeyLen ) ? LEX_ABBREVIATE : iKeyLen ;
  1051. }
  1052. if( iLen2Match > iKeyLen && i < iMax - 1 )
  1053. {
  1054. DEBUG_INFO( printf( "Trying Next... length mismatch - iKeyLen: %i iLen2Match: %i comparing: [%s] with: [%s]\n", iKeyLen, iLen2Match, sToken, sKeys2Match ) );
  1055. i++;
  1056. if( ( iLenMatched = ( sKeys2Match - aCheck[i - 1].sWord ) ) == 0 )
  1057. {
  1058. sKeys2Match = NULL;
  1059. DEBUG_INFO( printf( "Continue with: [%s]\n", aCheck[i].sWord ) );
  1060. continue;
  1061. }
  1062. /* Is there a next potential Pattern. */
  1063. if( i < iMax && strncmp( aCheck[i - 1].sWord, aCheck[i].sWord, iLenMatched ) == 0 )
  1064. {
  1065. /* Same relative position, in the next Pattern. */
  1066. sKeys2Match = aCheck[i].sWord + iLenMatched;
  1067. DEBUG_INFO( printf( "Continue with: [%s] at: [%s]\n", aCheck[i].sWord, sKeys2Match ) );
  1068. continue;
  1069. }
  1070. else
  1071. {
  1072. DEBUG_INFO( printf( "Gave-Up! %i !< %i or Pattern [%s] not compatible with last match\n", i, iMax, aCheck[i].sWord ) );
  1073. break;
  1074. }
  1075. }
  1076. DEBUG_INFO( printf( "iKeyLen: %i iLen2Match: %i comparing: [%s] with: [%s]\n", iKeyLen, iLen2Match, sToken, sKeys2Match ) );
  1077. iCompare = strncmp( (char*) sToken, sKeys2Match, iLen2Match );
  1078. #else
  1079. iCompare = strcmp( (char*) sToken, sKeys2Match );
  1080. #endif
  1081. if( iCompare == 0 ) /* Match found */
  1082. {
  1083. if( pNextSpacer == NULL ) /* Full Match! */
  1084. {
  1085. DEBUG_INFO( printf( "Saving Tentative %s [%s] == [%s]\n", sDesc, sToken, sKeys2Match ) );
  1086. iTentative = i;
  1087. iLenMatched = strlen( aCheck[i].sWord );
  1088. /* Saving this pointer of the input stream, we might have to get here again. */
  1089. szBaseBuffer = s_szBuffer; iBaseSize = iSize;
  1090. DEBUG_INFO( printf( "Saved Buffer Postion: %i at: [%s]\n", iBaseSize, szBaseBuffer ) );
  1091. /* No White Space after last Token! */
  1092. if( iHold || iPairToken )
  1093. {
  1094. DEBUG_INFO( printf( "No White space after [%s] Holding: %i\n", sToken, aiHold[0] ) );
  1095. break;
  1096. }
  1097. IsExtendedMatch :
  1098. i++;
  1099. /* Is there a next potential Pattern, that is an extended version of the current Pattern. */
  1100. if( i < iMax && strncmp( aCheck[i - 1].sWord, aCheck[i].sWord, iLenMatched ) == 0 )
  1101. {
  1102. if( strlen( aCheck[i].sWord ) > ( iLenMatched + 4 ) && ( pNextSpacer = strstr( aCheck[i].sWord + iLenMatched, "{WS}" ) ) != NULL )
  1103. {
  1104. /* Same relative position, in the next Pattern. */
  1105. sKeys2Match = pNextSpacer + 4;
  1106. DEBUG_INFO( printf( "Continue with: [%s] at: [%s]\n", aCheck[i].sWord, sKeys2Match ) );
  1107. }
  1108. else
  1109. {
  1110. DEBUG_INFO( printf( "Skip... - Not Extended: [%s]\n", aCheck[i].sWord ) );
  1111. goto IsExtendedMatch;
  1112. }
  1113. }
  1114. else
  1115. {
  1116. DEBUG_INFO( printf( "Gave-Up! %i !< %i or Pattern [%s] not extension of Pattern [%s]\n", i, iMax, aCheck[i].sWord, aCheck[iTentative].sWord ) );
  1117. break;
  1118. }
  1119. }
  1120. else
  1121. {
  1122. sKeys2Match = pNextSpacer + 4;
  1123. DEBUG_INFO( printf( "Partial %s Match! [%s] == [%s] - Looking for: [%s]\n", sDesc, sToken, aCheck[i].sWord, sKeys2Match ) );
  1124. /* Saving this pointer of the input stream, we might have to get here again. */
  1125. szBaseBuffer = s_szBuffer; iBaseSize = iSize;
  1126. DEBUG_INFO( printf( "Saved Buffer Postion: %i at: [%s]\n", iBaseSize, szBaseBuffer ) );
  1127. }
  1128. /* i may have been increased above - don't want to read next token if it won't get used! */
  1129. if( i < iMax )
  1130. {
  1131. bRecursive = TRUE;
  1132. cSpacer = chr;
  1133. DEBUG_INFO( printf( "Getting next Token...\n" ) );
  1134. SimpLex_GetNextToken();
  1135. continue;
  1136. }
  1137. }
  1138. else if( iCompare > 0 )
  1139. {
  1140. DEBUG_INFO( printf( "Trying Next %s Pattern... [%s] > [%s]\n", sDesc, sToken, sKeys2Match ) );
  1141. i++;
  1142. if( ( iLenMatched = ( sKeys2Match - aCheck[i - 1].sWord ) ) == 0 )
  1143. {
  1144. sKeys2Match = NULL;
  1145. DEBUG_INFO( printf( "Continue with: [%s]\n", aCheck[i].sWord ) );
  1146. continue;
  1147. }
  1148. /* Is there a next potential Pattern. */
  1149. if( i < iMax && strncmp( aCheck[i - 1].sWord, aCheck[i].sWord, iLenMatched ) == 0 )
  1150. {
  1151. /* Same relative position, in the next Pattern. */
  1152. sKeys2Match = aCheck[i].sWord + iLenMatched;
  1153. DEBUG_INFO( printf( "Continue with: [%s] at: [%s]\n", aCheck[i].sWord, sKeys2Match ) );
  1154. continue;
  1155. }
  1156. else
  1157. {
  1158. DEBUG_INFO( printf( "Gave-Up! %i !< %i or Pattern [%s] not compatible with previous match.\n", i, iMax, aCheck[i].sWord ) );
  1159. break;
  1160. }
  1161. }
  1162. else
  1163. {
  1164. DEBUG_INFO( printf( "Gave-Up! [%s] < [%s]\n", sToken, sKeys2Match ) );
  1165. break;
  1166. }
  1167. }
  1168. if( s_szBuffer != szBaseBuffer )
  1169. {
  1170. s_szBuffer = szBaseBuffer; iSize = iBaseSize; iHold = 0; iReturn = 0; iPairToken = 0;
  1171. DEBUG_INFO( printf( "Partial Match - Restored position: %i at: [%s]\n", iSize, s_szBuffer ) );
  1172. }
  1173. if( iTentative > -1 )
  1174. {
  1175. DEBUG_INFO( printf( "Reducing %s Pattern: %i [%s]\n", sDesc, iTentative, aCheck[iTentative].sWord ) );
  1176. bIgnoreWords = TRUE;
  1177. iRet = aCheck[ iTentative ].iToken;
  1178. if( iRet < LEX_CUSTOM_ACTION )
  1179. {
  1180. iRet = CUSTOM_ACTION( iRet );
  1181. }
  1182. }
  1183. else
  1184. {
  1185. iRet = 0;
  1186. }
  1187. }
  1188. #ifdef __cplusplus
  1189. YY_BUFFER_STATE yy_create_buffer( FILE * pFile, int iBufSize )
  1190. #else
  1191. void * yy_create_buffer( FILE * pFile, int iBufSize )
  1192. #endif
  1193. {
  1194. /* Avoid warning of unused symbols. */
  1195. (void) pFile;
  1196. (void) iBufSize;
  1197. iSize = 0;
  1198. #ifdef __cplusplus
  1199. return (YY_BUFFER_STATE) szLexBuffer;
  1200. #else
  1201. return (void*) szLexBuffer;
  1202. #endif
  1203. }
  1204. #ifdef __cplusplus
  1205. void yy_switch_to_buffer( YY_BUFFER_STATE pBuffer )
  1206. #else
  1207. void yy_switch_to_buffer( void * pBuffer )
  1208. #endif
  1209. {
  1210. /* Avoid warning of unused symbols. */
  1211. (void) pBuffer;
  1212. FORCE_REDUCE();
  1213. iSize = 0;
  1214. }
  1215. #ifdef __cplusplus
  1216. void yy_delete_buffer( YY_BUFFER_STATE pBuffer )
  1217. #else
  1218. void yy_delete_buffer( void * pBuffer )
  1219. #endif
  1220. {
  1221. /* Avoid warning of unused symbols. */
  1222. (void) pBuffer;
  1223. FORCE_REDUCE();
  1224. iSize = 0;
  1225. }
  1226. void * yy_bytes_buffer( char * pBuffer, int iBufSize )
  1227. {
  1228. s_szBuffer = pBuffer;
  1229. iSize = iBufSize;
  1230. if( bStart )
  1231. {
  1232. bStart = FALSE;
  1233. GenTrees();
  1234. INIT_ACTION();
  1235. }
  1236. return s_szBuffer;
  1237. }
  1238. static void GenTrees( void )
  1239. {
  1240. register unsigned int i;
  1241. register unsigned int iIndex;
  1242. i = 0;
  1243. while( i < 256 )
  1244. {
  1245. acOmmit[i] = 0;
  1246. acNewLine[i] = 0;
  1247. acReturn[i] = 0;
  1248. aPairNodes[i].iMin = -1;
  1249. aPairNodes[i].iMax = -1;
  1250. aSelfNodes[i].iMin = -1;
  1251. aSelfNodes[i].iMax = -1;
  1252. aKeyNodes[i].iMin = -1;
  1253. aKeyNodes[i].iMax = -1;
  1254. aWordNodes[i].iMin = -1;
  1255. aWordNodes[i].iMax = -1;
  1256. aRuleNodes[i].iMin = -1;
  1257. aRuleNodes[i].iMax = -1;
  1258. i++;
  1259. }
  1260. while( i < MAX_RULES )
  1261. {
  1262. aRuleNodes[i].iMin = -1;
  1263. aRuleNodes[i].iMax = -1;
  1264. i++;
  1265. }
  1266. i = 0;
  1267. while ( szOmmit[i] )
  1268. {
  1269. acOmmit[ (int)(szOmmit[i]) ] = 1;
  1270. i++;
  1271. }
  1272. i = 0;
  1273. while ( szNewLine[i] )
  1274. {
  1275. acNewLine[ (int)(szNewLine[i]) ] = 1;
  1276. i++;
  1277. }
  1278. i = 0;
  1279. while ( i < iDelimiters )
  1280. {
  1281. acReturn[ (int)(aDelimiters[i].cDelimiter) ] = aDelimiters[i].iToken;
  1282. i++;
  1283. }
  1284. i = 0;
  1285. while ( i < iPairs )
  1286. {
  1287. iIndex = aPairs[i].sStart[0];
  1288. if( aPairNodes[ iIndex ].iMin == -1 )
  1289. {
  1290. aPairNodes[ iIndex ].iMin = i;
  1291. }
  1292. aPairNodes[ iIndex ].iMax = i;
  1293. i++;
  1294. }
  1295. i = 0;
  1296. while ( i < iSelfs )
  1297. {
  1298. iIndex = aSelfs[i].sWord[0];
  1299. if( aSelfNodes[ iIndex ].iMin == -1 )
  1300. {
  1301. aSelfNodes[ iIndex ].iMin = i;
  1302. }
  1303. aSelfNodes[ iIndex ].iMax = i;
  1304. i++;
  1305. }
  1306. #ifdef USE_KEYWORDS
  1307. i = 0;
  1308. while ( i < iKeys )
  1309. {
  1310. iIndex = aKeys[i].sWord[0];
  1311. if( aKeyNodes[ iIndex ].iMin == -1 )
  1312. {
  1313. aKeyNodes[ iIndex ].iMin = i;
  1314. }
  1315. aKeyNodes[ iIndex ].iMax = i;
  1316. i++;
  1317. }
  1318. #endif
  1319. i = 0;
  1320. while ( i < iWords )
  1321. {
  1322. iIndex = aWords[i].sWord[0];
  1323. if( aWordNodes[ iIndex ].iMin == -1 )
  1324. {
  1325. aWordNodes[ iIndex ].iMin = i;
  1326. }
  1327. aWordNodes[ iIndex ].iMax = i;
  1328. i++;
  1329. }
  1330. /* Reduce logic excpects the Rules to be sorted. */
  1331. qsort( ( void * ) aiRules, iRules, LEX_RULE_SIZE, rulecmp );
  1332. i = 0;
  1333. while ( i < iRules )
  1334. {
  1335. iIndex = (unsigned int) aiRules[i][0];
  1336. if( iIndex > 1023 )
  1337. {
  1338. printf( "ERROR! Primary Token: %i out of range.\n", (int) iIndex );
  1339. exit( EXIT_FAILURE );
  1340. }
  1341. if( aRuleNodes[ iIndex ].iMin == -1 )
  1342. {
  1343. aRuleNodes[ iIndex ].iMin = i;
  1344. }
  1345. aRuleNodes[ iIndex ].iMax = i;
  1346. i++;
  1347. }
  1348. }
  1349. static int rulecmp( const void * pLeft, const void * pRight )
  1350. {
  1351. int *iLeftRule = (int*)( pLeft );
  1352. int *iRightRule = (int*)( pRight );
  1353. register unsigned int i = 0;
  1354. while( iLeftRule[i] == iRightRule[i] )
  1355. {
  1356. i++;
  1357. }
  1358. if( iLeftRule[i] < iRightRule[i] )
  1359. {
  1360. return -1;
  1361. }
  1362. else
  1363. {
  1364. return 1;
  1365. }
  1366. }