/* * compiler lexer which converts PP tokens to the ones which * grammar parser generated by bison can understand * * Copyright 2006 Przemyslaw Czerpak * * 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 program; see the file LICENSE.txt. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA (or visit https://www.gnu.org/licenses/). * * 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 "hbpp.h" #include "hbcomp.h" #include "hbdate.h" #include "harboury.h" #define HB_PP_LEX_SELF(t) ( HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_SEND && \ (t)->pNext && (t)->pNext->spaces == 0 && \ HB_PP_TOKEN_TYPE((t)->pNext->type) == HB_PP_TOKEN_SEND ) #define HB_PP_LEX_NEEDLEFT(t) ( HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_ASSIGN || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_PLUSEQ || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_MINUSEQ || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_MULTEQ || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_DIVEQ || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_MODEQ || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_EXPEQ || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_EQUAL || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_EQ || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_ALIAS || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_MULT || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_DIV || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_MOD || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_POWER || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_IN || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_AND || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_OR || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_PIPE || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_RIGHT_PB || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_RIGHT_SB || \ HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_RIGHT_CB || \ ( HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_SEND && \ (t)->spaces == 0 && ! HB_PP_LEX_SELF(t) ) ) #define LOOKUP 0 #define OPERATOR -2 #define LSEPARATOR -3 #define RSEPARATOR -4 #define LINDEX -5 #define RINDEX -6 #define LARRAY -7 #define RARRAY -8 #define AS_TYPE -9 #define DECLARE_TYPE -10 typedef struct { const char * value; /* keyword name */ HB_SIZE minlen; /* minimal length */ HB_SIZE maxlen; /* maximal length */ int type; /* terminal symbol code */ } HB_LEX_KEY; static const HB_LEX_KEY s_keytable[] = { { "ALWAYS", 4, 6, ALWAYS }, { "ANNOUNCE", 4, 8, ANNOUNCE }, { "AS", 2, 2, AS_TYPE }, { "BEGIN", 4, 5, BEGINSEQ }, { "BREAK", 4, 5, BREAK }, { "CASE", 4, 4, CASE }, { "DECLARE", 4, 7, DECLARE }, { "DESCEND", 7, 7, DESCEND }, { "DO", 2, 2, DO }, { "DYNAMIC", 7, 7, DYNAMIC }, { "ELSE", 4, 4, ELSE }, { "ELSEIF", 5, 6, ELSEIF }, { "END", 3, 3, END }, { "ENDCASE", 4, 7, ENDCASE }, { "ENDDO", 4, 5, ENDDO }, { "ENDIF", 4, 5, ENDIF }, { "ENDSEQUENCE", 6, 11, ENDSEQ }, { "ENDSWITCH", 5, 9, ENDSWITCH }, { "ENDWITH", 4, 7, ENDWITH }, { "EXIT", 4, 4, EXIT }, { "EXTERNAL", 4, 8, EXTERN }, { "FIELD", 4, 5, FIELD }, { "FOR", 3, 3, FOR }, { "FUNCTION", 4, 8, FUNCTION }, { "IF", 2, 2, IF }, { "IIF", 3, 3, IIF }, { "IN", 2, 2, IN }, { "INIT", 4, 4, INIT }, { "LOCAL", 4, 5, LOCAL }, { "LOOP", 4, 4, LOOP }, { "MEMVAR", 4, 6, MEMVAR }, { "NEXT", 4, 4, NEXT }, { "NIL", 3, 3, NIL }, { "OPTIONAL", 4, 8, OPTIONAL }, { "OTHERWISE", 4, 9, OTHERWISE }, { "PARAMETERS", 4, 10, PARAMETERS }, { "PRIVATE", 4, 7, PRIVATE }, { "PROCEDURE", 4, 9, PROCEDURE }, { "PUBLIC", 4, 6, PUBLIC }, { "QSELF", 5, 5, SELF }, { "RECOVER", 4, 7, RECOVER }, { "RETURN", 4, 6, RETURN }, { "STATIC", 4, 6, STATIC }, { "STEP", 4, 4, STEP }, { "SWITCH", 4, 6, DOSWITCH }, { "THREAD", 4, 6, THREAD }, { "TO", 2, 2, TO }, { "WHILE", 4, 5, WHILE }, { "WITH", 4, 4, WITH }, { "_FIELD", 4, 6, FIELD }, { "_HB_CLASS", 9, 9, DECLARE_CLASS }, { "_HB_MEMBER", 10, 10, DECLARE_MEMBER }, { "_PROCREQ_", 9, 9, PROCREQ } }; #define _AS_ARRAY 1 #define _AS_BLOCK 2 #define _AS_CHARACTER 3 #define _AS_CLASS 4 #define _AS_DATE 5 #define _AS_DATETIME 5 #define _AS_HASH 9 #define _AS_LOGICAL 6 #define _AS_NUMERIC 7 #define _AS_OBJECT 8 #define _AS_POINTER 9 #define _AS_SYMBOL 9 #define _AS_VARIANT 9 static const int s_asTypes[] = { 0, AS_ARRAY, AS_BLOCK, AS_CHARACTER, AS_CLASS, AS_DATE, AS_LOGICAL, AS_NUMERIC, AS_OBJECT, AS_VARIANT }; static const int s_asArrayTypes[] = { 0, AS_ARRAY_ARRAY, AS_BLOCK_ARRAY, AS_CHARACTER_ARRAY, AS_CLASS_ARRAY, AS_DATE_ARRAY, AS_LOGICAL_ARRAY, AS_NUMERIC_ARRAY, AS_OBJECT_ARRAY, AS_ARRAY }; static const HB_LEX_KEY s_typetable[] = { { "ANYTYPE", 4, 7, _AS_VARIANT }, { "ARRAY", 4, 5, _AS_ARRAY }, { "BLOCK", 4, 5, _AS_BLOCK }, { "CHARACTER", 4, 9, _AS_CHARACTER }, { "CLASS", 4, 5, _AS_CLASS }, { "CODEBLOCK", 4, 9, _AS_BLOCK }, { "DATE", 4, 4, _AS_DATE }, { "DATETIME", 5, 8, _AS_DATETIME }, { "HASH", 4, 4, _AS_HASH }, { "LOGICAL", 4, 7, _AS_LOGICAL }, { "NUMERIC", 4, 7, _AS_NUMERIC }, { "OBJECT", 4, 6, _AS_OBJECT }, { "POINTER", 4, 7, _AS_POINTER }, { "STRING", 4, 6, _AS_CHARACTER }, { "SYMBOL", 4, 6, _AS_SYMBOL }, { "TIMESTAMP", 4, 8, _AS_DATETIME }, { "USUAL", 4, 5, _AS_VARIANT } }; static int hb_comp_asType( PHB_PP_TOKEN pToken, HB_BOOL fArray ) { if( pToken && HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_KEYWORD ) { const HB_LEX_KEY * pKey = s_typetable; int i = HB_SIZEOFARRAY( s_typetable ); hb_pp_tokenUpper( pToken ); do { if( pKey->minlen <= pToken->len && pToken->len <= pKey->maxlen && memcmp( pKey->value, pToken->value, pToken->len ) == 0 ) return ( fArray ? s_asArrayTypes : s_asTypes )[ pKey->type ]; ++pKey; } while( --i ); } return 0; } static int hb_comp_keywordType( PHB_PP_TOKEN pToken ) { const HB_LEX_KEY * pKey = s_keytable; int i = HB_SIZEOFARRAY( s_keytable ); do { if( pKey->minlen <= pToken->len && pToken->len <= pKey->maxlen && memcmp( pKey->value, pToken->value, pToken->len ) == 0 ) { if( HB_PP_TOKEN_ALLOC( pToken->type ) && pToken->len == pKey->maxlen ) { hb_xfree( HB_UNCONST( pToken->value ) ); pToken->value = pKey->value; pToken->type |= HB_PP_TOKEN_STATIC; } return pKey->type; } ++pKey; } while( --i ); return IDENTIFIER; } static const char * hb_comp_tokenIdentifer( HB_COMP_DECL, PHB_PP_TOKEN pToken ) { if( HB_PP_TOKEN_ALLOC( pToken->type ) ) { pToken->value = hb_compIdentifierNew( HB_COMP_PARAM, pToken->value, HB_IDENT_FREE ); pToken->type |= HB_PP_TOKEN_STATIC; } return pToken->value; } static const char * hb_comp_tokenString( YYSTYPE * yylval_ptr, HB_COMP_DECL, PHB_PP_TOKEN pToken ) { yylval_ptr->valChar.length = pToken->len; yylval_ptr->valChar.string = ( char * ) HB_UNCONST( pToken->value ); yylval_ptr->valChar.dealloc = HB_FALSE; if( HB_PP_TOKEN_ALLOC( pToken->type ) ) { yylval_ptr->valChar.dealloc = pToken->len != strlen( pToken->value ); pToken->value = hb_compIdentifierNew( HB_COMP_PARAM, pToken->value, yylval_ptr->valChar.dealloc ? HB_IDENT_COPY : HB_IDENT_FREE ); if( ! yylval_ptr->valChar.dealloc ) yylval_ptr->valChar.string = ( char * ) HB_UNCONST( pToken->value ); pToken->type |= HB_PP_TOKEN_STATIC; } return pToken->value; } #if defined( HB_COMPAT_FOXPRO ) || 1 static HB_BOOL hb_comp_timeDecode( PHB_PP_TOKEN pTime, long * plTime ) { HB_MAXINT lHour, lMinute, lMilliSec; double dNumber; int iDec, iWidth; if( ! pTime || HB_PP_TOKEN_TYPE( pTime->type ) != HB_PP_TOKEN_NUMBER || hb_compStrToNum( pTime->value, pTime->len, &lHour, &dNumber, &iDec, &iWidth ) || lHour < 0 || lHour >= 24 ) return HB_FALSE; pTime = pTime->pNext; if( ! pTime || HB_PP_TOKEN_TYPE( pTime->type ) != HB_PP_TOKEN_SEND ) return HB_FALSE; pTime = pTime->pNext; if( ! pTime || HB_PP_TOKEN_TYPE( pTime->type ) != HB_PP_TOKEN_NUMBER || hb_compStrToNum( pTime->value, pTime->len, &lMinute, &dNumber, &iDec, &iWidth ) || lMinute < 0 || lMinute >= 60 ) return HB_FALSE; pTime = pTime->pNext; if( ! pTime ) return HB_FALSE; if( HB_PP_TOKEN_TYPE( pTime->type ) == HB_PP_TOKEN_SEND ) { pTime = pTime->pNext; if( ! pTime || HB_PP_TOKEN_TYPE( pTime->type ) != HB_PP_TOKEN_NUMBER ) return HB_FALSE; if( hb_compStrToNum( pTime->value, pTime->len, &lMilliSec, &dNumber, &iDec, &iWidth ) ) { if( dNumber < 0.0 || dNumber >= 60.0 ) return HB_FALSE; lMilliSec = ( HB_MAXINT ) ( dNumber * 1000 + 0.05 / HB_MILLISECS_PER_DAY ); if( lMilliSec == 60000 ) --lMilliSec; } else if( lMilliSec < 0 || lMilliSec >= 60 ) return HB_FALSE; else lMilliSec *= 1000; pTime = pTime->pNext; } else lMilliSec = 0; if( HB_PP_TOKEN_TYPE( pTime->type ) == HB_PP_TOKEN_KEYWORD && lHour > 0 && lHour <= 12 ) { if( ( pTime->len == 1 && ( pTime->value[ 0 ] == 'A' || pTime->value[ 0 ] == 'a' ) ) || ( pTime->len == 2 && hb_stricmp( pTime->value, "AM" ) == 0 ) ) { if( lHour == 12 ) lHour = 0; pTime = pTime->pNext; } else if( ( pTime->len == 1 && ( pTime->value[ 0 ] == 'P' || pTime->value[ 0 ] == 'p' ) ) || ( pTime->len == 2 && hb_stricmp( pTime->value, "PM" ) == 0 ) ) { if( lHour < 12 ) lHour += 12; pTime = pTime->pNext; } } if( ! pTime || HB_PP_TOKEN_TYPE( pTime->type ) != HB_PP_TOKEN_RIGHT_CB ) return HB_FALSE; *plTime = ( long ) ( ( lHour * 60 + lMinute ) * 60000 + lMilliSec ); return HB_TRUE; } static int hb_comp_dayTimeDecode( PHB_COMP_LEX pLex, PHB_PP_TOKEN pToken, YYSTYPE * yylval_ptr ) { /* TODO: decode datetime in VFP strict date form: * {^YYYY/MM/DD[,][HH[:MM[:SS][.CCC]][A|P]]} * VFP accepts slash, dot or hyphen as date delimiter and * 12 or 24-hour formatted time, * If only hours are included in time part then comma have to * be used to separate date and time parts or it's necesary * to follow the hours with a colon. * { ^ [[] * [ [ : [ : [ . ] ] ] [AM|PP] ] } */ PHB_PP_TOKEN pYear, pMonth, pDay, pTime = NULL; HB_MAXINT lYear = 0, lMonth = 0, lDay = 0; long lDate = 0, lTime = 0; double dNumber; int iDec, iWidth, iType = 0; pYear = pToken->pNext->pNext; if( pYear && HB_PP_TOKEN_TYPE( pYear->type ) == HB_PP_TOKEN_NUMBER && pYear->pNext ) { if( ( HB_PP_TOKEN_TYPE( pYear->pNext->type ) == HB_PP_TOKEN_DIV || HB_PP_TOKEN_TYPE( pYear->pNext->type ) == HB_PP_TOKEN_MINUS ) && ! hb_compStrToNum( pYear->value, pYear->len, &lYear, &dNumber, &iDec, &iWidth ) ) { pMonth = pYear->pNext->pNext; if( pMonth && HB_PP_TOKEN_TYPE( pMonth->type ) == HB_PP_TOKEN_NUMBER && pMonth->pNext && HB_PP_TOKEN_TYPE( pYear->pNext->type ) == HB_PP_TOKEN_TYPE( pMonth->pNext->type ) && ! hb_compStrToNum( pMonth->value, pMonth->len, &lMonth, &dNumber, &iDec, &iWidth ) ) { pDay = pMonth->pNext->pNext; if( pDay && HB_PP_TOKEN_TYPE( pDay->type ) == HB_PP_TOKEN_NUMBER && pDay->pNext && ! hb_compStrToNum( pDay->value, pDay->len, &lDay, &dNumber, &iDec, &iWidth ) ) { pTime = pDay->pNext; } } } else if( HB_PP_TOKEN_TYPE( pYear->pNext->type ) == HB_PP_TOKEN_NUMBER && pYear->pNext->pNext ) { if( hb_compStrToNum( pYear->value, pYear->len, &lYear, &dNumber, &iDec, &iWidth ) ) { if( iDec == 2 ) { lYear = ( HB_MAXINT ) dNumber; lMonth = ( HB_MAXINT ) ( dNumber * 100 + 0.1 ) % 100; pDay = pYear->pNext; if( hb_compStrToNum( pDay->value, pDay->len, &lDay, &dNumber, &iDec, &iWidth ) ) { if( iDec == 2 ) { lDay = ( HB_MAXINT ) ( dNumber * 100 + 0.1 ); pTime = pDay->pNext; } } } } } if( pTime ) { lDate = hb_dateEncode( ( int ) lYear, ( int ) lMonth, ( int ) lDay ); if( lDate != 0 || ( lYear == 0 && lMonth == 0 && lDay == 0 ) ) { iType = NUM_DATE; if( HB_PP_TOKEN_TYPE( pTime->type ) != HB_PP_TOKEN_RIGHT_CB ) { if( HB_PP_TOKEN_TYPE( pTime->type ) == HB_PP_TOKEN_COMMA ) pTime = pTime->pNext; iType = hb_comp_timeDecode( pTime, &lTime ) ? TIMESTAMP : 0; } } } else if( hb_comp_timeDecode( pYear, &lTime ) ) iType = TIMESTAMP; } if( iType ) { while( HB_PP_TOKEN_TYPE( pToken->type ) != HB_PP_TOKEN_RIGHT_CB ) pToken = hb_pp_tokenGet( pLex->pPP ); if( iType == TIMESTAMP ) { yylval_ptr->valTimeStamp.date = lDate; yylval_ptr->valTimeStamp.time = lTime; } else yylval_ptr->valLong.lNumber = lDate; pLex->iState = LITERAL; } return iType; } #endif extern int hb_comp_yylex( YYSTYPE * yylval_ptr, HB_COMP_DECL ); int hb_comp_yylex( YYSTYPE * yylval_ptr, HB_COMP_DECL ) { PHB_COMP_LEX pLex = HB_COMP_PARAM->pLex; PHB_PP_TOKEN pToken = hb_pp_tokenGet( pLex->pPP ); if( pLex->fEol ) { pLex->fEol = HB_FALSE; HB_COMP_PARAM->currLine++; } if( ! pToken || HB_COMP_PARAM->fExit ) { pLex->lasttok = NULL; return 0; } pLex->lasttok = pToken->value; switch( HB_PP_TOKEN_TYPE( pToken->type ) ) { case HB_PP_TOKEN_NUMBER: { HB_MAXINT lNumber; double dNumber; int iDec, iWidth; pLex->iState = LITERAL; if( hb_compStrToNum( pToken->value, pToken->len, &lNumber, &dNumber, &iDec, &iWidth ) ) { yylval_ptr->valDouble.dNumber = dNumber; yylval_ptr->valDouble.bDec = ( HB_UCHAR ) iDec; yylval_ptr->valDouble.bWidth = ( HB_UCHAR ) iWidth; return NUM_DOUBLE; } else { yylval_ptr->valLong.lNumber = lNumber; yylval_ptr->valLong.bWidth = ( HB_UCHAR ) iWidth; return NUM_LONG; } } case HB_PP_TOKEN_DATE: { int iYear, iMonth, iDay; pLex->iState = LITERAL; if( pToken->value[ 0 ] == '0' && ( pToken->value[ 1 ] == 'D' || pToken->value[ 1 ] == 'd' ) ) { if( pToken->len == 10 ) { hb_dateStrGet( pToken->value + 2, &iYear, &iMonth, &iDay ); } else { iYear = iMonth = iDay = 0; if( pToken->len != 3 || pToken->value[ 2 ] != '0' ) iYear = -1; } } else if( ! hb_timeStampStrGet( pToken->value, &iYear, &iMonth, &iDay, NULL, NULL, NULL, NULL ) ) iYear = -1; yylval_ptr->valLong.lNumber = hb_dateEncode( iYear, iMonth, iDay ); if( yylval_ptr->valLong.lNumber == 0 && ( iYear != 0 || iMonth != 0 || iDay != 0 ) ) { hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_INVALID_DATE, pToken->value, NULL ); } return NUM_DATE; } case HB_PP_TOKEN_TIMESTAMP: pLex->iState = LITERAL; if( ! hb_timeStampStrGetDT( pToken->value, &yylval_ptr->valTimeStamp.date, &yylval_ptr->valTimeStamp.time ) ) { hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_INVALID_TIMESTAMP, pToken->value, NULL ); } return TIMESTAMP; case HB_PP_TOKEN_STRING: pLex->iState = LITERAL; pLex->lasttok = hb_comp_tokenString( yylval_ptr, HB_COMP_PARAM, pToken ); return LITERAL; case HB_PP_TOKEN_LOGICAL: pLex->iState = LITERAL; return pToken->value[ 1 ] == 'T' ? TRUEVALUE : FALSEVALUE; case HB_PP_TOKEN_MACROVAR: pLex->iState = MACROVAR; hb_pp_tokenUpper( pToken ); pLex->lasttok = yylval_ptr->string = hb_comp_tokenIdentifer( HB_COMP_PARAM, pToken ); return MACROVAR; case HB_PP_TOKEN_MACROTEXT: pLex->iState = MACROTEXT; hb_pp_tokenUpper( pToken ); pLex->lasttok = yylval_ptr->string = hb_comp_tokenIdentifer( HB_COMP_PARAM, pToken ); return MACROTEXT; case HB_PP_TOKEN_LEFT_SB: switch( pLex->iState ) { case OPERATOR: case LSEPARATOR: case LARRAY: case IF: case ELSEIF: case CASE: case BREAK: case RETURN: case IN: case WITH: case WHILE: case DOSWITCH: case WITHOBJECT: pLex->iState = LITERAL; hb_pp_tokenToString( pLex->pPP, pToken ); pLex->lasttok = hb_comp_tokenString( yylval_ptr, HB_COMP_PARAM, pToken ); return LITERAL; default: pLex->iState = LINDEX; return '['; } case HB_PP_TOKEN_RIGHT_SB: pLex->iState = RINDEX; return ']'; case HB_PP_TOKEN_LEFT_CB: if( pToken->pNext ) { if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_PIPE ) { yylval_ptr->asCodeblock.string = hb_strdup( hb_pp_tokenBlockString( pLex->pPP, pToken, &yylval_ptr->asCodeblock.flags, &yylval_ptr->asCodeblock.length ) ); hb_pp_tokenGet( pLex->pPP ); return CBSTART; } #if defined( HB_COMPAT_FOXPRO ) || 1 else if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_POWER ) { int iType = hb_comp_dayTimeDecode( pLex, pToken, yylval_ptr ); if( iType ) return iType; } #endif } pLex->iState = LARRAY; return '{'; case HB_PP_TOKEN_RIGHT_CB: pLex->iState = RARRAY; return '}'; case HB_PP_TOKEN_LEFT_PB: pLex->iState = LSEPARATOR; return '('; case HB_PP_TOKEN_RIGHT_PB: pLex->iState = RSEPARATOR; return ')'; case HB_PP_TOKEN_EPSILON: pLex->iState = OPERATOR; return EPSILON; case HB_PP_TOKEN_HASH: case HB_PP_TOKEN_DIRECTIVE: if( pLex->iState == LOOKUP && pToken->pNext && HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD && hb_stricmp( "LINE", pToken->pNext->value ) == 0 ) { hb_pp_tokenGet( pLex->pPP ); return LINE; } pLex->iState = OPERATOR; return NE1; case HB_PP_TOKEN_NE: pLex->iState = OPERATOR; return NE2; case HB_PP_TOKEN_ASSIGN: pLex->iState = OPERATOR; return INASSIGN; case HB_PP_TOKEN_EQUAL: pLex->iState = OPERATOR; return EQ; case HB_PP_TOKEN_INC: pLex->iState = OPERATOR; return INC; case HB_PP_TOKEN_DEC: pLex->iState = OPERATOR; return DEC; case HB_PP_TOKEN_ALIAS: pLex->iState = OPERATOR; return ALIASOP; case HB_PP_TOKEN_LE: pLex->iState = OPERATOR; return LE; case HB_PP_TOKEN_GE: pLex->iState = OPERATOR; return GE; case HB_PP_TOKEN_PLUSEQ: pLex->iState = OPERATOR; return PLUSEQ; case HB_PP_TOKEN_MINUSEQ: pLex->iState = OPERATOR; return MINUSEQ; case HB_PP_TOKEN_MULTEQ: pLex->iState = OPERATOR; return MULTEQ; case HB_PP_TOKEN_DIVEQ: pLex->iState = OPERATOR; return DIVEQ; case HB_PP_TOKEN_MODEQ: pLex->iState = OPERATOR; return MODEQ; case HB_PP_TOKEN_EXPEQ: pLex->iState = OPERATOR; return EXPEQ; case HB_PP_TOKEN_POWER: pLex->iState = OPERATOR; return POWER; case HB_PP_TOKEN_AND: pLex->iState = OPERATOR; return AND; case HB_PP_TOKEN_OR: pLex->iState = OPERATOR; return OR; case HB_PP_TOKEN_NOT: pLex->iState = OPERATOR; return NOT; case HB_PP_TOKEN_SEND: if( HB_PP_LEX_SELF( pToken ) ) { pLex->lasttok = yylval_ptr->string = "SELF"; pLex->iState = IDENTIFIER; return IDENTIFIER; } pLex->iState = OPERATOR; return ( HB_UCHAR ) pToken->value[ 0 ]; case HB_PP_TOKEN_EQ: if( HB_SUPPORT_HARBOUR && pToken->pNext && pToken->pNext->spaces == 0 && HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_GT ) { hb_pp_tokenGet( pLex->pPP ); pLex->iState = OPERATOR; return HASHOP; } /* fallthrough */ case HB_PP_TOKEN_PLUS: case HB_PP_TOKEN_MINUS: case HB_PP_TOKEN_MULT: case HB_PP_TOKEN_DIV: case HB_PP_TOKEN_MOD: case HB_PP_TOKEN_IN: case HB_PP_TOKEN_COMMA: case HB_PP_TOKEN_PIPE: case HB_PP_TOKEN_AMPERSAND: case HB_PP_TOKEN_DOT: case HB_PP_TOKEN_LT: case HB_PP_TOKEN_GT: case HB_PP_TOKEN_REFERENCE: pLex->iState = OPERATOR; return ( HB_UCHAR ) pToken->value[ 0 ]; case HB_PP_TOKEN_EOL: pLex->fEol = HB_TRUE; case HB_PP_TOKEN_EOC: pLex->iState = LOOKUP; return ( HB_UCHAR ) pToken->value[ 0 ]; case HB_PP_TOKEN_KEYWORD: { int iType; hb_pp_tokenUpper( pToken ); iType = hb_comp_keywordType( pToken ); pLex->lasttok = yylval_ptr->string = hb_comp_tokenIdentifer( HB_COMP_PARAM, pToken ); switch( iType ) { case FUNCTION: case PROCEDURE: if( HB_SUPPORT_HARBOUR && ( ( pLex->iState != LOOKUP && pLex->iState != STATIC && pLex->iState != INIT && pLex->iState != EXIT ) || HB_PP_TOKEN_ISEOC( pToken->pNext ) || HB_PP_TOKEN_TYPE( pToken->pNext->type ) != HB_PP_TOKEN_KEYWORD ) ) { iType = IDENTIFIER; break; } pLex->iState = iType; return pLex->iState; case INIT: if( pLex->iState == LOOKUP && pToken->pNext && HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD && pToken->pNext->len >= 4 && ( hb_strnicmp( "FUNCTION", pToken->pNext->value, pToken->pNext->len ) == 0 || hb_strnicmp( "PROCEDURE", pToken->pNext->value, pToken->pNext->len ) == 0 ) ) { pLex->iState = INIT; return INIT; } iType = IDENTIFIER; break; case BEGINSEQ: if( pLex->iState == LOOKUP && pToken->pNext && HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD ) { if( pToken->pNext->len >= 4 && pToken->pNext->len <= 8 && hb_strnicmp( "SEQUENCE", pToken->pNext->value, pToken->pNext->len ) == 0 ) { hb_pp_tokenGet( pLex->pPP ); pLex->iState = BEGINSEQ; return BEGINSEQ; } } iType = IDENTIFIER; break; case RECOVER: if( pLex->iState == LOOKUP ) { if( HB_PP_TOKEN_ISEOC( pToken->pNext ) ) { pLex->iState = RECOVER; return RECOVER; } else if( pToken->pNext && HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD && pToken->pNext->len >= 4 && pToken->pNext->len <= 5 && hb_strnicmp( "USING", pToken->pNext->value, pToken->pNext->len ) == 0 ) { hb_pp_tokenGet( pLex->pPP ); pLex->iState = RECOVERUSING; return RECOVERUSING; } } iType = IDENTIFIER; break; case END: if( pLex->iState == LOOKUP ) { if( HB_PP_TOKEN_ISEOC( pToken->pNext ) ) { pLex->iState = END; return END; } else if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD && pToken->pNext->len >= 4 && pToken->pNext->len <= 8 && hb_strnicmp( "SEQUENCE", pToken->pNext->value, pToken->pNext->len ) == 0 ) { hb_pp_tokenGet( pLex->pPP ); pLex->iState = ENDSEQ; return ENDSEQ; } if( ! HB_SUPPORT_HARBOUR && HB_COMP_PARAM->iSyntaxCheckOnly < 2 ) { /* Clipper does not like end[], end(), end->, end-- & end++ at the begining of line */ if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_PB || HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_SB || HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_INC || HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_DEC || HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_ALIAS ) hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_ENDIF, NULL, NULL ); } } iType = IDENTIFIER; break; case ELSE: if( HB_SUPPORT_HARBOUR && ( pLex->iState != LOOKUP || ! HB_PP_TOKEN_ISEOC( pToken->pNext ) ) ) { iType = IDENTIFIER; break; } pLex->iState = ELSE; return ELSE; case ELSEIF: case CASE: if( HB_SUPPORT_HARBOUR && ( pLex->iState != LOOKUP || HB_PP_TOKEN_ISEOC( pToken->pNext ) || HB_PP_LEX_NEEDLEFT( pToken->pNext ) ) ) { iType = IDENTIFIER; break; } pLex->iState = iType; return iType; case ENDIF: case ENDCASE: case ENDDO: if( HB_SUPPORT_HARBOUR && ( pLex->iState != LOOKUP || ! HB_PP_TOKEN_ISEOC( pToken->pNext ) ) ) { iType = IDENTIFIER; break; } pLex->iState = iType; return iType; case OTHERWISE: case ENDSEQ: case ENDSWITCH: case ENDWITH: case ALWAYS: if( pLex->iState == LOOKUP && HB_PP_TOKEN_ISEOC( pToken->pNext ) ) { pLex->iState = iType; return iType; } iType = IDENTIFIER; break; case FOR: if( pLex->iState == LOOKUP && ! HB_PP_TOKEN_ISEOC( pToken->pNext ) ) { PHB_PP_TOKEN pNext = pToken->pNext; if( HB_PP_TOKEN_TYPE( pNext->type ) == HB_PP_TOKEN_KEYWORD && pNext->pNext && HB_PP_TOKEN_TYPE( pNext->pNext->type ) == HB_PP_TOKEN_KEYWORD && hb_stricmp( "EACH", pNext->value ) == 0 ) { hb_pp_tokenGet( pLex->pPP ); pLex->iState = FOREACH; return FOREACH; } if( ! hb_pp_tokenNextExp( &pNext ) && pNext && HB_PP_TOKEN_TYPE( pNext->type ) == HB_PP_TOKEN_KEYWORD && hb_stricmp( "TO", pNext->value ) == 0 ) { pLex->iState = FOR; return FOR; } } iType = IDENTIFIER; break; case NEXT: if( pLex->iState == LOOKUP ) { if( HB_PP_TOKEN_ISEOC( pToken->pNext ) || ( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD && HB_PP_TOKEN_ISEOC( pToken->pNext->pNext ) ) ) { pLex->iState = iType; return iType; } if( ! HB_SUPPORT_HARBOUR && HB_COMP_PARAM->iSyntaxCheckOnly < 2 ) { /* Clipper does not like NEXT[], NEXT(), NEXT->, NEXT++ & NEXT-- at the begining of line */ if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_PB || HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_SB || HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_INC || HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_DEC || HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_ALIAS ) hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_NEXTFOR, NULL, NULL ); } } iType = IDENTIFIER; break; case RETURN: case BREAK: /* NOTE: Clipper does not like break[] in any context * There are no resons to limit this use in Harbour. */ if( pLex->iState == LOOKUP && ( HB_PP_TOKEN_ISEOC( pToken->pNext ) || ! HB_PP_LEX_NEEDLEFT( pToken->pNext ) ) ) { pLex->iState = iType; return iType; } iType = IDENTIFIER; break; case WHILE: case DOSWITCH: if( pLex->iState == LOOKUP && ! HB_PP_TOKEN_ISEOC( pToken->pNext ) && ! HB_PP_LEX_NEEDLEFT( pToken->pNext ) ) { pLex->iState = iType; return iType; } iType = IDENTIFIER; break; case DECLARE: if( pLex->iState == LOOKUP && ! HB_PP_TOKEN_ISEOC( pToken->pNext ) ) { if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_MACROVAR || HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_MACROTEXT || HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_AMPERSAND ) { pLex->iState = PRIVATE; return PRIVATE; } else if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD ) { if( HB_PP_TOKEN_ISEOC( pToken->pNext->pNext ) || HB_PP_TOKEN_TYPE( pToken->pNext->pNext->type ) == HB_PP_TOKEN_LEFT_SB || HB_PP_TOKEN_TYPE( pToken->pNext->pNext->type ) == HB_PP_TOKEN_COMMA || HB_PP_TOKEN_TYPE( pToken->pNext->pNext->type ) == HB_PP_TOKEN_ASSIGN || ( HB_PP_TOKEN_TYPE( pToken->pNext->pNext->type ) == HB_PP_TOKEN_KEYWORD && hb_stricmp( "AS", pToken->pNext->pNext->value ) == 0 ) ) { pLex->iState = PRIVATE; return PRIVATE; } pLex->iState = DECLARE; return DECLARE; } } iType = IDENTIFIER; break; case DO: if( pLex->iState == LOOKUP && ! HB_PP_TOKEN_ISEOC( pToken->pNext ) ) { if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD ) { if( pToken->pNext->len == 4 && hb_stricmp( "CASE", pToken->pNext->value ) == 0 ) { if( HB_PP_TOKEN_ISEOC( pToken->pNext->pNext ) ) { hb_pp_tokenGet( pLex->pPP ); pLex->iState = DOCASE; return DOCASE; } } else if( pToken->pNext->len >= 4 && pToken->pNext->len <= 5 && hb_strnicmp( "WHILE", pToken->pNext->value, pToken->pNext->len ) == 0 && /* check if it's not DO while [WITH ] */ ! HB_PP_TOKEN_ISEOC( pToken->pNext->pNext ) && ( HB_PP_TOKEN_TYPE( pToken->pNext->pNext->type ) != HB_PP_TOKEN_KEYWORD || pToken->pNext->pNext->len != 4 || hb_stricmp( "WITH", pToken->pNext->pNext->value ) != 0 ) ) { /* DO WHILE */ hb_pp_tokenGet( pLex->pPP ); pLex->iState = WHILE; return WHILE; } /* DO identifier [WITH ] */ pToken = hb_pp_tokenGet( pLex->pPP ); /* do not upper next token for case sensitive file systems */ /* hb_pp_tokenUpper( pToken ); */ pLex->lasttok = yylval_ptr->string = hb_comp_tokenIdentifer( HB_COMP_PARAM, pToken ); pLex->iState = IDENTIFIER; return DOIDENT; } else if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_MACROVAR || HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_MACROTEXT ) { /* DO &id WITH */ pLex->iState = DO; return DO; } } iType = IDENTIFIER; break; case WITH: if( ! HB_PP_TOKEN_ISEOC( pToken->pNext ) ) { if( pLex->iState == LOOKUP && HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD && pToken->pNext->len >= 4 && hb_strnicmp( "OBJECT", pToken->pNext->value, pToken->pNext->len ) == 0 ) { hb_pp_tokenGet( pLex->pPP ); pLex->iState = WITHOBJECT; return WITHOBJECT; } else if( pLex->iState == MACROVAR || pLex->iState == MACROTEXT || pLex->iState == IDENTIFIER || pLex->iState == BEGINSEQ ) { pLex->iState = WITH; return WITH; } } iType = IDENTIFIER; break; case IIF: if( pLex->iState == FUNCTION || pLex->iState == PROCEDURE || ( ! HB_SUPPORT_HARBOUR && HB_PP_TOKEN_ISEOC( pToken->pNext ) ) ) hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_SYNTAX, "IIF", NULL ); else if( pToken->pNext && HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_PB ) { pLex->iState = IIF; return IIF; } else if( ! HB_SUPPORT_HARBOUR ) hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_SYNTAX, pToken->pNext->value, NULL ); else iType = IDENTIFIER; break; case IF: if( pLex->iState == FUNCTION || pLex->iState == PROCEDURE || ( ! HB_SUPPORT_HARBOUR && HB_PP_TOKEN_ISEOC( pToken->pNext ) ) ) hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_SYNTAX, "IF", NULL ); else if( pToken->pNext && HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_PB ) { if( pLex->iState == LOOKUP ) { PHB_PP_TOKEN pNext = pToken->pNext->pNext; /* COND EXP */ pLex->iState = IF; if( hb_pp_tokenNextExp( &pNext ) ) /* TRUE EXP */ { if( hb_pp_tokenNextExp( &pNext ) ) /* FALSE EXP */ { if( ! hb_pp_tokenNextExp( &pNext ) && pNext && HB_PP_TOKEN_TYPE( pNext->type ) == HB_PP_TOKEN_RIGHT_PB ) pLex->iState = IIF; } } } else pLex->iState = IIF; return pLex->iState; } else if( HB_PP_LEX_NEEDLEFT( pToken->pNext ) || pLex->iState != LOOKUP ) { if( ! HB_SUPPORT_HARBOUR ) hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_SYNTAX2, pToken->pNext->value, "IF" ); } else { pLex->iState = IF; return IF; } iType = IDENTIFIER; break; case PROCREQ: if( pLex->iState == LOOKUP && ! HB_PP_TOKEN_ISEOC( pToken->pNext ) && HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_PB ) { hb_pp_tokenGet( pLex->pPP ); pLex->iState = LSEPARATOR; return PROCREQ; } iType = IDENTIFIER; break; case FIELD: if( pToken->pNext && ( ( pLex->iState == LOOKUP && HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD ) || HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_ALIAS ) ) { pLex->iState = FIELD; return FIELD; } iType = IDENTIFIER; break; case SELF: if( pToken->pNext && pToken->pNext->pNext && HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_PB && HB_PP_TOKEN_TYPE( pToken->pNext->pNext->type ) == HB_PP_TOKEN_RIGHT_PB ) { hb_pp_tokenGet( pLex->pPP ); hb_pp_tokenGet( pLex->pPP ); pLex->iState = RSEPARATOR; return SELF; } iType = IDENTIFIER; break; case AS_TYPE: { int iAs = hb_comp_asType( pToken->pNext, HB_FALSE ); if( iAs ) { pLex->iState = DECLARE_TYPE; pToken = hb_pp_tokenGet( pLex->pPP ); if( iAs == AS_ARRAY && pToken->pNext && HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD && hb_stricmp( "OF", pToken->pNext->value ) == 0 ) { int iAsArray = hb_comp_asType( pToken->pNext->pNext, HB_TRUE ); if( iAsArray ) { hb_pp_tokenGet( pLex->pPP ); hb_pp_tokenGet( pLex->pPP ); return iAsArray; } } return iAs; } iType = IDENTIFIER; break; } case DECLARE_CLASS: if( pLex->iState == LOOKUP && ! HB_PP_TOKEN_ISEOC( pToken->pNext ) && HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD ) { pLex->iState = DECLARE_TYPE; return DECLARE_CLASS; } iType = IDENTIFIER; break; case DECLARE_MEMBER: if( pLex->iState == LOOKUP && ! HB_PP_TOKEN_ISEOC( pToken->pNext ) && ( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD || HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_CB ) ) { pLex->iState = OPERATOR; return DECLARE_MEMBER; } iType = IDENTIFIER; break; case THREAD: if( pLex->iState == LOOKUP && ! HB_PP_TOKEN_ISEOC( pToken->pNext ) && HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD && pToken->pNext->len >= 4 && hb_strnicmp( "STATIC", pToken->pNext->value, pToken->pNext->len ) == 0 ) { pLex->iState = LOOKUP; return iType; } iType = IDENTIFIER; break; case IN: if( pLex->iState == IDENTIFIER ) { pLex->iState = iType; return iType; } break; case NIL: if( pLex->iState == DECLARE_TYPE ) iType = IDENTIFIER; break; case EXIT: case LOOP: case LOCAL: case STATIC: case MEMVAR: case PUBLIC: case PRIVATE: case PARAMETERS: case EXTERN: case DYNAMIC: case ANNOUNCE: if( pLex->iState == LOOKUP ) { pLex->iState = iType; return iType; } break; case TO: case STEP: case OPTIONAL: case DESCEND: break; } pLex->iState = IDENTIFIER; return iType; } default: return ( HB_UCHAR ) pToken->value[ 0 ]; } } void hb_compParserRun( HB_COMP_DECL ) { YYSTYPE yylval; int iToken; while( ! HB_COMP_PARAM->fExit && HB_COMP_PARAM->iErrorCount == 0 ) { if( HB_COMP_PARAM->fSingleModule ) { PHB_PP_TOKEN pToken = hb_pp_tokenGet( HB_COMP_PARAM->pLex->pPP ); if( ! pToken ) break; } else { iToken = hb_comp_yylex( &yylval, HB_COMP_PARAM ); if( iToken == 0 ) break; if( iToken == DOIDENT ) hb_compModuleAdd( HB_COMP_PARAM, yylval.string, HB_FALSE ); else if( iToken == PROCREQ ) { iToken = hb_comp_yylex( &yylval, HB_COMP_PARAM ); if( iToken == LITERAL ) { const char * szFile, * szExt = NULL; if( yylval.valChar.dealloc ) szFile = hb_compIdentifierNew( HB_COMP_PARAM, yylval.valChar.string, HB_IDENT_FREE ); else szFile = yylval.valChar.string; iToken = hb_comp_yylex( &yylval, HB_COMP_PARAM ); if( iToken == '+' ) { iToken = hb_comp_yylex( &yylval, HB_COMP_PARAM ); if( iToken == LITERAL ) { if( yylval.valChar.dealloc ) szExt = hb_compIdentifierNew( HB_COMP_PARAM, yylval.valChar.string, HB_IDENT_FREE ); else szExt = yylval.valChar.string; } iToken = hb_comp_yylex( &yylval, HB_COMP_PARAM ); } if( iToken == ')' ) { if( szExt && *szExt ) szFile = hb_compIdentifierNew( HB_COMP_PARAM, hb_xstrcpy( NULL, szFile, szExt, NULL ), HB_IDENT_FREE ); hb_compModuleAdd( HB_COMP_PARAM, szFile, HB_FALSE ); } } } } } } void hb_compParserStop( HB_COMP_DECL ) { HB_SYMBOL_UNUSED( HB_COMP_PARAM ); }