%option prefix="engine_ska_yy" %{ #include #include #include #include #include #include "ParsingSmbs.h" #include "smcPars.h" extern CTFileName _fnmApplicationPath; YYSTYPE engine_ska_yylval; #ifdef __cplusplus extern "C" { int engine_ska_yywrap(void); } #endif int engine_ska_yywrap(void) { // no more buffers return 1; }; // declarations for recursive SMC script parsing struct BufferStackEntry { YY_BUFFER_STATE bse_bs; const char *bse_strName; const char *bse_strContents; int bse_iLineCt; BOOL bse_bParserEnd; }; static BufferStackEntry _abseBufferStack[SMC_MAX_INCLUDE_LEVEL]; static int _ibsBufferStackTop = -1; void SMCPushBuffer(const char *strName, const char *strBuffer, BOOL bParserEnd) { _ibsBufferStackTop++; _abseBufferStack[_ibsBufferStackTop].bse_strContents = strdup(strBuffer); _abseBufferStack[_ibsBufferStackTop].bse_strName = strdup(strName); _abseBufferStack[_ibsBufferStackTop].bse_iLineCt = 1; _abseBufferStack[_ibsBufferStackTop].bse_bParserEnd = bParserEnd; _abseBufferStack[_ibsBufferStackTop].bse_bs = engine_ska_yy_scan_string((char*)(const char*)strBuffer); engine_ska_yy_switch_to_buffer(_abseBufferStack[_ibsBufferStackTop].bse_bs); } BOOL SMCPopBuffer(void) { engine_ska_yy_delete_buffer( _abseBufferStack[_ibsBufferStackTop].bse_bs); free((void*)_abseBufferStack[_ibsBufferStackTop].bse_strName); free((void*)_abseBufferStack[_ibsBufferStackTop].bse_strContents); BOOL bParserEnd = _abseBufferStack[_ibsBufferStackTop].bse_bParserEnd; _ibsBufferStackTop--; if (_ibsBufferStackTop>=0) { engine_ska_yy_switch_to_buffer(_abseBufferStack[_ibsBufferStackTop].bse_bs); } return bParserEnd; } const char *SMCGetBufferName(void) { return _abseBufferStack[_ibsBufferStackTop].bse_strName; } int SMCGetBufferLineNumber(void) { return _abseBufferStack[_ibsBufferStackTop].bse_iLineCt; } int SMCGetBufferStackDepth(void) { return _ibsBufferStackTop; } const char *SMCGetBufferContents(void) { return _abseBufferStack[_ibsBufferStackTop].bse_strContents; } void SMCCountOneLine(void) { _abseBufferStack[_ibsBufferStackTop].bse_iLineCt++; } %} %x COMMENT %x INCLUDE DIGIT [0-9] HEXDIGIT [0-9A-Fa-f] DOUBLEQUOTE \" STRINGCONTENT ([^\"]|(\\\")) NONEXP_FLT ({DIGIT}+"."{DIGIT}*) EXP_FLT (({DIGIT}+("."({DIGIT}*)?)?)("E"|"e")("+"|"-")?{DIGIT}+) %% "#INCLUDE" BEGIN(INCLUDE); "SE_SMC" { return(k_SE_SMC); } "SE_END" { return(k_SE_END); } "TFNM" { return(k_TFNM); } "NAME" { return(k_NAME); } "MESH" { return(k_MESH); } "SKELETON" { return(k_SKELETON);} "ANIMSET" { return(k_ANIMSET);} "ANIMATION" { return(K_ANIMATION);} "TEXTURES" { return(k_TEXTURES);} "PARENTBONE" { return(k_PARENTBONE);} "OFFSET" { return(k_OFFSET);} "COLISION" { return(k_COLISION);} "ANIMSPEED" { return(k_ANIMSPEED);} "COLOR" { return(k_COLOR);} "ALLFRAMESBBOX" { return(k_ALLFRAMESBBOX);} [ \t]*"\"" /* eat the whitespace */ [^"\""]*"\"" { /* got the include file name */ if (SMCGetBufferStackDepth() >= SMC_MAX_INCLUDE_LEVEL) { ThrowF_t("File '%s' line %d\nIncludes nested too deeply '%s'",SMCGetBufferName(), SMCGetBufferLineNumber(),yytext); } char strFileName[256]; strcpy(strFileName, yytext); strFileName[strlen(strFileName)-1] = 0; CTString strIncludeFile; try { strIncludeFile.Load_t(CTString(strFileName)); SMCPushBuffer(strFileName, strIncludeFile, FALSE); } catch(char *strError) { (void)strError; ThrowF_t("File '%s'\n Could not open '%s' (line %d)",SMCGetBufferName(), strFileName, SMCGetBufferLineNumber()); } BEGIN(INITIAL); } . { /* something unrecognized inside include statement */ BEGIN(INITIAL); ThrowF_t("File '%s'\n Wrong syntax for include statement",SMCGetBufferName()); } <> { if (SMCPopBuffer()) { yyterminate(); } } /* single character operators and punctuations */ ";"|","|"{"|"}" { return(yytext[0]);} /* constants */ "-"?{DIGIT}+ { engine_ska_yylval.i = atoi(yytext); return(c_int); } "0x"{HEXDIGIT}+ { engine_ska_yylval.i = strtoul(yytext+2, NULL, 16); return(c_int);} "-"?{NONEXP_FLT}("f"|"F")? { engine_ska_yylval.f = (float) atof(yytext); return(c_float); } "-"?{EXP_FLT}("f"|"F")? { engine_ska_yylval.f = (float) atof(yytext); return(c_float); } "\""{STRINGCONTENT}*"\"" { char *strNew; // remove double-quotes yytext[strlen(yytext)-1] = 0; strNew = yytext+1; engine_ska_yylval.str = (const char*)strNew; return(c_string); } /* eat up comments */ "/*" { BEGIN(COMMENT); } "* /" { BEGIN(INITIAL); } . {} "//"[^\n]*\n { SMCCountOneLine(); } /* eat up whitespace */ [ \t]+ { } /* eat up linefeeds and count lines in all conditions */ <*>\n { SMCCountOneLine();; } /* for all unrecognized characters */ . { // report an error ThrowF_t("File '%s'\n Unrecognized character '%c' (line %d)", SMCGetBufferName(), yytext[0], SMCGetBufferLineNumber()); //ThrowF_t("Unrecognized character '%c' in line %d)", yytext[0], _yy_iLine ); } %%