From 1c454bbe6c34350375afa83fdde49aabef7b3961 Mon Sep 17 00:00:00 2001 From: Alexander Pavlov Date: Sun, 24 Dec 2023 11:36:31 +0300 Subject: [PATCH] Update Ecc. --- Sources/Ecc/Ecc.vcxproj | 94 +- Sources/Ecc/Ecc.vcxproj.filters | 112 +- Sources/Ecc/Ecc.vcxproj.user | 4 +- Sources/Ecc/Main.cpp | 4 +- Sources/Ecc/Parser.y | 2870 +++++++++++++++---------------- Sources/Ecc/Scanner.l | 344 ++-- Sources/Ecc/StdH.h | 2 +- Sources/Ecc/bison.simple | 1372 +++++++-------- 8 files changed, 2399 insertions(+), 2403 deletions(-) diff --git a/Sources/Ecc/Ecc.vcxproj b/Sources/Ecc/Ecc.vcxproj index 0c0aead..f5e5c02 100644 --- a/Sources/Ecc/Ecc.vcxproj +++ b/Sources/Ecc/Ecc.vcxproj @@ -112,8 +112,8 @@ Debug\ - .\Release\ - .\Release\ + Release\ + Release\ false $(SolutionDir)..\Tools.Win32;$(ExecutablePath) $(SolutionDir);$(ProjectDir);$(IncludePath) @@ -124,8 +124,8 @@ $(SolutionDir)..\Tools.Win32;$(ExecutablePath) $(SolutionDir);$(ProjectDir);$(IncludePath) $(SolutionDir)Ecc;$(SourcePath) - .\Release\ - .\Release\ + Release\ + Release\ @@ -142,8 +142,7 @@ .\Debug\ .\Debug\ 4996;4333 - - + .\Debug\Ecc.tlb @@ -165,9 +164,9 @@ true - mkdir $(SolutionDir)..\Bin 2>nul -mkdir $(SolutionDir)..\Bin\Debug 2>nul -copy Debug\$(TargetName).exe $(SolutionDir)..\Bin\Debug\ >nul + mkdir $(SolutionDir)..\Bin 2>nul +mkdir $(SolutionDir)..\Bin\Debug 2>nul +copy Debug\$(TargetName).exe $(SolutionDir)..\Bin\Debug\ >nul copy Debug\$(TargetName).map $(SolutionDir)..\Bin\Debug\ >nul Copying %(Filename) binaries to \Bin\Debug $(SolutionDir)..\Bin\Debug\$(TargetName).exe;%(Outputs) @@ -187,8 +186,7 @@ copy Debug\$(TargetName).map $(SolutionDir)..\Bin\Debug\ >nul .\Debug\ .\Debug\ 4996;4333 - - + .\Debug\Ecc.tlb @@ -210,9 +208,9 @@ copy Debug\$(TargetName).map $(SolutionDir)..\Bin\Debug\ >nul true - mkdir $(SolutionDir)..\Bin 2>nul -mkdir $(SolutionDir)..\Bin\Debug 2>nul -copy Debug\$(TargetName).exe $(SolutionDir)..\Bin\Debug\ >nul + mkdir $(SolutionDir)..\Bin 2>nul +mkdir $(SolutionDir)..\Bin\Debug 2>nul +copy Debug\$(TargetName).exe $(SolutionDir)..\Bin\Debug\ >nul copy Debug\$(TargetName).map $(SolutionDir)..\Bin\Debug\ >nul Copying %(Filename) binaries to \Bin\Debug $(SolutionDir)..\Bin\Debug\$(TargetName).exe;%(Outputs) @@ -236,8 +234,7 @@ copy Debug\$(TargetName).map $(SolutionDir)..\Bin\Debug\ >nul .\Release\ .\Release\ 4996;4333 - - + .\Release\Ecc.tlb @@ -259,11 +256,11 @@ copy Debug\$(TargetName).map $(SolutionDir)..\Bin\Debug\ >nul true - mkdir $(SolutionDir)..\x32\SamTFE\Mods\SSA\Bin\ 2>nul -copy Release\$(TargetName).exe $(SolutionDir)..\x32\SamTFE\Mods\SSA\Bin\ >nul -copy Release\$(TargetName).map $(SolutionDir)..\x32\SamTFE\Mods\SSA\Bin\ >nul - Copying %(Filename) binaries to \x32\SamTFE\Mods\SSA\Bin\ - $(SolutionDir)..\x32\SamTFE\Mods\SSA\Bin\$(TargetName).exe;%(Outputs) + mkdir $(SolutionDir)..\Bin 2>nul +copy Release\$(TargetName).exe $(SolutionDir)..\Bin\ >nul +copy Release\$(TargetName).map $(SolutionDir)..\Bin\ >nul + Copying %(Filename) binaries to \Bin + $(SolutionDir)..\Bin\$(TargetName).exe;%(Outputs) @@ -284,8 +281,7 @@ copy Release\$(TargetName).map $(SolutionDir)..\x32\SamTFE\Mods\SSA\Bin\ >nul .\Release\ .\Release\ 4996;4333 - - + .\Release\Ecc.tlb @@ -307,53 +303,53 @@ copy Release\$(TargetName).map $(SolutionDir)..\x32\SamTFE\Mods\SSA\Bin\ >nul true - mkdir $(SolutionDir)..\x64\SamTFE\Mods\SSA\Bin\ 2>nul -copy Release\$(TargetName).exe $(SolutionDir)..\x64\SamTFE\Mods\SSA\Bin\ >nul -copy Release\$(TargetName).map $(SolutionDir)..\x64\SamTFE\Mods\SSA\Bin\ >nul - Copying %(Filename) binaries to \x32\SamTFE\Mods\SSA\Bin\ - $(SolutionDir)..\x64\SamTFE\Mods\SSA\Bin\$(TargetName).exe;%(Outputs) + mkdir $(SolutionDir)..\Bin 2>nul +copy Release\$(TargetName).exe $(SolutionDir)..\Bin\ >nul +copy Release\$(TargetName).map $(SolutionDir)..\Bin\ >nul + Copying %(Filename) binaries to \Bin + $(SolutionDir)..\Bin\$(TargetName).exe;%(Outputs) - mkdir $(SolutionDir)..\Bin 2>nul -copy Debug\%(Filename).exe $(SolutionDir)..\Bin\ >nul + mkdir $(SolutionDir)..\Bin 2>nul +copy Debug\%(Filename).exe $(SolutionDir)..\Bin\ >nul copy Debug\%(Filename).map $(SolutionDir)..\Bin\ >nul - mkdir $(SolutionDir)..\Bin 2>nul -copy Debug\%(Filename).exe $(SolutionDir)..\Bin\ >nul + mkdir $(SolutionDir)..\Bin 2>nul +copy Debug\%(Filename).exe $(SolutionDir)..\Bin\ >nul copy Debug\%(Filename).map $(SolutionDir)..\Bin\ >nul Document - pushd $(SolutionDir) -bison -o$(ProjectName)/Parser.c $(ProjectName)/Parser.y -d -popd -copy %(RootDir)%(Directory)\Parser.c %(RootDir)%(Directory)\Parser.cpp + pushd $(SolutionDir) +bison -o$(ProjectName)/Parser.c $(ProjectName)/Parser.y -d +popd +copy %(RootDir)%(Directory)\Parser.c %(RootDir)%(Directory)\Parser.cpp del %(RootDir)%(Directory)\Parser.c /q - pushd $(SolutionDir) -bison -o$(ProjectName)/Parser.c $(ProjectName)/Parser.y -d -popd -copy %(RootDir)%(Directory)\Parser.c %(RootDir)%(Directory)\Parser.cpp + pushd $(SolutionDir) +bison -o$(ProjectName)/Parser.c $(ProjectName)/Parser.y -d +popd +copy %(RootDir)%(Directory)\Parser.c %(RootDir)%(Directory)\Parser.cpp del %(RootDir)%(Directory)\Parser.c /q Creating parser source Creating parser source %(RootDir)%(Directory)\Parser.cpp;%(RootDir)%(Directory)\Parser.h;%(Outputs) %(RootDir)%(Directory)\Parser.cpp;%(RootDir)%(Directory)\Parser.h;%(Outputs) - pushd $(SolutionDir) -bison -o$(ProjectName)/Parser.c $(ProjectName)/Parser.y -d -popd -copy %(RootDir)%(Directory)\Parser.c %(RootDir)%(Directory)\Parser.cpp + pushd $(SolutionDir) +bison -o$(ProjectName)/Parser.c $(ProjectName)/Parser.y -d +popd +copy %(RootDir)%(Directory)\Parser.c %(RootDir)%(Directory)\Parser.cpp del %(RootDir)%(Directory)\Parser.c /q - pushd $(SolutionDir) -bison -o$(ProjectName)/Parser.c $(ProjectName)/Parser.y -d -popd -copy %(RootDir)%(Directory)\Parser.c %(RootDir)%(Directory)\Parser.cpp + pushd $(SolutionDir) +bison -o$(ProjectName)/Parser.c $(ProjectName)/Parser.y -d +popd +copy %(RootDir)%(Directory)\Parser.c %(RootDir)%(Directory)\Parser.cpp del %(RootDir)%(Directory)\Parser.c /q Creating parser source Creating parser source @@ -393,4 +389,4 @@ del %(RootDir)%(Directory)\Parser.c /q - \ No newline at end of file + diff --git a/Sources/Ecc/Ecc.vcxproj.filters b/Sources/Ecc/Ecc.vcxproj.filters index 18fab06..0b479e1 100644 --- a/Sources/Ecc/Ecc.vcxproj.filters +++ b/Sources/Ecc/Ecc.vcxproj.filters @@ -1,57 +1,57 @@ - - - - - {acd5aeef-9312-4c06-9a18-ffc69148b586} - cpp - - - {97120739-0d00-462f-bb75-be637f0e69f3} - - - {414eb5ab-c891-41f1-85bb-3594afce7081} - c - - - {aebfcf57-f684-490f-baf9-b3c0fd748e23} - h;hpp;hxx;hm;inl;fi;fd - - - {cf15f1a2-66f9-41f7-872d-8fbaa310a5e2} - ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe - - - - - Source Files\Dummy - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files\Grammar files - - - Source Files\Grammar files - - + + + + + {acd5aeef-9312-4c06-9a18-ffc69148b586} + cpp + + + {97120739-0d00-462f-bb75-be637f0e69f3} + + + {414eb5ab-c891-41f1-85bb-3594afce7081} + c + + + {aebfcf57-f684-490f-baf9-b3c0fd748e23} + h;hpp;hxx;hm;inl;fi;fd + + + {cf15f1a2-66f9-41f7-872d-8fbaa310a5e2} + ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe + + + + + Source Files\Dummy + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files\Grammar files + + + Source Files\Grammar files + + \ No newline at end of file diff --git a/Sources/Ecc/Ecc.vcxproj.user b/Sources/Ecc/Ecc.vcxproj.user index ace9a86..695b5c7 100644 --- a/Sources/Ecc/Ecc.vcxproj.user +++ b/Sources/Ecc/Ecc.vcxproj.user @@ -1,3 +1,3 @@ - - + + \ No newline at end of file diff --git a/Sources/Ecc/Main.cpp b/Sources/Ecc/Main.cpp index 558ae58..d30ca34 100644 --- a/Sources/Ecc/Main.cpp +++ b/Sources/Ecc/Main.cpp @@ -244,10 +244,10 @@ void ReplaceIfChanged(const char *strOld, const char *strNew) // skip #line directives while(strNewLine[0]=='#' && strNewLine[1]=='l' && !feof(fNew)) { - fgets(strNewLine, sizeof(strNewLine)-1, fNew); + char *str = fgets(strNewLine, sizeof(strNewLine)-1, fNew); } while(strOldLine[0]=='#' && strOldLine[1]=='l' && !feof(fOld)) { - fgets(strOldLine, sizeof(strOldLine)-1, fOld); + char *str = fgets(strOldLine, sizeof(strOldLine)-1, fOld); } if (strcmp(strNewLine, strOldLine)!=0) { iChanged = 1; diff --git a/Sources/Ecc/Parser.y b/Sources/Ecc/Parser.y index 3315f97..383bacf 100644 --- a/Sources/Ecc/Parser.y +++ b/Sources/Ecc/Parser.y @@ -1,1435 +1,1435 @@ -%{ -// rcg10042001 Changed to specify Ecc directory... -#include "Ecc/StdH.h" -#include "Ecc/Main.h" - -// turn off over-helpful bit of bison... --ryan. -#ifdef __GNUC__ -#define __attribute__(x) -#endif - -#define YYINITDEPTH 1000 - -static const char *_strCurrentClass; -static int _iCurrentClassID; -static const char *_strCurrentBase; -static const char *_strCurrentDescription; -static const char *_strCurrentThumbnail; -static const char *_strCurrentEnum; -static int _bClassIsExported = 0; - -static const char *_strCurrentPropertyID; -static const char *_strCurrentPropertyIdentifier; -static const char *_strCurrentPropertyPropertyType; -static const char *_strCurrentPropertyEnumType; -static const char *_strCurrentPropertyDataType; -static const char *_strCurrentPropertyName; -static const char *_strCurrentPropertyShortcut; -static const char *_strCurrentPropertyColor; -static const char *_strCurrentPropertyFlags; -static const char *_strCurrentPropertyDefaultCode; - -static const char *_strCurrentComponentIdentifier; -static const char *_strCurrentComponentType; -static const char *_strCurrentComponentID; -static const char *_strCurrentComponentFileName; - -static int _ctInProcedureHandler = 0; -static char _strLastProcedureName[256]; - -static char _strInWaitName[256]; -static char _strAfterWaitName[256]; -static char _strInWaitID[256]; -static char _strAfterWaitID[256]; - -static char _strInLoopName[256]; -static char _strAfterLoopName[256]; -static char _strInLoopID[256]; -static char _strAfterLoopID[256]; -static char _strCurrentStateID[256]; - -static int _bInProcedure; // set if currently compiling a procedure -static int _bInHandler; -static int _bHasOtherwise; // set if current 'wait' block has an 'otherwise' statement - -static const char *_strCurrentEvent; -static int _bFeature_AbstractBaseClass; -static int _bFeature_ImplementsOnInitClass; -static int _bFeature_ImplementsOnEndClass; -static int _bFeature_ImplementsOnPrecache; -static int _bFeature_ImplementsOnWorldInit; -static int _bFeature_ImplementsOnWorldEnd; -static int _bFeature_ImplementsOnWorldTick; -static int _bFeature_ImplementsOnWorldRender; -static int _bFeature_CanBePredictable; - -static int _iNextFreeID; -inline int CreateID(void) { - return _iNextFreeID++; -} - -static int _ctBraces = 0; -void OpenBrace(void) { - _ctBraces++; -} -void CloseBrace(void) { - _ctBraces--; -} -SType Braces(int iBraces) { - static char strBraces[50]; - memset(strBraces, '}', sizeof(strBraces)); - strBraces[iBraces] = 0; - return SType(strBraces); -} -char *RemoveLineDirective(char *str) -{ - if (str[0]=='\n' && str[1]=='#') { - return strchr(str+2, '\n')+1; - } else { - return str; - } -} -const char *GetLineDirective(SType &st) -{ - char *str = st.strString; - if (str[0]=='\n' && str[1]=='#' && str[2]=='l') { - char *strResult = strdup(str); - strchr(strResult+3,'\n')[1] = 0; - return strResult; - } else { - return ""; - } -} -void AddHandlerFunction(char *strProcedureName, int iStateID) -{ - fprintf(_fDeclaration, " BOOL %s(const CEntityEvent &__eeInput);\n", strProcedureName); - fprintf(_fTables, " {0x%08x, -1, CEntity::pEventHandler(&%s::%s), " - "DEBUGSTRING(\"%s::%s\")},\n", - iStateID, _strCurrentClass, strProcedureName, _strCurrentClass, strProcedureName); -} - - -void AddHandlerFunction(char *strProcedureName, char *strStateID, char *strBaseStateID) -{ - fprintf(_fDeclaration, " BOOL %s(const CEntityEvent &__eeInput);\n", strProcedureName); - fprintf(_fTables, " {%s, %s, CEntity::pEventHandler(&%s::%s)," - "DEBUGSTRING(\"%s::%s\")},\n", - strStateID, strBaseStateID, _strCurrentClass, strProcedureName, - _strCurrentClass, RemoveLineDirective(strProcedureName)); - strcpy(_strLastProcedureName, RemoveLineDirective(strProcedureName)); - _ctInProcedureHandler = 0; -} - -void CreateInternalHandlerFunction(char *strFunctionName, char *strID) -{ - int iID = CreateID(); - _ctInProcedureHandler++; - sprintf(strID, "0x%08x", iID); - sprintf(strFunctionName, "H0x%08x_%s_%02d", iID, _strLastProcedureName, _ctInProcedureHandler); - AddHandlerFunction(strFunctionName, iID); -} - -void DeclareFeatureProperties(void) -{ - if (_bFeature_CanBePredictable) { - fprintf(_fTables, " CEntityProperty(CEntityProperty::EPT_ENTITYPTR, NULL, (0x%08x<<8)+%s, _offsetof(%s, %s), %s, %s, %s, %s),\n", - _iCurrentClassID, - "255", - _strCurrentClass, - "m_penPrediction", - "\"\"", - "0", - "0", - "0"); - fprintf(_fDeclaration, " %s %s;\n", - "CEntityPointer", - "m_penPrediction" - ); - fprintf(_fImplementation, " m_penPrediction = NULL;\n"); - } -} - -#define YYERROR_VERBOSE 1 - -%} - -/* BISON Declarations */ - -/* different type of constants */ -%token c_char -%token c_int -%token c_float -%token c_bool -%token c_string - -/* the standard cpp identifier */ -%token identifier - -/* specially bracketed cpp blocks */ -%token cppblock - -/* standard cpp-keywords */ -%token k_while -%token k_for -%token k_if -%token k_else -%token k_enum -%token k_switch -%token k_case -%token k_class -%token k_do -%token k_void -%token k_const -%token k_inline -%token k_static -%token k_virtual -%token k_return -%token k_autowait -%token k_autocall -%token k_waitevent - -/* aditional keywords */ -%token k_event -%token k_name -%token k_thumbnail -%token k_features -%token k_uses -%token k_export - -%token k_texture -%token k_sound -%token k_model - -%token k_properties -%token k_components -%token k_functions -%token k_procedures - -%token k_wait -%token k_on -%token k_otherwise - -%token k_call -%token k_jump -%token k_stop -%token k_resume -%token k_pass - -/* special data types */ -%token k_CTString -%token k_CTStringTrans -%token k_CTFileName -%token k_CTFileNameNoDep -%token k_BOOL -%token k_COLOR -%token k_FLOAT -%token k_INDEX -%token k_RANGE -%token k_CEntityPointer -%token k_CModelObject -%token k_CModelInstance -%token k_CAnimObject -%token k_CSoundObject -%token k_CPlacement3D -%token k_FLOATaabbox3D -%token k_FLOATmatrix3D -%token k_FLOATquat3D -%token k_ANGLE -%token k_FLOAT3D -%token k_ANGLE3D -%token k_FLOATplane3D -%token k_ANIMATION -%token k_ILLUMINATIONTYPE -%token k_FLAGS - -%start program - -%% - -/*///////////////////////////////////////////////////////// - * Global structure of the source file. - */ -program - : /* empty file */ {} - | c_int { - int iID = atoi($1.strString); - if(iID>32767) { - yyerror("Maximum allowed id for entity source file is 32767"); - } - _iCurrentClassID = iID; - _iNextFreeID = iID<<16; - fprintf(_fDeclaration, "#ifndef _%s_INCLUDED\n", _strFileNameBaseIdentifier); - fprintf(_fDeclaration, "#define _%s_INCLUDED 1\n", _strFileNameBaseIdentifier); - - } opt_global_cppblock { - - //fprintf(_fImplementation, "\n#undef DECL_DLL\n#define DECL_DLL _declspec(dllimport)\n"); - } uses_list { - //fprintf(_fImplementation, "\n#undef DECL_DLL\n#define DECL_DLL _declspec(dllexport)\n"); - - fprintf(_fImplementation, "#include <%s.h>\n", _strFileNameBase); - fprintf(_fImplementation, "#include <%s_tables.h>\n", _strFileNameBase); - } enum_and_event_declarations_list { - } opt_global_cppblock { - } opt_class_declaration { - fprintf(_fDeclaration, "#endif // _%s_INCLUDED\n", _strFileNameBaseIdentifier); - } - ; - - -/* - * Prolog cpp code. - */ -opt_global_cppblock - : /* null */ - | cppblock { fprintf(_fImplementation, "%s\n", $1.strString); } - ; - -uses_list - : /* null */ - | uses_list uses_statement - ; -uses_statement - : k_uses c_string ';' { - char *strUsedFileName = strdup($2.strString); - strUsedFileName[strlen(strUsedFileName)-1] = 0; - fprintf(_fDeclaration, "#include <%s.h>\n", strUsedFileName+1); - } - ; - - -enum_and_event_declarations_list - : /* null */ - | enum_and_event_declarations_list enum_declaration - | enum_and_event_declarations_list event_declaration - ; -/*///////////////////////////////////////////////////////// - * Enum types declarations - */ -enum_declaration - : k_enum identifier { - _strCurrentEnum = $2.strString; - fprintf(_fTables, "EP_ENUMBEG(%s)\n", _strCurrentEnum ); - fprintf(_fDeclaration, "extern DECL_DLL CEntityPropertyEnumType %s_enum;\n", _strCurrentEnum ); - fprintf(_fDeclaration, "enum %s {\n", _strCurrentEnum ); - } '{' enum_values_list opt_comma '}' ';' { - fprintf(_fTables, "EP_ENUMEND(%s);\n\n", _strCurrentEnum); - fprintf(_fDeclaration, "};\n"); - fprintf(_fDeclaration, "DECL_DLL inline void ClearToDefault(%s &e) { e = (%s)0; } ;\n", _strCurrentEnum, _strCurrentEnum); - } - ; -opt_comma : /*null*/ | ','; -enum_values_list - : enum_value - | enum_values_list ',' enum_value - ; - -enum_value - : c_int identifier c_string { - fprintf(_fTables, " EP_ENUMVALUE(%s, %s),\n", $2.strString, $3.strString); - fprintf(_fDeclaration, " %s = %s,\n", $2.strString, $1.strString); - } - ; - -/*///////////////////////////////////////////////////////// - * Event declarations - */ -event_declaration - : k_event identifier { - _strCurrentEvent = $2.strString; - int iID = CreateID(); - fprintf(_fDeclaration, "#define EVENTCODE_%s 0x%08x\n", _strCurrentEvent, iID); - fprintf(_fDeclaration, "class DECL_DLL %s : public CEntityEvent {\npublic:\n", - _strCurrentEvent); - fprintf(_fDeclaration, "%s();\n", _strCurrentEvent ); - fprintf(_fDeclaration, "CEntityEvent *MakeCopy(void);\n"); - fprintf(_fImplementation, - "CEntityEvent *%s::MakeCopy(void) { " - "CEntityEvent *peeCopy = new %s(*this); " - "return peeCopy;}\n", - _strCurrentEvent, _strCurrentEvent); - fprintf(_fImplementation, "%s::%s() : CEntityEvent(EVENTCODE_%s) {;\n", - _strCurrentEvent, _strCurrentEvent, _strCurrentEvent); - } '{' event_members_list opt_comma '}' ';' { - fprintf(_fImplementation, "};\n"); - fprintf(_fDeclaration, "};\n"); - fprintf(_fDeclaration, "DECL_DLL inline void ClearToDefault(%s &e) { e = %s(); } ;\n", _strCurrentEvent, _strCurrentEvent); - } - ; - -event_members_list - : /* null */ - | non_empty_event_members_list - ; - -non_empty_event_members_list - : event_member - | event_members_list ',' event_member - ; - -event_member - : any_type identifier { - fprintf(_fDeclaration, "%s %s;\n", $1.strString, $2.strString); - fprintf(_fImplementation, " ClearToDefault(%s);\n", $2.strString); - } - ; - -/*///////////////////////////////////////////////////////// - * The class declaration structure. - */ -opt_class_declaration - : /* null */ - | class_declaration - ; - -class_declaration - : /* null */ - | class_optexport identifier ':' identifier '{' - k_name c_string ';' - k_thumbnail c_string ';' { - _strCurrentClass = $2.strString; - _strCurrentBase = $4.strString; - _strCurrentDescription = $7.strString; - _strCurrentThumbnail = $10.strString; - - fprintf(_fTables, "#define ENTITYCLASS %s\n\n", _strCurrentClass); - fprintf(_fDeclaration, "extern \"C\" DECL_DLL CDLLEntityClass %s_DLLClass;\n", - _strCurrentClass); - fprintf(_fDeclaration, "%s %s : public %s {\npublic:\n", - $1.strString, _strCurrentClass, _strCurrentBase); - - } opt_features { - fprintf(_fDeclaration, " %s virtual void SetDefaultProperties(void);\n", _bClassIsExported?"":"DECL_DLL"); - fprintf(_fImplementation, "void %s::SetDefaultProperties(void) {\n", _strCurrentClass); - fprintf(_fTables, "CEntityProperty %s_properties[] = {\n", _strCurrentClass); - - } k_properties ':' property_declaration_list { - fprintf(_fImplementation, " %s::SetDefaultProperties();\n}\n", _strCurrentBase); - - fprintf(_fTables, "CEntityComponent %s_components[] = {\n", _strCurrentClass); - } opt_internal_properties { - } k_components ':' component_declaration_list { - _bTrackLineInformation = 1; - fprintf(_fTables, "CEventHandlerEntry %s_handlers[] = {\n", _strCurrentClass); - - _bInProcedure = 0; - _bInHandler = 0; - } k_functions ':' function_list { - - _bInProcedure = 1; - } k_procedures ':' procedure_list { - } '}' ';' { - fprintf(_fTables, "};\n#define %s_handlersct ARRAYCOUNT(%s_handlers)\n", - _strCurrentClass, _strCurrentClass); - fprintf(_fTables, "\n"); - - if (_bFeature_AbstractBaseClass) { - fprintf(_fTables, "CEntity *%s_New(void) { return NULL; };\n", - _strCurrentClass); - } else { - fprintf(_fTables, "CEntity *%s_New(void) { return new %s; };\n", - _strCurrentClass, _strCurrentClass); - } - - if (!_bFeature_ImplementsOnInitClass) { - fprintf(_fTables, "void %s_OnInitClass(void) {};\n", _strCurrentClass); - } else { - fprintf(_fTables, "void %s_OnInitClass(void);\n", _strCurrentClass); - } - - if (!_bFeature_ImplementsOnEndClass) { - fprintf(_fTables, "void %s_OnEndClass(void) {};\n", _strCurrentClass); - } else { - fprintf(_fTables, "void %s_OnEndClass(void);\n", _strCurrentClass); - } - - if (!_bFeature_ImplementsOnPrecache) { - fprintf(_fTables, "void %s_OnPrecache(CDLLEntityClass *pdec, INDEX iUser) {};\n", _strCurrentClass); - } else { - fprintf(_fTables, "void %s_OnPrecache(CDLLEntityClass *pdec, INDEX iUser);\n", _strCurrentClass); - } - - if (!_bFeature_ImplementsOnWorldEnd) { - fprintf(_fTables, "void %s_OnWorldEnd(CWorld *pwo) {};\n", _strCurrentClass); - } else { - fprintf(_fTables, "void %s_OnWorldEnd(CWorld *pwo);\n", _strCurrentClass); - } - - if (!_bFeature_ImplementsOnWorldInit) { - fprintf(_fTables, "void %s_OnWorldInit(CWorld *pwo) {};\n", _strCurrentClass); - } else { - fprintf(_fTables, "void %s_OnWorldInit(CWorld *pwo);\n", _strCurrentClass); - } - - if (!_bFeature_ImplementsOnWorldTick) { - fprintf(_fTables, "void %s_OnWorldTick(CWorld *pwo) {};\n", _strCurrentClass); - } else { - fprintf(_fTables, "void %s_OnWorldTick(CWorld *pwo);\n", _strCurrentClass); - } - - if (!_bFeature_ImplementsOnWorldRender) { - fprintf(_fTables, "void %s_OnWorldRender(CWorld *pwo) {};\n", _strCurrentClass); - } else { - fprintf(_fTables, "void %s_OnWorldRender(CWorld *pwo);\n", _strCurrentClass); - } - - fprintf(_fTables, "ENTITY_CLASSDEFINITION(%s, %s, %s, %s, 0x%08x);\n", - _strCurrentClass, _strCurrentBase, - _strCurrentDescription, _strCurrentThumbnail, _iCurrentClassID); - fprintf(_fTables, "DECLARE_CTFILENAME(_fnm%s_tbn, %s);\n", _strCurrentClass, _strCurrentThumbnail); - - fprintf(_fDeclaration, "};\n"); - } - ; - -class_optexport - : k_class { $$ = $1; _bClassIsExported = 0; } - | k_class k_export { $$ = $1+" DECL_DLL "; _bClassIsExported = 1; } - ; - -opt_features - : /*null */ - | k_features { - _bFeature_ImplementsOnWorldInit = 0; - _bFeature_ImplementsOnWorldEnd = 0; - _bFeature_ImplementsOnWorldTick = 0; - _bFeature_ImplementsOnWorldRender = 0; - _bFeature_ImplementsOnInitClass = 0; - _bFeature_ImplementsOnEndClass = 0; - _bFeature_ImplementsOnPrecache = 0; - _bFeature_AbstractBaseClass = 0; - _bFeature_CanBePredictable = 0; - }features_list ';' - ; -features_list - : feature - | features_list ',' feature - ; -feature - : c_string { - if (strcmp($1.strString, "\"AbstractBaseClass\"")==0) { - _bFeature_AbstractBaseClass = 1; - } else if (strcmp($1.strString, "\"IsTargetable\"")==0) { - fprintf(_fDeclaration, "virtual BOOL IsTargetable(void) const { return TRUE; };\n"); - } else if (strcmp($1.strString, "\"IsImportant\"")==0) { - fprintf(_fDeclaration, "virtual BOOL IsImportant(void) const { return TRUE; };\n"); - } else if (strcmp($1.strString, "\"HasName\"")==0) { - fprintf(_fDeclaration, - "virtual const CTString &GetName(void) const { return m_strName; };\n"); - } else if (strcmp($1.strString, "\"CanBePredictable\"")==0) { - fprintf(_fDeclaration, - "virtual CEntity *GetPredictionPair(void) { return m_penPrediction; };\n"); - fprintf(_fDeclaration, - "virtual void SetPredictionPair(CEntity *penPair) { m_penPrediction = penPair; };\n"); - _bFeature_CanBePredictable = 1; - } else if (strcmp($1.strString, "\"HasDescription\"")==0) { - fprintf(_fDeclaration, - "virtual const CTString &GetDescription(void) const { return m_strDescription; };\n"); - } else if (strcmp($1.strString, "\"HasTarget\"")==0) { - fprintf(_fDeclaration, - "virtual CEntity *GetTarget(void) const { return m_penTarget; };\n"); - } else if (strcmp($1.strString, "\"ImplementsOnInitClass\"")==0) { - _bFeature_ImplementsOnInitClass = 1; - } else if (strcmp($1.strString, "\"ImplementsOnEndClass\"")==0) { - _bFeature_ImplementsOnEndClass = 1; - } else if (strcmp($1.strString, "\"ImplementsOnPrecache\"")==0) { - _bFeature_ImplementsOnPrecache = 1; - } else if (strcmp($1.strString, "\"ImplementsOnWorldInit\"")==0) { - _bFeature_ImplementsOnWorldInit = 1; - } else if (strcmp($1.strString, "\"ImplementsOnWorldEnd\"")==0) { - _bFeature_ImplementsOnWorldEnd = 1; - } else if (strcmp($1.strString, "\"ImplementsOnWorldTick\"")==0) { - _bFeature_ImplementsOnWorldTick = 1; - } else if (strcmp($1.strString, "\"ImplementsOnWorldRender\"")==0) { - _bFeature_ImplementsOnWorldRender = 1; - } else { - yyerror((SType("Unknown feature: ")+$1).strString); - } - } - ; - -opt_internal_properties - : /* null */ - | '{' internal_property_list '}' - ; -internal_property_list - : /* null */ - | internal_property_list internal_property - ; -internal_property - : any_type identifier ';' { - fprintf(_fDeclaration, "%s %s;\n", $1.strString, $2.strString); - } - ; - -/*///////////////////////////////////////////////////////// - * Property declarations - */ - -property_declaration_list - : empty_property_declaration_list { - DeclareFeatureProperties(); // this won't work, but at least it will generate an error!!!! - fprintf(_fTables, " CEntityProperty()\n};\n"); - fprintf(_fTables, "#define %s_propertiesct 0\n", _strCurrentClass); - fprintf(_fTables, "\n"); - fprintf(_fTables, "\n"); - } - | nonempty_property_declaration_list opt_comma { - DeclareFeatureProperties(); - fprintf(_fTables, "};\n"); - fprintf(_fTables, "#define %s_propertiesct ARRAYCOUNT(%s_properties)\n", - _strCurrentClass, _strCurrentClass); - fprintf(_fTables, "\n"); - } - ; -nonempty_property_declaration_list - : property_declaration - | nonempty_property_declaration_list ',' property_declaration - ; -empty_property_declaration_list - : /* null */ - ; - -property_declaration - : property_id property_type property_identifier property_wed_name_opt property_default_opt property_flags_opt { - fprintf(_fTables, " CEntityProperty(%s, %s, (0x%08x<<8)+%s, _offsetof(%s, %s), %s, %s, %s, %s),\n", - _strCurrentPropertyPropertyType, - _strCurrentPropertyEnumType, - _iCurrentClassID, - _strCurrentPropertyID, - _strCurrentClass, - _strCurrentPropertyIdentifier, - _strCurrentPropertyName, - _strCurrentPropertyShortcut, - _strCurrentPropertyColor, - _strCurrentPropertyFlags); - fprintf(_fDeclaration, " %s %s;\n", - _strCurrentPropertyDataType, - _strCurrentPropertyIdentifier - ); - - if (strlen(_strCurrentPropertyDefaultCode)>0) { - fprintf(_fImplementation, " %s\n", _strCurrentPropertyDefaultCode); - } - } - ; - -property_id : c_int { _strCurrentPropertyID = $1.strString; }; -property_identifier : identifier { _strCurrentPropertyIdentifier = $1.strString; }; - -property_type - : k_enum identifier { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ENUM"; - _strCurrentPropertyEnumType = (SType("&")+$2+"_enum").strString; - _strCurrentPropertyDataType = (SType("enum ")+$2.strString).strString; - } - | k_FLAGS identifier { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLAGS"; - _strCurrentPropertyEnumType = (SType("&")+$2+"_enum").strString; - _strCurrentPropertyDataType = "ULONG"; - } - | k_CTString { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_STRING"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "CTString"; - } - | k_CTStringTrans { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_STRINGTRANS"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "CTStringTrans"; - } - | k_CTFileName { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FILENAME"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "CTFileName"; - } - | k_CTFileNameNoDep { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FILENAMENODEP"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "CTFileNameNoDep"; - } - | k_BOOL { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_BOOL"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "BOOL"; - } - | k_COLOR { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_COLOR"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "COLOR"; - } - | k_FLOAT { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLOAT"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "FLOAT"; - } - | k_INDEX { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_INDEX"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "INDEX"; - } - | k_RANGE { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_RANGE"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "RANGE"; - } - | k_CEntityPointer { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ENTITYPTR"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "CEntityPointer"; - } - | k_CModelObject { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_MODELOBJECT"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "CModelObject"; - } - | k_CModelInstance { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_MODELINSTANCE"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "CModelInstance"; - } - | k_CAnimObject { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ANIMOBJECT"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "CAnimObject"; - } - | k_CSoundObject { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_SOUNDOBJECT"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "CSoundObject"; - } - | k_CPlacement3D { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_PLACEMENT3D"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "CPlacement3D"; - } - | k_FLOATaabbox3D { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLOATAABBOX3D"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "FLOATaabbox3D"; - } - | k_FLOATmatrix3D { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLOATMATRIX3D"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "FLOATmatrix3D"; - } - | k_FLOATquat3D { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLOATQUAT3D"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "FLOATquat3D"; - } - | k_ANGLE { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ANGLE"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "ANGLE"; - } - | k_ANGLE3D { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ANGLE3D"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "ANGLE3D"; - } - | k_FLOAT3D { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLOAT3D"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "FLOAT3D"; - } - | k_FLOATplane3D { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLOATplane3D"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "FLOATplane3D"; - } - | k_ILLUMINATIONTYPE { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ILLUMINATIONTYPE"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "ILLUMINATIONTYPE"; - } - | k_ANIMATION { - _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ANIMATION"; - _strCurrentPropertyEnumType = "NULL"; - _strCurrentPropertyDataType = "ANIMATION"; - } - ; - -property_wed_name_opt - : /* null */ { - _strCurrentPropertyName = "\"\""; - _strCurrentPropertyShortcut = "0"; - _strCurrentPropertyColor = "0"; // this won't be rendered anyway - } - | c_string property_shortcut_opt property_color_opt { - _strCurrentPropertyName = $1.strString; - } - ; -property_shortcut_opt - : /* null */ { - _strCurrentPropertyShortcut = "0"; - } - | c_char { - _strCurrentPropertyShortcut = $1.strString; - } - -property_color_opt - : /* null */ { - _strCurrentPropertyColor = "0x7F0000FFUL"; // dark red - } - | k_COLOR '(' expression ')' { - _strCurrentPropertyColor = $3.strString; - } -property_flags_opt - : /* null */ { - _strCurrentPropertyFlags = "0"; // dark red - } - | k_features '(' expression ')' { - _strCurrentPropertyFlags = $3.strString; - } - -property_default_opt - : /* null */ { - if (strcmp(_strCurrentPropertyDataType,"CEntityPointer")==0) { - _strCurrentPropertyDefaultCode = (SType(_strCurrentPropertyIdentifier)+" = NULL;").strString; - } else if (strcmp(_strCurrentPropertyDataType,"CModelObject")==0) { - _strCurrentPropertyDefaultCode = - (SType(_strCurrentPropertyIdentifier)+".SetData(NULL);\n"+ - _strCurrentPropertyIdentifier+".mo_toTexture.SetData(NULL);").strString; - } else if (strcmp(_strCurrentPropertyDataType,"CModelInstance")==0) { - _strCurrentPropertyDefaultCode = - (SType(_strCurrentPropertyIdentifier)+".Clear();\n").strString; - } else if (strcmp(_strCurrentPropertyDataType,"CAnimObject")==0) { - _strCurrentPropertyDefaultCode = - (SType(_strCurrentPropertyIdentifier)+".SetData(NULL);\n").strString; - } else if (strcmp(_strCurrentPropertyDataType,"CSoundObject")==0) { - _strCurrentPropertyDefaultCode = - (SType(_strCurrentPropertyIdentifier)+".SetOwner(this);\n"+ - _strCurrentPropertyIdentifier+".Stop_internal();").strString; - } else { - yyerror("this kind of property must have default value"); - _strCurrentPropertyDefaultCode = ""; - } - } - | '=' property_default_expression { - if (strcmp(_strCurrentPropertyDataType,"CEntityPointer")==0) { - yyerror("CEntityPointer type properties always default to NULL"); - } else { - _strCurrentPropertyDefaultCode = (SType(_strCurrentPropertyIdentifier)+" = "+$2.strString+";").strString; - } - } - ; -property_default_expression - : c_int|c_float|c_bool|c_char|c_string - | identifier {$$ = $1 + " ";} - | identifier '(' expression ')' {$$ = $1+$2+$3+$4;} - | type_keyword '(' expression ')' {$$ = $1+$2+$3+$4;} - | '-' property_default_expression {$$ = $1+$2;} - | '(' expression ')' {$$ = $1+$2+$3;} - ; - -/*///////////////////////////////////////////////////////// - * Component declarations - */ -component_declaration_list - : empty_component_declaration_list { - fprintf(_fTables, " CEntityComponent()\n};\n"); - fprintf(_fTables, "#define %s_componentsct 0\n", _strCurrentClass); - fprintf(_fTables, "\n"); - fprintf(_fTables, "\n"); - } - | nonempty_component_declaration_list opt_comma { - fprintf(_fTables, "};\n"); - fprintf(_fTables, "#define %s_componentsct ARRAYCOUNT(%s_components)\n", - _strCurrentClass, _strCurrentClass); - fprintf(_fTables, "\n"); - } - ; -nonempty_component_declaration_list - : component_declaration - | nonempty_component_declaration_list ',' component_declaration - ; -empty_component_declaration_list - : /* null */ - ; - -component_declaration - : component_id component_type component_identifier component_filename { - fprintf(_fTables, "#define %s ((0x%08x<<8)+%s)\n", - _strCurrentComponentIdentifier, - _iCurrentClassID, - _strCurrentComponentID); - fprintf(_fTables, " CEntityComponent(%s, %s, \"%s%s\" %s),\n", - _strCurrentComponentType, - _strCurrentComponentIdentifier, - "EF","NM", - _strCurrentComponentFileName); - } - ; - -component_id : c_int { _strCurrentComponentID = $1.strString; }; -component_identifier : identifier { _strCurrentComponentIdentifier = $1.strString; }; -component_filename : c_string { _strCurrentComponentFileName = $1.strString; }; - -component_type - : k_model { _strCurrentComponentType = "ECT_MODEL"; } - | k_texture { _strCurrentComponentType = "ECT_TEXTURE"; } - | k_sound { _strCurrentComponentType = "ECT_SOUND"; } - | k_class { _strCurrentComponentType = "ECT_CLASS"; } - ; - -/*///////////////////////////////////////////////////////// - * Functions - */ -function_list - : { $$ = "";} - | function_list function_implementation {$$ = $1+$2;} - ; - -function_implementation - : opt_export opt_virtual return_type opt_tilde identifier '(' parameters_list ')' opt_const - '{' statements '}' opt_semicolon { - const char *strReturnType = $3.strString; - const char *strFunctionHeader = ($4+$5+$6+$7+$8+$9).strString; - const char *strFunctionBody = ($10+$11+$12).strString; - if (strcmp($5.strString, _strCurrentClass)==0) { - if (strcmp(strReturnType+strlen(strReturnType)-4, "void")==0 ) { - strReturnType = ""; - } else { - yyerror("use 'void' as return type for constructors"); - } - } - fprintf(_fDeclaration, " %s %s %s %s;\n", - $1.strString, $2.strString, strReturnType, strFunctionHeader); - fprintf(_fImplementation, " %s %s::%s %s\n", - strReturnType, _strCurrentClass, strFunctionHeader, strFunctionBody); - } - ; -opt_tilde - : { $$ = "";} - | '~' { $$ = " ~ "; } - ; - -opt_export - : { $$ = "";} - | k_export { - if (_bClassIsExported) { - $$ = ""; - } else { - $$ = " DECL_DLL "; - } - } - ; - -opt_const - : { $$ = "";} - | k_const { $$ = $1; } - ; -opt_virtual - : { $$ = "";} - | k_virtual { $$ = $1; } - ; -opt_semicolon - : /* null */ - | ';' - ; -parameters_list - : { $$ = "";} - | k_void - | non_void_parameters_list - ; -non_void_parameters_list - : parameter_declaration - | non_void_parameters_list ',' parameter_declaration {$$ = $1+$2+$3;} - ; -parameter_declaration - : any_type identifier { $$=$1+" "+$2; } - ; - -return_type - : any_type - | k_void - ; - -any_type - : type_keyword - | identifier - | k_enum identifier { $$=$1+" "+$2; } - | any_type '*' { $$=$1+" "+$2; } - | any_type '&' { $$=$1+" "+$2; } - | k_void '*' { $$=$1+" "+$2; } - | k_const any_type { $$=$1+" "+$2; } - | k_inline any_type { $$=$1+" "+$2; } - | k_static any_type { $$=$1+" "+$2; } - | k_class any_type { $$=$1+" "+$2; } - | identifier '<' any_type '>' { $$=$1+" "+$2+" "+$3+" "+$4; } - ; - - -/*///////////////////////////////////////////////////////// - * Procedures - */ -procedure_list - : { $$ = "";} - | procedure_list procedure_implementation {$$ = $1+$2;} - ; - -opt_override - : { $$ = "-1"; } - | ':' identifier ':' ':' identifier { - $$ = SType("STATE_")+$2+"_"+$5; - } - ; - -procedure_implementation - : identifier '(' event_specification ')' opt_override { - char *strProcedureName = $1.strString; - char strInputEventType[80]; - char strInputEventName[80]; - sscanf($3.strString, "%s %s", strInputEventType, strInputEventName); - - char strStateID[256]; - const char *strBaseStateID = "-1"; - if(strcmp(RemoveLineDirective(strProcedureName), "Main")==0){ - strcpy(strStateID, "1"); - if(strncmp(strInputEventType, "EVoid", 4)!=0 && _strCurrentThumbnail[2]!=0) { - yyerror("procedure 'Main' can take input parameters only in classes without thumbnails"); - } - } else { - sprintf(strStateID, "0x%08x", CreateID()); - } - - sprintf(_strCurrentStateID, "STATE_%s_%s", - _strCurrentClass, RemoveLineDirective(strProcedureName)); - fprintf(_fDeclaration, "#define %s %s\n", _strCurrentStateID, strStateID); - AddHandlerFunction(strProcedureName, strStateID, $5.strString); - fprintf(_fImplementation, - "BOOL %s::%s(const CEntityEvent &__eeInput) {\n#undef STATE_CURRENT\n#define STATE_CURRENT %s\n", - _strCurrentClass, strProcedureName, _strCurrentStateID); - fprintf(_fImplementation, - " ASSERTMSG(__eeInput.ee_slEvent==EVENTCODE_%s, \"%s::%s expects '%s' as input!\");", - strInputEventType, _strCurrentClass, RemoveLineDirective(strProcedureName), - strInputEventType); - fprintf(_fImplementation, " const %s &%s = (const %s &)__eeInput;", - strInputEventType, strInputEventName, strInputEventType); - - } '{' statements '}' opt_semicolon { - char *strFunctionBody = $8.strString; - fprintf(_fImplementation, "%s ASSERT(FALSE); return TRUE;};", strFunctionBody); - } - ; - -event_specification - : { - $$="EVoid e"; - } - | identifier { - $$=$1+" e"; - } - | identifier identifier { - $$=$1+" "+$2; - } - ; - -expression - : c_int|c_float|c_bool|c_char|c_string - | identifier {$$ = $1 + " ";} - | type_keyword - | '='|'+'|'-'|'<'|'>'|'!'|'|'|'&'|'*'|'/'|'%'|'^'|'['|']'|':'|','|'.'|'?'|'~' - | '(' ')' {$$=$1+$2;} - | '+' '+' {$$=$1+$2;} - | '-' '-' {$$=$1+$2;} - | '-' '>' {$$=$1+$2;} - | ':' ':' {$$=$1+$2;} - | '&' '&' {$$=$1+$2;} - | '|' '|' {$$=$1+$2;} - | '^' '^' {$$=$1+$2;} - | '>' '>' {$$=$1+$2;} - | '<' '<' {$$=$1+$2;} - | '=' '=' {$$=$1+$2;} - | '!' '=' {$$=$1+$2;} - | '>' '=' {$$=$1+$2;} - | '<' '=' {$$=$1+$2;} - | '&' '=' {$$=$1+$2;} - | '|' '=' {$$=$1+$2;} - | '^' '=' {$$=$1+$2;} - | '+' '=' {$$=$1+$2;} - | '-' '=' {$$=$1+$2;} - | '/' '=' {$$=$1+$2;} - | '%' '=' {$$=$1+$2;} - | '*' '=' {$$=$1+$2;} - | '>' '>' '=' {$$=$1+$2+$3;} - | '<' '<' '=' {$$=$1+$2+$3;} - | '(' expression ')' {$$ = $1+$2+$3;} - | expression expression {$$ = $1+" "+$2;} - ; -type_keyword - : k_CTString|k_CTStringTrans|k_CTFileName|k_CTFileNameNoDep - | k_BOOL|k_COLOR|k_FLOAT|k_INDEX|k_RANGE - | k_CEntityPointer|k_CModelObject|k_CModelInstance|k_CAnimObject|k_CSoundObject - | k_CPlacement3D | k_FLOATaabbox3D|k_FLOATmatrix3D| k_FLOATquat3D|k_ANGLE|k_ANIMATION|k_ILLUMINATIONTYPE - | k_ANGLE3D|k_FLOAT3D|k_FLOATplane3D - | k_const - | k_static - ; -case_constant_expression - : c_int|c_float|c_bool|c_char|c_string - | identifier {$$ = $1 + " ";} - ; - - -/* Simple statements: - */ -statements - : { $$ = "";} - | statements statement { $$ = $1+$2; } - ; -statement - : expression ';' {$$=$1+$2;} - | k_switch '(' expression ')' '{' statements '}' {$$=$1+$2+$3+$4+$5+$6+$7;} - | k_case case_constant_expression ':' {$$=$1+" "+$2+$3+" ";} - | '{' statements '}' {$$=$1+$2+$3;} - | expression '{' statements '}' {$$=$1+$2+$3+$4;} - | statement_while - | statement_dowhile - | statement_for - | statement_if - | statement_if_else - | statement_wait - | statement_autowait - | statement_waitevent - | statement_call - | statement_autocall - | statement_stop - | statement_resume - | statement_pass - | statement_return - | statement_jump - | ';' - ; - - -statement_if - : k_if '(' expression ')' '{' statements '}' { - if ($6.bCrossesStates) { - char strAfterIfName[80], strAfterIfID[11]; - CreateInternalHandlerFunction(strAfterIfName, strAfterIfID); - $$ = $1+"(!"+$2+$3+$4+"){ Jump(STATE_CURRENT,"+strAfterIfID+", FALSE, EInternal());return TRUE;}"+$6+ - "Jump(STATE_CURRENT,"+strAfterIfID+", FALSE, EInternal());return TRUE;}"+ - "BOOL "+_strCurrentClass+"::"+strAfterIfName+"(const CEntityEvent &__eeInput){"+ - "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+ - "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+strAfterIfID+"\n"; - } else { - $$ = $1+$2+$3+$4+$5+$6+$7; - } - } - ; - -statement_if_else - : k_if '(' expression ')' '{' statements '}' k_else statement { - if ($6.bCrossesStates || $9.bCrossesStates) { - char strAfterIfName[80], strAfterIfID[11]; - char strElseName[80], strElseID[11]; - CreateInternalHandlerFunction(strAfterIfName, strAfterIfID); - CreateInternalHandlerFunction(strElseName, strElseID); - $$ = $1+"(!"+$2+$3+$4+"){ Jump(STATE_CURRENT,"+strElseID+", FALSE, EInternal());return TRUE;}"+ - $6+"Jump(STATE_CURRENT,"+strAfterIfID+", FALSE, EInternal());return TRUE;}"+ - "BOOL "+_strCurrentClass+"::"+strElseName+"(const CEntityEvent &__eeInput){"+ - "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+ - "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+strElseID+"\n"+ - $9+"Jump(STATE_CURRENT,"+strAfterIfID+", FALSE, EInternal());return TRUE;}\n"+ - "BOOL "+_strCurrentClass+"::"+strAfterIfName+"(const CEntityEvent &__eeInput){"+ - "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+ - "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+strAfterIfID+"\n"; - } else { - $$ = $1+$2+$3+$4+$5+$6+$7+$8+" "+$9; - } - } - ; - -statement_while - : k_while '(' expression ')' { - if (strlen(_strInLoopName)>0) { - yyerror("Nested loops are not implemented yet"); - } - } '{' statements '}' { - if ($7.bCrossesStates) { - CreateInternalHandlerFunction(_strInLoopName, _strInLoopID); - CreateInternalHandlerFunction(_strAfterLoopName, _strAfterLoopID); - $$ = SType(GetLineDirective($1))+"Jump(STATE_CURRENT,"+_strInLoopID+", FALSE, EInternal());return TRUE;}"+ - "BOOL "+_strCurrentClass+"::"+_strInLoopName+"(const CEntityEvent &__eeInput)"+$6+ - "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+ - "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strInLoopID+"\n"+ - "if(!"+$2+$3+$4+"){ Jump(STATE_CURRENT,"+_strAfterLoopID+", FALSE, EInternal());return TRUE;}"+ - $7+"Jump(STATE_CURRENT,"+_strInLoopID+", FALSE, EInternal());return TRUE;"+$8+ - "BOOL "+_strCurrentClass+"::"+_strAfterLoopName+"(const CEntityEvent &__eeInput) {"+ - "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+ - "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strAfterLoopID+"\n"; - } else { - $$ = $1+$2+$3+$4+$6+$7+$8; - } - _strInLoopName[0] = 0; - } - ; - -statement_dowhile - : k_do '{' statements '}' { - if (strlen(_strInLoopName)>0) { - yyerror("Nested loops are not implemented yet"); - } - _strInLoopName[0] = 0; - } k_while '(' expression ')' ';' { - if ($3.bCrossesStates) { - CreateInternalHandlerFunction(_strInLoopName, _strInLoopID); - CreateInternalHandlerFunction(_strAfterLoopName, _strAfterLoopID); - $$ = SType(GetLineDirective($1))+"Jump(STATE_CURRENT,"+_strInLoopID+", FALSE, EInternal());return TRUE;}"+ - "BOOL "+_strCurrentClass+"::"+_strInLoopName+"(const CEntityEvent &__eeInput)"+$2+ - "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+ - "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strInLoopID+"\n"+$3+ - "if(!"+$7+$8+$9+"){ Jump(STATE_CURRENT,"+_strAfterLoopID+", FALSE, EInternal());return TRUE;}"+ - "Jump(STATE_CURRENT,"+_strInLoopID+", FALSE, EInternal());return TRUE;"+$4+ - "BOOL "+_strCurrentClass+"::"+_strAfterLoopName+"(const CEntityEvent &__eeInput) {"+ - "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+ - "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strAfterLoopID+"\n"; - } else { - $$ = $1+$2+$3+$4+$6+$7+$8+$9+$10; - } - _strInLoopName[0] = 0; - } - ; - -statement_for - : k_for '(' expression ';' expression ';' expression ')' { - if (strlen(_strInLoopName)>0) { - yyerror("Nested loops are not implemented yet"); - } - } '{' statements '}' { - if ($11.bCrossesStates) { - CreateInternalHandlerFunction(_strInLoopName, _strInLoopID); - CreateInternalHandlerFunction(_strAfterLoopName, _strAfterLoopID); - yyerror("For loops across states are not supported"); - } else { - $$ = $1+$2+$3+$4+$5+$6+$7+$8+$10+$11+$12; - } - _strInLoopName[0] = 0; - } - ; - -statement_wait - : k_wait wait_expression { - if (!_bInProcedure) { - yyerror("Cannot have 'wait' in functions"); - } - CreateInternalHandlerFunction(_strInWaitName, _strInWaitID); - CreateInternalHandlerFunction(_strAfterWaitName, _strAfterWaitID); - _bHasOtherwise = 0; - _bInHandler = 1; - } '{' handlers_list '}' { - if ($5.bCrossesStates) { - yyerror("'wait' statements must not be nested"); - $$ = ""; - } else { - SType stDefault; - if (!_bHasOtherwise) { - stDefault = SType("default: return FALSE; break;"); - } else { - stDefault = SType(""); - } - - $$ = SType(GetLineDirective($1))+$2+";\n"+ - "Jump(STATE_CURRENT, "+_strInWaitID+", FALSE, EBegin());return TRUE;}"+ - "BOOL "+_strCurrentClass+"::"+_strInWaitName+"(const CEntityEvent &__eeInput) {"+ - "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strInWaitID+"\n"+ - "switch(__eeInput.ee_slEvent)"+$4+$5+stDefault+$6+ - "return TRUE;}BOOL "+_strCurrentClass+"::"+_strAfterWaitName+"(const CEntityEvent &__eeInput){"+ - "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+ - "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strAfterWaitID+"\n"; - $$.bCrossesStates = 1; - _bInHandler = 0; - } - } - ; -statement_autowait - : k_autowait wait_expression ';' { - if (!_bInProcedure) { - yyerror("Cannot have 'autowait' in functions"); - } - CreateInternalHandlerFunction(_strInWaitName, _strInWaitID); - CreateInternalHandlerFunction(_strAfterWaitName, _strAfterWaitID); - _bHasOtherwise = 0; - - $$ = SType(GetLineDirective($1))+$2+";\n"+ - "Jump(STATE_CURRENT, "+_strInWaitID+", FALSE, EBegin());return TRUE;}"+ - "BOOL "+_strCurrentClass+"::"+_strInWaitName+"(const CEntityEvent &__eeInput) {"+ - "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strInWaitID+"\n"+ - "switch(__eeInput.ee_slEvent) {"+ - "case EVENTCODE_EBegin: return TRUE;"+ - "case EVENTCODE_ETimer: Jump(STATE_CURRENT,"+_strAfterWaitID+", FALSE, EInternal()); return TRUE;"+ - "default: return FALSE; }}"+ - "BOOL "+_strCurrentClass+"::"+_strAfterWaitName+"(const CEntityEvent &__eeInput){"+ - "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+ - "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strAfterWaitID+"\n"+$3; - $$.bCrossesStates = 1; - } - ; - -statement_waitevent - : k_waitevent wait_expression identifier opt_eventvar ';' { - if (!_bInProcedure) { - yyerror("Cannot have 'autocall' in functions"); - } - CreateInternalHandlerFunction(_strInWaitName, _strInWaitID); - CreateInternalHandlerFunction(_strAfterWaitName, _strAfterWaitID); - _bHasOtherwise = 0; - - $$ = SType(GetLineDirective($1))+$2+";\n"+ - "Jump(STATE_CURRENT, "+_strInWaitID+", FALSE, EBegin());return TRUE;}"+ - "BOOL "+_strCurrentClass+"::"+_strInWaitName+"(const CEntityEvent &__eeInput) {"+ - "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strInWaitID+"\n"+ - "switch(__eeInput.ee_slEvent) {"+ - "case EVENTCODE_EBegin: return TRUE;"+ - "case EVENTCODE_"+$3+": Jump(STATE_CURRENT,"+_strAfterWaitID+", FALSE, __eeInput); return TRUE;"+ - "default: return FALSE; }}"+ - "BOOL "+_strCurrentClass+"::"+_strAfterWaitName+"(const CEntityEvent &__eeInput){"+ - "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strAfterWaitID+"\n"+ - "const "+$3+"&"+$4+"= ("+$3+"&)__eeInput;\n"+$5; - $$.bCrossesStates = 1; - } - ; - - -opt_eventvar - : { - $$ = SType("__e"); - } - | identifier { - $$ = $1; - } - -statement_autocall - : k_autocall jumptarget '(' event_expression ')' identifier opt_eventvar ';' { - if (!_bInProcedure) { - yyerror("Cannot have 'autocall' in functions"); - } - CreateInternalHandlerFunction(_strInWaitName, _strInWaitID); - CreateInternalHandlerFunction(_strAfterWaitName, _strAfterWaitID); - _bHasOtherwise = 0; - - $$ = SType(GetLineDirective($1))+$2+";\n"+ - "Jump(STATE_CURRENT, "+_strInWaitID+", FALSE, EBegin());return TRUE;}"+ - "BOOL "+_strCurrentClass+"::"+_strInWaitName+"(const CEntityEvent &__eeInput) {"+ - "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strInWaitID+"\n"+ - "switch(__eeInput.ee_slEvent) {"+ - "case EVENTCODE_EBegin: Call"+$3+"STATE_CURRENT, "+$2+", "+$4+$5+";return TRUE;"+ - "case EVENTCODE_"+$6+": Jump(STATE_CURRENT,"+_strAfterWaitID+", FALSE, __eeInput); return TRUE;"+ - "default: return FALSE; }}"+ - "BOOL "+_strCurrentClass+"::"+_strAfterWaitName+"(const CEntityEvent &__eeInput){"+ - "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strAfterWaitID+"\n"+ - "const "+$6+"&"+$7+"= ("+$6+"&)__eeInput;\n"+$8; - $$.bCrossesStates = 1; - } - ; - -wait_expression - : '(' ')' { - $$ = SType("SetTimerAt(THINKTIME_NEVER)"); - } - | '(' expression ')' { - $$ = SType("SetTimerAfter")+$1+$2+$3; - } - ; - -statement_jump - : k_jump jumptarget '(' event_expression ')' ';' { - if (!_bInProcedure) { - yyerror("Cannot have 'jump' in functions"); - } - $$ = SType(GetLineDirective($1))+"Jump"+$3+"STATE_CURRENT, "+$2+", "+$4+$5+";return TRUE;"; - } - ; - -statement_call - : k_call jumptarget '(' event_expression')' ';' { - if (!_bInProcedure) { - yyerror("Cannot have 'call' in functions"); - } - if (!_bInHandler) { - yyerror("'call' must be inside a 'wait' statement"); - } - $$ = SType(GetLineDirective($1))+"Call"+$3+"STATE_CURRENT, "+$2+", "+$4+$5+";return TRUE;"; - } - ; - -event_expression - : expression { - $$ = $1; - } - | { - $$ = SType("EVoid()"); - } - ; - -jumptarget - : identifier { - $$ = SType("STATE_")+_strCurrentClass+"_"+$1+", TRUE"; - } - | identifier ':' ':' identifier { - $$ = SType("STATE_")+$1+"_"+$4+", FALSE"; - } - ; - -statement_stop - : k_stop ';' { - $$ = SType(GetLineDirective($1))+"UnsetTimer();Jump(STATE_CURRENT," - +_strAfterWaitID+", FALSE, EInternal());"+"return TRUE"+$2; - } - ; -statement_resume - : k_resume ';' { - $$ = SType(GetLineDirective($1))+"return TRUE"+$2; - } - ; -statement_pass - : k_pass ';' { - $$ = SType(GetLineDirective($1))+"return FALSE"+$2; - } - ; -statement_return - : k_return opt_expression ';' { - if (!_bInProcedure) { - $$ = $1+" "+$2+$3; - } else { - if (strlen($2.strString)==0) { - $2 = SType("EVoid()"); - } - $$ = SType(GetLineDirective($1)) - +"Return(STATE_CURRENT,"+$2+");" - +$1+" TRUE"+$3; - } - } - ; -opt_expression - : {$$ = "";} - | expression - ; - -handler - : k_on '(' event_specification ')' ':' '{' statements '}' opt_semicolon { - char strInputEventType[80]; - char strInputEventName[80]; - sscanf($3.strString, "%s %s", strInputEventType, strInputEventName); - - $$ = SType("case")+$2+"EVENTCODE_"+strInputEventType+$4+$5+$6+ - "const "+strInputEventType+"&"+strInputEventName+"= ("+ - strInputEventType+"&)__eeInput;\n"+$7+$8+"ASSERT(FALSE);break;"; - } - | k_otherwise '(' event_specification ')' ':' '{' statements '}' opt_semicolon { - char strInputEventType[80]; - char strInputEventName[80]; - sscanf($3.strString, "%s %s", strInputEventType, strInputEventName); - - $$ = SType("default")+$5+$6+$7+$8+"ASSERT(FALSE);break;"; - _bHasOtherwise = 1; - } - ; -handlers_list - : { $$ = "";} - | handlers_list handler { $$ = $1+$2; } - ; - -%% +%{ +// rcg10042001 Changed to specify Ecc directory... +#include "Ecc/StdH.h" +#include "Ecc/Main.h" + +// turn off over-helpful bit of bison... --ryan. +#ifdef __GNUC__ +#define __attribute__(x) +#endif + +#define YYINITDEPTH 1000 + +static const char *_strCurrentClass; +static int _iCurrentClassID; +static const char *_strCurrentBase; +static const char *_strCurrentDescription; +static const char *_strCurrentThumbnail; +static const char *_strCurrentEnum; +static int _bClassIsExported = 0; + +static const char *_strCurrentPropertyID; +static const char *_strCurrentPropertyIdentifier; +static const char *_strCurrentPropertyPropertyType; +static const char *_strCurrentPropertyEnumType; +static const char *_strCurrentPropertyDataType; +static const char *_strCurrentPropertyName; +static const char *_strCurrentPropertyShortcut; +static const char *_strCurrentPropertyColor; +static const char *_strCurrentPropertyFlags; +static const char *_strCurrentPropertyDefaultCode; + +static const char *_strCurrentComponentIdentifier; +static const char *_strCurrentComponentType; +static const char *_strCurrentComponentID; +static const char *_strCurrentComponentFileName; + +static int _ctInProcedureHandler = 0; +static char _strLastProcedureName[256]; + +static char _strInWaitName[256]; +static char _strAfterWaitName[256]; +static char _strInWaitID[256]; +static char _strAfterWaitID[256]; + +static char _strInLoopName[256]; +static char _strAfterLoopName[256]; +static char _strInLoopID[256]; +static char _strAfterLoopID[256]; +static char _strCurrentStateID[256]; + +static int _bInProcedure; // set if currently compiling a procedure +static int _bInHandler; +static int _bHasOtherwise; // set if current 'wait' block has an 'otherwise' statement + +static const char *_strCurrentEvent; +static int _bFeature_AbstractBaseClass; +static int _bFeature_ImplementsOnInitClass; +static int _bFeature_ImplementsOnEndClass; +static int _bFeature_ImplementsOnPrecache; +static int _bFeature_ImplementsOnWorldInit; +static int _bFeature_ImplementsOnWorldEnd; +static int _bFeature_ImplementsOnWorldTick; +static int _bFeature_ImplementsOnWorldRender; +static int _bFeature_CanBePredictable; + +static int _iNextFreeID; +inline int CreateID(void) { + return _iNextFreeID++; +} + +static int _ctBraces = 0; +void OpenBrace(void) { + _ctBraces++; +} +void CloseBrace(void) { + _ctBraces--; +} +SType Braces(int iBraces) { + static char strBraces[50]; + memset(strBraces, '}', sizeof(strBraces)); + strBraces[iBraces] = 0; + return SType(strBraces); +} +char *RemoveLineDirective(char *str) +{ + if (str[0]=='\n' && str[1]=='#') { + return strchr(str+2, '\n')+1; + } else { + return str; + } +} +const char *GetLineDirective(SType &st) +{ + char *str = st.strString; + if (str[0]=='\n' && str[1]=='#' && str[2]=='l') { + char *strResult = strdup(str); + strchr(strResult+3,'\n')[1] = 0; + return strResult; + } else { + return ""; + } +} +void AddHandlerFunction(char *strProcedureName, int iStateID) +{ + fprintf(_fDeclaration, " BOOL %s(const CEntityEvent &__eeInput);\n", strProcedureName); + fprintf(_fTables, " {0x%08x, -1, CEntity::pEventHandler(&%s::%s), " + "DEBUGSTRING(\"%s::%s\")},\n", + iStateID, _strCurrentClass, strProcedureName, _strCurrentClass, strProcedureName); +} + + +void AddHandlerFunction(char *strProcedureName, char *strStateID, char *strBaseStateID) +{ + fprintf(_fDeclaration, " BOOL %s(const CEntityEvent &__eeInput);\n", strProcedureName); + fprintf(_fTables, " {%s, %s, CEntity::pEventHandler(&%s::%s)," + "DEBUGSTRING(\"%s::%s\")},\n", + strStateID, strBaseStateID, _strCurrentClass, strProcedureName, + _strCurrentClass, RemoveLineDirective(strProcedureName)); + strcpy(_strLastProcedureName, RemoveLineDirective(strProcedureName)); + _ctInProcedureHandler = 0; +} + +void CreateInternalHandlerFunction(char *strFunctionName, char *strID) +{ + int iID = CreateID(); + _ctInProcedureHandler++; + sprintf(strID, "0x%08x", iID); + sprintf(strFunctionName, "H0x%08x_%s_%02d", iID, _strLastProcedureName, _ctInProcedureHandler); + AddHandlerFunction(strFunctionName, iID); +} + +void DeclareFeatureProperties(void) +{ + if (_bFeature_CanBePredictable) { + fprintf(_fTables, " CEntityProperty(CEntityProperty::EPT_ENTITYPTR, NULL, (0x%08x<<8)+%s, _offsetof(%s, %s), %s, %s, %s, %s),\n", + _iCurrentClassID, + "255", + _strCurrentClass, + "m_penPrediction", + "\"\"", + "0", + "0", + "0"); + fprintf(_fDeclaration, " %s %s;\n", + "CEntityPointer", + "m_penPrediction" + ); + fprintf(_fImplementation, " m_penPrediction = NULL;\n"); + } +} + +#define YYERROR_VERBOSE 1 + +%} + +/* BISON Declarations */ + +/* different type of constants */ +%token c_char +%token c_int +%token c_float +%token c_bool +%token c_string + +/* the standard cpp identifier */ +%token identifier + +/* specially bracketed cpp blocks */ +%token cppblock + +/* standard cpp-keywords */ +%token k_while +%token k_for +%token k_if +%token k_else +%token k_enum +%token k_switch +%token k_case +%token k_class +%token k_do +%token k_void +%token k_const +%token k_inline +%token k_static +%token k_virtual +%token k_return +%token k_autowait +%token k_autocall +%token k_waitevent + +/* aditional keywords */ +%token k_event +%token k_name +%token k_thumbnail +%token k_features +%token k_uses +%token k_export + +%token k_texture +%token k_sound +%token k_model + +%token k_properties +%token k_components +%token k_functions +%token k_procedures + +%token k_wait +%token k_on +%token k_otherwise + +%token k_call +%token k_jump +%token k_stop +%token k_resume +%token k_pass + +/* special data types */ +%token k_CTString +%token k_CTStringTrans +%token k_CTFileName +%token k_CTFileNameNoDep +%token k_BOOL +%token k_COLOR +%token k_FLOAT +%token k_INDEX +%token k_RANGE +%token k_CEntityPointer +%token k_CModelObject +%token k_CModelInstance +%token k_CAnimObject +%token k_CSoundObject +%token k_CPlacement3D +%token k_FLOATaabbox3D +%token k_FLOATmatrix3D +%token k_FLOATquat3D +%token k_ANGLE +%token k_FLOAT3D +%token k_ANGLE3D +%token k_FLOATplane3D +%token k_ANIMATION +%token k_ILLUMINATIONTYPE +%token k_FLAGS + +%start program + +%% + +/*///////////////////////////////////////////////////////// + * Global structure of the source file. + */ +program + : /* empty file */ {} + | c_int { + int iID = atoi($1.strString); + if(iID>32767) { + yyerror("Maximum allowed id for entity source file is 32767"); + } + _iCurrentClassID = iID; + _iNextFreeID = iID<<16; + fprintf(_fDeclaration, "#ifndef _%s_INCLUDED\n", _strFileNameBaseIdentifier); + fprintf(_fDeclaration, "#define _%s_INCLUDED 1\n", _strFileNameBaseIdentifier); + + } opt_global_cppblock { + + //fprintf(_fImplementation, "\n#undef DECL_DLL\n#define DECL_DLL _declspec(dllimport)\n"); + } uses_list { + //fprintf(_fImplementation, "\n#undef DECL_DLL\n#define DECL_DLL _declspec(dllexport)\n"); + + fprintf(_fImplementation, "#include <%s.h>\n", _strFileNameBase); + fprintf(_fImplementation, "#include <%s_tables.h>\n", _strFileNameBase); + } enum_and_event_declarations_list { + } opt_global_cppblock { + } opt_class_declaration { + fprintf(_fDeclaration, "#endif // _%s_INCLUDED\n", _strFileNameBaseIdentifier); + } + ; + + +/* + * Prolog cpp code. + */ +opt_global_cppblock + : /* null */ + | cppblock { fprintf(_fImplementation, "%s\n", $1.strString); } + ; + +uses_list + : /* null */ + | uses_list uses_statement + ; +uses_statement + : k_uses c_string ';' { + char *strUsedFileName = strdup($2.strString); + strUsedFileName[strlen(strUsedFileName)-1] = 0; + fprintf(_fDeclaration, "#include <%s.h>\n", strUsedFileName+1); + } + ; + + +enum_and_event_declarations_list + : /* null */ + | enum_and_event_declarations_list enum_declaration + | enum_and_event_declarations_list event_declaration + ; +/*///////////////////////////////////////////////////////// + * Enum types declarations + */ +enum_declaration + : k_enum identifier { + _strCurrentEnum = $2.strString; + fprintf(_fTables, "EP_ENUMBEG(%s)\n", _strCurrentEnum ); + fprintf(_fDeclaration, "extern DECL_DLL CEntityPropertyEnumType %s_enum;\n", _strCurrentEnum ); + fprintf(_fDeclaration, "enum %s {\n", _strCurrentEnum ); + } '{' enum_values_list opt_comma '}' ';' { + fprintf(_fTables, "EP_ENUMEND(%s);\n\n", _strCurrentEnum); + fprintf(_fDeclaration, "};\n"); + fprintf(_fDeclaration, "DECL_DLL inline void ClearToDefault(%s &e) { e = (%s)0; } ;\n", _strCurrentEnum, _strCurrentEnum); + } + ; +opt_comma : /*null*/ | ','; +enum_values_list + : enum_value + | enum_values_list ',' enum_value + ; + +enum_value + : c_int identifier c_string { + fprintf(_fTables, " EP_ENUMVALUE(%s, %s),\n", $2.strString, $3.strString); + fprintf(_fDeclaration, " %s = %s,\n", $2.strString, $1.strString); + } + ; + +/*///////////////////////////////////////////////////////// + * Event declarations + */ +event_declaration + : k_event identifier { + _strCurrentEvent = $2.strString; + int iID = CreateID(); + fprintf(_fDeclaration, "#define EVENTCODE_%s 0x%08x\n", _strCurrentEvent, iID); + fprintf(_fDeclaration, "class DECL_DLL %s : public CEntityEvent {\npublic:\n", + _strCurrentEvent); + fprintf(_fDeclaration, "%s();\n", _strCurrentEvent ); + fprintf(_fDeclaration, "CEntityEvent *MakeCopy(void);\n"); + fprintf(_fImplementation, + "CEntityEvent *%s::MakeCopy(void) { " + "CEntityEvent *peeCopy = new %s(*this); " + "return peeCopy;}\n", + _strCurrentEvent, _strCurrentEvent); + fprintf(_fImplementation, "%s::%s() : CEntityEvent(EVENTCODE_%s) {;\n", + _strCurrentEvent, _strCurrentEvent, _strCurrentEvent); + } '{' event_members_list opt_comma '}' ';' { + fprintf(_fImplementation, "};\n"); + fprintf(_fDeclaration, "};\n"); + fprintf(_fDeclaration, "DECL_DLL inline void ClearToDefault(%s &e) { e = %s(); } ;\n", _strCurrentEvent, _strCurrentEvent); + } + ; + +event_members_list + : /* null */ + | non_empty_event_members_list + ; + +non_empty_event_members_list + : event_member + | event_members_list ',' event_member + ; + +event_member + : any_type identifier { + fprintf(_fDeclaration, "%s %s;\n", $1.strString, $2.strString); + fprintf(_fImplementation, " ClearToDefault(%s);\n", $2.strString); + } + ; + +/*///////////////////////////////////////////////////////// + * The class declaration structure. + */ +opt_class_declaration + : /* null */ + | class_declaration + ; + +class_declaration + : /* null */ + | class_optexport identifier ':' identifier '{' + k_name c_string ';' + k_thumbnail c_string ';' { + _strCurrentClass = $2.strString; + _strCurrentBase = $4.strString; + _strCurrentDescription = $7.strString; + _strCurrentThumbnail = $10.strString; + + fprintf(_fTables, "#define ENTITYCLASS %s\n\n", _strCurrentClass); + fprintf(_fDeclaration, "extern \"C\" DECL_DLL CDLLEntityClass %s_DLLClass;\n", + _strCurrentClass); + fprintf(_fDeclaration, "%s %s : public %s {\npublic:\n", + $1.strString, _strCurrentClass, _strCurrentBase); + + } opt_features { + fprintf(_fDeclaration, " %s virtual void SetDefaultProperties(void);\n", _bClassIsExported?"":"DECL_DLL"); + fprintf(_fImplementation, "void %s::SetDefaultProperties(void) {\n", _strCurrentClass); + fprintf(_fTables, "CEntityProperty %s_properties[] = {\n", _strCurrentClass); + + } k_properties ':' property_declaration_list { + fprintf(_fImplementation, " %s::SetDefaultProperties();\n}\n", _strCurrentBase); + + fprintf(_fTables, "CEntityComponent %s_components[] = {\n", _strCurrentClass); + } opt_internal_properties { + } k_components ':' component_declaration_list { + _bTrackLineInformation = 1; + fprintf(_fTables, "CEventHandlerEntry %s_handlers[] = {\n", _strCurrentClass); + + _bInProcedure = 0; + _bInHandler = 0; + } k_functions ':' function_list { + + _bInProcedure = 1; + } k_procedures ':' procedure_list { + } '}' ';' { + fprintf(_fTables, "};\n#define %s_handlersct ARRAYCOUNT(%s_handlers)\n", + _strCurrentClass, _strCurrentClass); + fprintf(_fTables, "\n"); + + if (_bFeature_AbstractBaseClass) { + fprintf(_fTables, "CEntity *%s_New(void) { return NULL; };\n", + _strCurrentClass); + } else { + fprintf(_fTables, "CEntity *%s_New(void) { return new %s; };\n", + _strCurrentClass, _strCurrentClass); + } + + if (!_bFeature_ImplementsOnInitClass) { + fprintf(_fTables, "void %s_OnInitClass(void) {};\n", _strCurrentClass); + } else { + fprintf(_fTables, "void %s_OnInitClass(void);\n", _strCurrentClass); + } + + if (!_bFeature_ImplementsOnEndClass) { + fprintf(_fTables, "void %s_OnEndClass(void) {};\n", _strCurrentClass); + } else { + fprintf(_fTables, "void %s_OnEndClass(void);\n", _strCurrentClass); + } + + if (!_bFeature_ImplementsOnPrecache) { + fprintf(_fTables, "void %s_OnPrecache(CDLLEntityClass *pdec, INDEX iUser) {};\n", _strCurrentClass); + } else { + fprintf(_fTables, "void %s_OnPrecache(CDLLEntityClass *pdec, INDEX iUser);\n", _strCurrentClass); + } + + if (!_bFeature_ImplementsOnWorldEnd) { + fprintf(_fTables, "void %s_OnWorldEnd(CWorld *pwo) {};\n", _strCurrentClass); + } else { + fprintf(_fTables, "void %s_OnWorldEnd(CWorld *pwo);\n", _strCurrentClass); + } + + if (!_bFeature_ImplementsOnWorldInit) { + fprintf(_fTables, "void %s_OnWorldInit(CWorld *pwo) {};\n", _strCurrentClass); + } else { + fprintf(_fTables, "void %s_OnWorldInit(CWorld *pwo);\n", _strCurrentClass); + } + + if (!_bFeature_ImplementsOnWorldTick) { + fprintf(_fTables, "void %s_OnWorldTick(CWorld *pwo) {};\n", _strCurrentClass); + } else { + fprintf(_fTables, "void %s_OnWorldTick(CWorld *pwo);\n", _strCurrentClass); + } + + if (!_bFeature_ImplementsOnWorldRender) { + fprintf(_fTables, "void %s_OnWorldRender(CWorld *pwo) {};\n", _strCurrentClass); + } else { + fprintf(_fTables, "void %s_OnWorldRender(CWorld *pwo);\n", _strCurrentClass); + } + + fprintf(_fTables, "ENTITY_CLASSDEFINITION(%s, %s, %s, %s, 0x%08x);\n", + _strCurrentClass, _strCurrentBase, + _strCurrentDescription, _strCurrentThumbnail, _iCurrentClassID); + fprintf(_fTables, "DECLARE_CTFILENAME(_fnm%s_tbn, %s);\n", _strCurrentClass, _strCurrentThumbnail); + + fprintf(_fDeclaration, "};\n"); + } + ; + +class_optexport + : k_class { $$ = $1; _bClassIsExported = 0; } + | k_class k_export { $$ = $1+" DECL_DLL "; _bClassIsExported = 1; } + ; + +opt_features + : /*null */ + | k_features { + _bFeature_ImplementsOnWorldInit = 0; + _bFeature_ImplementsOnWorldEnd = 0; + _bFeature_ImplementsOnWorldTick = 0; + _bFeature_ImplementsOnWorldRender = 0; + _bFeature_ImplementsOnInitClass = 0; + _bFeature_ImplementsOnEndClass = 0; + _bFeature_ImplementsOnPrecache = 0; + _bFeature_AbstractBaseClass = 0; + _bFeature_CanBePredictable = 0; + }features_list ';' + ; +features_list + : feature + | features_list ',' feature + ; +feature + : c_string { + if (strcmp($1.strString, "\"AbstractBaseClass\"")==0) { + _bFeature_AbstractBaseClass = 1; + } else if (strcmp($1.strString, "\"IsTargetable\"")==0) { + fprintf(_fDeclaration, "virtual BOOL IsTargetable(void) const { return TRUE; };\n"); + } else if (strcmp($1.strString, "\"IsImportant\"")==0) { + fprintf(_fDeclaration, "virtual BOOL IsImportant(void) const { return TRUE; };\n"); + } else if (strcmp($1.strString, "\"HasName\"")==0) { + fprintf(_fDeclaration, + "virtual const CTString &GetName(void) const { return m_strName; };\n"); + } else if (strcmp($1.strString, "\"CanBePredictable\"")==0) { + fprintf(_fDeclaration, + "virtual CEntity *GetPredictionPair(void) { return m_penPrediction; };\n"); + fprintf(_fDeclaration, + "virtual void SetPredictionPair(CEntity *penPair) { m_penPrediction = penPair; };\n"); + _bFeature_CanBePredictable = 1; + } else if (strcmp($1.strString, "\"HasDescription\"")==0) { + fprintf(_fDeclaration, + "virtual const CTString &GetDescription(void) const { return m_strDescription; };\n"); + } else if (strcmp($1.strString, "\"HasTarget\"")==0) { + fprintf(_fDeclaration, + "virtual CEntity *GetTarget(void) const { return m_penTarget; };\n"); + } else if (strcmp($1.strString, "\"ImplementsOnInitClass\"")==0) { + _bFeature_ImplementsOnInitClass = 1; + } else if (strcmp($1.strString, "\"ImplementsOnEndClass\"")==0) { + _bFeature_ImplementsOnEndClass = 1; + } else if (strcmp($1.strString, "\"ImplementsOnPrecache\"")==0) { + _bFeature_ImplementsOnPrecache = 1; + } else if (strcmp($1.strString, "\"ImplementsOnWorldInit\"")==0) { + _bFeature_ImplementsOnWorldInit = 1; + } else if (strcmp($1.strString, "\"ImplementsOnWorldEnd\"")==0) { + _bFeature_ImplementsOnWorldEnd = 1; + } else if (strcmp($1.strString, "\"ImplementsOnWorldTick\"")==0) { + _bFeature_ImplementsOnWorldTick = 1; + } else if (strcmp($1.strString, "\"ImplementsOnWorldRender\"")==0) { + _bFeature_ImplementsOnWorldRender = 1; + } else { + yyerror((SType("Unknown feature: ")+$1).strString); + } + } + ; + +opt_internal_properties + : /* null */ + | '{' internal_property_list '}' + ; +internal_property_list + : /* null */ + | internal_property_list internal_property + ; +internal_property + : any_type identifier ';' { + fprintf(_fDeclaration, "%s %s;\n", $1.strString, $2.strString); + } + ; + +/*///////////////////////////////////////////////////////// + * Property declarations + */ + +property_declaration_list + : empty_property_declaration_list { + DeclareFeatureProperties(); // this won't work, but at least it will generate an error!!!! + fprintf(_fTables, " CEntityProperty()\n};\n"); + fprintf(_fTables, "#define %s_propertiesct 0\n", _strCurrentClass); + fprintf(_fTables, "\n"); + fprintf(_fTables, "\n"); + } + | nonempty_property_declaration_list opt_comma { + DeclareFeatureProperties(); + fprintf(_fTables, "};\n"); + fprintf(_fTables, "#define %s_propertiesct ARRAYCOUNT(%s_properties)\n", + _strCurrentClass, _strCurrentClass); + fprintf(_fTables, "\n"); + } + ; +nonempty_property_declaration_list + : property_declaration + | nonempty_property_declaration_list ',' property_declaration + ; +empty_property_declaration_list + : /* null */ + ; + +property_declaration + : property_id property_type property_identifier property_wed_name_opt property_default_opt property_flags_opt { + fprintf(_fTables, " CEntityProperty(%s, %s, (0x%08x<<8)+%s, _offsetof(%s, %s), %s, %s, %s, %s),\n", + _strCurrentPropertyPropertyType, + _strCurrentPropertyEnumType, + _iCurrentClassID, + _strCurrentPropertyID, + _strCurrentClass, + _strCurrentPropertyIdentifier, + _strCurrentPropertyName, + _strCurrentPropertyShortcut, + _strCurrentPropertyColor, + _strCurrentPropertyFlags); + fprintf(_fDeclaration, " %s %s;\n", + _strCurrentPropertyDataType, + _strCurrentPropertyIdentifier + ); + + if (strlen(_strCurrentPropertyDefaultCode)>0) { + fprintf(_fImplementation, " %s\n", _strCurrentPropertyDefaultCode); + } + } + ; + +property_id : c_int { _strCurrentPropertyID = $1.strString; }; +property_identifier : identifier { _strCurrentPropertyIdentifier = $1.strString; }; + +property_type + : k_enum identifier { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ENUM"; + _strCurrentPropertyEnumType = (SType("&")+$2+"_enum").strString; + _strCurrentPropertyDataType = (SType("enum ")+$2.strString).strString; + } + | k_FLAGS identifier { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLAGS"; + _strCurrentPropertyEnumType = (SType("&")+$2+"_enum").strString; + _strCurrentPropertyDataType = "ULONG"; + } + | k_CTString { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_STRING"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "CTString"; + } + | k_CTStringTrans { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_STRINGTRANS"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "CTStringTrans"; + } + | k_CTFileName { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FILENAME"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "CTFileName"; + } + | k_CTFileNameNoDep { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FILENAMENODEP"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "CTFileNameNoDep"; + } + | k_BOOL { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_BOOL"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "BOOL"; + } + | k_COLOR { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_COLOR"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "COLOR"; + } + | k_FLOAT { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLOAT"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "FLOAT"; + } + | k_INDEX { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_INDEX"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "INDEX"; + } + | k_RANGE { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_RANGE"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "RANGE"; + } + | k_CEntityPointer { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ENTITYPTR"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "CEntityPointer"; + } + | k_CModelObject { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_MODELOBJECT"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "CModelObject"; + } + | k_CModelInstance { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_MODELINSTANCE"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "CModelInstance"; + } + | k_CAnimObject { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ANIMOBJECT"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "CAnimObject"; + } + | k_CSoundObject { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_SOUNDOBJECT"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "CSoundObject"; + } + | k_CPlacement3D { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_PLACEMENT3D"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "CPlacement3D"; + } + | k_FLOATaabbox3D { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLOATAABBOX3D"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "FLOATaabbox3D"; + } + | k_FLOATmatrix3D { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLOATMATRIX3D"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "FLOATmatrix3D"; + } + | k_FLOATquat3D { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLOATQUAT3D"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "FLOATquat3D"; + } + | k_ANGLE { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ANGLE"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "ANGLE"; + } + | k_ANGLE3D { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ANGLE3D"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "ANGLE3D"; + } + | k_FLOAT3D { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLOAT3D"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "FLOAT3D"; + } + | k_FLOATplane3D { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_FLOATplane3D"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "FLOATplane3D"; + } + | k_ILLUMINATIONTYPE { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ILLUMINATIONTYPE"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "ILLUMINATIONTYPE"; + } + | k_ANIMATION { + _strCurrentPropertyPropertyType = "CEntityProperty::EPT_ANIMATION"; + _strCurrentPropertyEnumType = "NULL"; + _strCurrentPropertyDataType = "ANIMATION"; + } + ; + +property_wed_name_opt + : /* null */ { + _strCurrentPropertyName = "\"\""; + _strCurrentPropertyShortcut = "0"; + _strCurrentPropertyColor = "0"; // this won't be rendered anyway + } + | c_string property_shortcut_opt property_color_opt { + _strCurrentPropertyName = $1.strString; + } + ; +property_shortcut_opt + : /* null */ { + _strCurrentPropertyShortcut = "0"; + } + | c_char { + _strCurrentPropertyShortcut = $1.strString; + } + +property_color_opt + : /* null */ { + _strCurrentPropertyColor = "0x7F0000FFUL"; // dark red + } + | k_COLOR '(' expression ')' { + _strCurrentPropertyColor = $3.strString; + } +property_flags_opt + : /* null */ { + _strCurrentPropertyFlags = "0"; // dark red + } + | k_features '(' expression ')' { + _strCurrentPropertyFlags = $3.strString; + } + +property_default_opt + : /* null */ { + if (strcmp(_strCurrentPropertyDataType,"CEntityPointer")==0) { + _strCurrentPropertyDefaultCode = (SType(_strCurrentPropertyIdentifier)+" = NULL;").strString; + } else if (strcmp(_strCurrentPropertyDataType,"CModelObject")==0) { + _strCurrentPropertyDefaultCode = + (SType(_strCurrentPropertyIdentifier)+".SetData(NULL);\n"+ + _strCurrentPropertyIdentifier+".mo_toTexture.SetData(NULL);").strString; + } else if (strcmp(_strCurrentPropertyDataType,"CModelInstance")==0) { + _strCurrentPropertyDefaultCode = + (SType(_strCurrentPropertyIdentifier)+".Clear();\n").strString; + } else if (strcmp(_strCurrentPropertyDataType,"CAnimObject")==0) { + _strCurrentPropertyDefaultCode = + (SType(_strCurrentPropertyIdentifier)+".SetData(NULL);\n").strString; + } else if (strcmp(_strCurrentPropertyDataType,"CSoundObject")==0) { + _strCurrentPropertyDefaultCode = + (SType(_strCurrentPropertyIdentifier)+".SetOwner(this);\n"+ + _strCurrentPropertyIdentifier+".Stop_internal();").strString; + } else { + yyerror("this kind of property must have default value"); + _strCurrentPropertyDefaultCode = ""; + } + } + | '=' property_default_expression { + if (strcmp(_strCurrentPropertyDataType,"CEntityPointer")==0) { + yyerror("CEntityPointer type properties always default to NULL"); + } else { + _strCurrentPropertyDefaultCode = (SType(_strCurrentPropertyIdentifier)+" = "+$2.strString+";").strString; + } + } + ; +property_default_expression + : c_int|c_float|c_bool|c_char|c_string + | identifier {$$ = $1 + " ";} + | identifier '(' expression ')' {$$ = $1+$2+$3+$4;} + | type_keyword '(' expression ')' {$$ = $1+$2+$3+$4;} + | '-' property_default_expression {$$ = $1+$2;} + | '(' expression ')' {$$ = $1+$2+$3;} + ; + +/*///////////////////////////////////////////////////////// + * Component declarations + */ +component_declaration_list + : empty_component_declaration_list { + fprintf(_fTables, " CEntityComponent()\n};\n"); + fprintf(_fTables, "#define %s_componentsct 0\n", _strCurrentClass); + fprintf(_fTables, "\n"); + fprintf(_fTables, "\n"); + } + | nonempty_component_declaration_list opt_comma { + fprintf(_fTables, "};\n"); + fprintf(_fTables, "#define %s_componentsct ARRAYCOUNT(%s_components)\n", + _strCurrentClass, _strCurrentClass); + fprintf(_fTables, "\n"); + } + ; +nonempty_component_declaration_list + : component_declaration + | nonempty_component_declaration_list ',' component_declaration + ; +empty_component_declaration_list + : /* null */ + ; + +component_declaration + : component_id component_type component_identifier component_filename { + fprintf(_fTables, "#define %s ((0x%08x<<8)+%s)\n", + _strCurrentComponentIdentifier, + _iCurrentClassID, + _strCurrentComponentID); + fprintf(_fTables, " CEntityComponent(%s, %s, \"%s%s\" %s),\n", + _strCurrentComponentType, + _strCurrentComponentIdentifier, + "EF","NM", + _strCurrentComponentFileName); + } + ; + +component_id : c_int { _strCurrentComponentID = $1.strString; }; +component_identifier : identifier { _strCurrentComponentIdentifier = $1.strString; }; +component_filename : c_string { _strCurrentComponentFileName = $1.strString; }; + +component_type + : k_model { _strCurrentComponentType = "ECT_MODEL"; } + | k_texture { _strCurrentComponentType = "ECT_TEXTURE"; } + | k_sound { _strCurrentComponentType = "ECT_SOUND"; } + | k_class { _strCurrentComponentType = "ECT_CLASS"; } + ; + +/*///////////////////////////////////////////////////////// + * Functions + */ +function_list + : { $$ = "";} + | function_list function_implementation {$$ = $1+$2;} + ; + +function_implementation + : opt_export opt_virtual return_type opt_tilde identifier '(' parameters_list ')' opt_const + '{' statements '}' opt_semicolon { + const char *strReturnType = $3.strString; + const char *strFunctionHeader = ($4+$5+$6+$7+$8+$9).strString; + const char *strFunctionBody = ($10+$11+$12).strString; + if (strcmp($5.strString, _strCurrentClass)==0) { + if (strcmp(strReturnType+strlen(strReturnType)-4, "void")==0 ) { + strReturnType = ""; + } else { + yyerror("use 'void' as return type for constructors"); + } + } + fprintf(_fDeclaration, " %s %s %s %s;\n", + $1.strString, $2.strString, strReturnType, strFunctionHeader); + fprintf(_fImplementation, " %s %s::%s %s\n", + strReturnType, _strCurrentClass, strFunctionHeader, strFunctionBody); + } + ; +opt_tilde + : { $$ = "";} + | '~' { $$ = " ~ "; } + ; + +opt_export + : { $$ = "";} + | k_export { + if (_bClassIsExported) { + $$ = ""; + } else { + $$ = " DECL_DLL "; + } + } + ; + +opt_const + : { $$ = "";} + | k_const { $$ = $1; } + ; +opt_virtual + : { $$ = "";} + | k_virtual { $$ = $1; } + ; +opt_semicolon + : /* null */ + | ';' + ; +parameters_list + : { $$ = "";} + | k_void + | non_void_parameters_list + ; +non_void_parameters_list + : parameter_declaration + | non_void_parameters_list ',' parameter_declaration {$$ = $1+$2+$3;} + ; +parameter_declaration + : any_type identifier { $$=$1+" "+$2; } + ; + +return_type + : any_type + | k_void + ; + +any_type + : type_keyword + | identifier + | k_enum identifier { $$=$1+" "+$2; } + | any_type '*' { $$=$1+" "+$2; } + | any_type '&' { $$=$1+" "+$2; } + | k_void '*' { $$=$1+" "+$2; } + | k_const any_type { $$=$1+" "+$2; } + | k_inline any_type { $$=$1+" "+$2; } + | k_static any_type { $$=$1+" "+$2; } + | k_class any_type { $$=$1+" "+$2; } + | identifier '<' any_type '>' { $$=$1+" "+$2+" "+$3+" "+$4; } + ; + + +/*///////////////////////////////////////////////////////// + * Procedures + */ +procedure_list + : { $$ = "";} + | procedure_list procedure_implementation {$$ = $1+$2;} + ; + +opt_override + : { $$ = "-1"; } + | ':' identifier ':' ':' identifier { + $$ = SType("STATE_")+$2+"_"+$5; + } + ; + +procedure_implementation + : identifier '(' event_specification ')' opt_override { + char *strProcedureName = $1.strString; + char strInputEventType[80]; + char strInputEventName[80]; + sscanf($3.strString, "%s %s", strInputEventType, strInputEventName); + + char strStateID[256]; + const char *strBaseStateID = "-1"; + if(strcmp(RemoveLineDirective(strProcedureName), "Main")==0){ + strcpy(strStateID, "1"); + if(strncmp(strInputEventType, "EVoid", 4)!=0 && _strCurrentThumbnail[2]!=0) { + yyerror("procedure 'Main' can take input parameters only in classes without thumbnails"); + } + } else { + sprintf(strStateID, "0x%08x", CreateID()); + } + + sprintf(_strCurrentStateID, "STATE_%s_%s", + _strCurrentClass, RemoveLineDirective(strProcedureName)); + fprintf(_fDeclaration, "#define %s %s\n", _strCurrentStateID, strStateID); + AddHandlerFunction(strProcedureName, strStateID, $5.strString); + fprintf(_fImplementation, + "BOOL %s::%s(const CEntityEvent &__eeInput) {\n#undef STATE_CURRENT\n#define STATE_CURRENT %s\n", + _strCurrentClass, strProcedureName, _strCurrentStateID); + fprintf(_fImplementation, + " ASSERTMSG(__eeInput.ee_slEvent==EVENTCODE_%s, \"%s::%s expects '%s' as input!\");", + strInputEventType, _strCurrentClass, RemoveLineDirective(strProcedureName), + strInputEventType); + fprintf(_fImplementation, " const %s &%s = (const %s &)__eeInput;", + strInputEventType, strInputEventName, strInputEventType); + + } '{' statements '}' opt_semicolon { + char *strFunctionBody = $8.strString; + fprintf(_fImplementation, "%s ASSERT(FALSE); return TRUE;};", strFunctionBody); + } + ; + +event_specification + : { + $$="EVoid e"; + } + | identifier { + $$=$1+" e"; + } + | identifier identifier { + $$=$1+" "+$2; + } + ; + +expression + : c_int|c_float|c_bool|c_char|c_string + | identifier {$$ = $1 + " ";} + | type_keyword + | '='|'+'|'-'|'<'|'>'|'!'|'|'|'&'|'*'|'/'|'%'|'^'|'['|']'|':'|','|'.'|'?'|'~' + | '(' ')' {$$=$1+$2;} + | '+' '+' {$$=$1+$2;} + | '-' '-' {$$=$1+$2;} + | '-' '>' {$$=$1+$2;} + | ':' ':' {$$=$1+$2;} + | '&' '&' {$$=$1+$2;} + | '|' '|' {$$=$1+$2;} + | '^' '^' {$$=$1+$2;} + | '>' '>' {$$=$1+$2;} + | '<' '<' {$$=$1+$2;} + | '=' '=' {$$=$1+$2;} + | '!' '=' {$$=$1+$2;} + | '>' '=' {$$=$1+$2;} + | '<' '=' {$$=$1+$2;} + | '&' '=' {$$=$1+$2;} + | '|' '=' {$$=$1+$2;} + | '^' '=' {$$=$1+$2;} + | '+' '=' {$$=$1+$2;} + | '-' '=' {$$=$1+$2;} + | '/' '=' {$$=$1+$2;} + | '%' '=' {$$=$1+$2;} + | '*' '=' {$$=$1+$2;} + | '>' '>' '=' {$$=$1+$2+$3;} + | '<' '<' '=' {$$=$1+$2+$3;} + | '(' expression ')' {$$ = $1+$2+$3;} + | expression expression {$$ = $1+" "+$2;} + ; +type_keyword + : k_CTString|k_CTStringTrans|k_CTFileName|k_CTFileNameNoDep + | k_BOOL|k_COLOR|k_FLOAT|k_INDEX|k_RANGE + | k_CEntityPointer|k_CModelObject|k_CModelInstance|k_CAnimObject|k_CSoundObject + | k_CPlacement3D | k_FLOATaabbox3D|k_FLOATmatrix3D| k_FLOATquat3D|k_ANGLE|k_ANIMATION|k_ILLUMINATIONTYPE + | k_ANGLE3D|k_FLOAT3D|k_FLOATplane3D + | k_const + | k_static + ; +case_constant_expression + : c_int|c_float|c_bool|c_char|c_string + | identifier {$$ = $1 + " ";} + ; + + +/* Simple statements: + */ +statements + : { $$ = "";} + | statements statement { $$ = $1+$2; } + ; +statement + : expression ';' {$$=$1+$2;} + | k_switch '(' expression ')' '{' statements '}' {$$=$1+$2+$3+$4+$5+$6+$7;} + | k_case case_constant_expression ':' {$$=$1+" "+$2+$3+" ";} + | '{' statements '}' {$$=$1+$2+$3;} + | expression '{' statements '}' {$$=$1+$2+$3+$4;} + | statement_while + | statement_dowhile + | statement_for + | statement_if + | statement_if_else + | statement_wait + | statement_autowait + | statement_waitevent + | statement_call + | statement_autocall + | statement_stop + | statement_resume + | statement_pass + | statement_return + | statement_jump + | ';' + ; + + +statement_if + : k_if '(' expression ')' '{' statements '}' { + if ($6.bCrossesStates) { + char strAfterIfName[80], strAfterIfID[11]; + CreateInternalHandlerFunction(strAfterIfName, strAfterIfID); + $$ = $1+"(!"+$2+$3+$4+"){ Jump(STATE_CURRENT,"+strAfterIfID+", FALSE, EInternal());return TRUE;}"+$6+ + "Jump(STATE_CURRENT,"+strAfterIfID+", FALSE, EInternal());return TRUE;}"+ + "BOOL "+_strCurrentClass+"::"+strAfterIfName+"(const CEntityEvent &__eeInput){"+ + "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+ + "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+strAfterIfID+"\n"; + } else { + $$ = $1+$2+$3+$4+$5+$6+$7; + } + } + ; + +statement_if_else + : k_if '(' expression ')' '{' statements '}' k_else statement { + if ($6.bCrossesStates || $9.bCrossesStates) { + char strAfterIfName[80], strAfterIfID[11]; + char strElseName[80], strElseID[11]; + CreateInternalHandlerFunction(strAfterIfName, strAfterIfID); + CreateInternalHandlerFunction(strElseName, strElseID); + $$ = $1+"(!"+$2+$3+$4+"){ Jump(STATE_CURRENT,"+strElseID+", FALSE, EInternal());return TRUE;}"+ + $6+"Jump(STATE_CURRENT,"+strAfterIfID+", FALSE, EInternal());return TRUE;}"+ + "BOOL "+_strCurrentClass+"::"+strElseName+"(const CEntityEvent &__eeInput){"+ + "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+ + "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+strElseID+"\n"+ + $9+"Jump(STATE_CURRENT,"+strAfterIfID+", FALSE, EInternal());return TRUE;}\n"+ + "BOOL "+_strCurrentClass+"::"+strAfterIfName+"(const CEntityEvent &__eeInput){"+ + "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+ + "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+strAfterIfID+"\n"; + } else { + $$ = $1+$2+$3+$4+$5+$6+$7+$8+" "+$9; + } + } + ; + +statement_while + : k_while '(' expression ')' { + if (strlen(_strInLoopName)>0) { + yyerror("Nested loops are not implemented yet"); + } + } '{' statements '}' { + if ($7.bCrossesStates) { + CreateInternalHandlerFunction(_strInLoopName, _strInLoopID); + CreateInternalHandlerFunction(_strAfterLoopName, _strAfterLoopID); + $$ = SType(GetLineDirective($1))+"Jump(STATE_CURRENT,"+_strInLoopID+", FALSE, EInternal());return TRUE;}"+ + "BOOL "+_strCurrentClass+"::"+_strInLoopName+"(const CEntityEvent &__eeInput)"+$6+ + "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+ + "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strInLoopID+"\n"+ + "if(!"+$2+$3+$4+"){ Jump(STATE_CURRENT,"+_strAfterLoopID+", FALSE, EInternal());return TRUE;}"+ + $7+"Jump(STATE_CURRENT,"+_strInLoopID+", FALSE, EInternal());return TRUE;"+$8+ + "BOOL "+_strCurrentClass+"::"+_strAfterLoopName+"(const CEntityEvent &__eeInput) {"+ + "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+ + "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strAfterLoopID+"\n"; + } else { + $$ = $1+$2+$3+$4+$6+$7+$8; + } + _strInLoopName[0] = 0; + } + ; + +statement_dowhile + : k_do '{' statements '}' { + if (strlen(_strInLoopName)>0) { + yyerror("Nested loops are not implemented yet"); + } + _strInLoopName[0] = 0; + } k_while '(' expression ')' ';' { + if ($3.bCrossesStates) { + CreateInternalHandlerFunction(_strInLoopName, _strInLoopID); + CreateInternalHandlerFunction(_strAfterLoopName, _strAfterLoopID); + $$ = SType(GetLineDirective($1))+"Jump(STATE_CURRENT,"+_strInLoopID+", FALSE, EInternal());return TRUE;}"+ + "BOOL "+_strCurrentClass+"::"+_strInLoopName+"(const CEntityEvent &__eeInput)"+$2+ + "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+ + "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strInLoopID+"\n"+$3+ + "if(!"+$7+$8+$9+"){ Jump(STATE_CURRENT,"+_strAfterLoopID+", FALSE, EInternal());return TRUE;}"+ + "Jump(STATE_CURRENT,"+_strInLoopID+", FALSE, EInternal());return TRUE;"+$4+ + "BOOL "+_strCurrentClass+"::"+_strAfterLoopName+"(const CEntityEvent &__eeInput) {"+ + "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+ + "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strAfterLoopID+"\n"; + } else { + $$ = $1+$2+$3+$4+$6+$7+$8+$9+$10; + } + _strInLoopName[0] = 0; + } + ; + +statement_for + : k_for '(' expression ';' expression ';' expression ')' { + if (strlen(_strInLoopName)>0) { + yyerror("Nested loops are not implemented yet"); + } + } '{' statements '}' { + if ($11.bCrossesStates) { + CreateInternalHandlerFunction(_strInLoopName, _strInLoopID); + CreateInternalHandlerFunction(_strAfterLoopName, _strAfterLoopID); + yyerror("For loops across states are not supported"); + } else { + $$ = $1+$2+$3+$4+$5+$6+$7+$8+$10+$11+$12; + } + _strInLoopName[0] = 0; + } + ; + +statement_wait + : k_wait wait_expression { + if (!_bInProcedure) { + yyerror("Cannot have 'wait' in functions"); + } + CreateInternalHandlerFunction(_strInWaitName, _strInWaitID); + CreateInternalHandlerFunction(_strAfterWaitName, _strAfterWaitID); + _bHasOtherwise = 0; + _bInHandler = 1; + } '{' handlers_list '}' { + if ($5.bCrossesStates) { + yyerror("'wait' statements must not be nested"); + $$ = ""; + } else { + SType stDefault; + if (!_bHasOtherwise) { + stDefault = SType("default: return FALSE; break;"); + } else { + stDefault = SType(""); + } + + $$ = SType(GetLineDirective($1))+$2+";\n"+ + "Jump(STATE_CURRENT, "+_strInWaitID+", FALSE, EBegin());return TRUE;}"+ + "BOOL "+_strCurrentClass+"::"+_strInWaitName+"(const CEntityEvent &__eeInput) {"+ + "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strInWaitID+"\n"+ + "switch(__eeInput.ee_slEvent)"+$4+$5+stDefault+$6+ + "return TRUE;}BOOL "+_strCurrentClass+"::"+_strAfterWaitName+"(const CEntityEvent &__eeInput){"+ + "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+ + "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strAfterWaitID+"\n"; + $$.bCrossesStates = 1; + _bInHandler = 0; + } + } + ; +statement_autowait + : k_autowait wait_expression ';' { + if (!_bInProcedure) { + yyerror("Cannot have 'autowait' in functions"); + } + CreateInternalHandlerFunction(_strInWaitName, _strInWaitID); + CreateInternalHandlerFunction(_strAfterWaitName, _strAfterWaitID); + _bHasOtherwise = 0; + + $$ = SType(GetLineDirective($1))+$2+";\n"+ + "Jump(STATE_CURRENT, "+_strInWaitID+", FALSE, EBegin());return TRUE;}"+ + "BOOL "+_strCurrentClass+"::"+_strInWaitName+"(const CEntityEvent &__eeInput) {"+ + "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strInWaitID+"\n"+ + "switch(__eeInput.ee_slEvent) {"+ + "case EVENTCODE_EBegin: return TRUE;"+ + "case EVENTCODE_ETimer: Jump(STATE_CURRENT,"+_strAfterWaitID+", FALSE, EInternal()); return TRUE;"+ + "default: return FALSE; }}"+ + "BOOL "+_strCurrentClass+"::"+_strAfterWaitName+"(const CEntityEvent &__eeInput){"+ + "\nASSERT(__eeInput.ee_slEvent==EVENTCODE_EInternal);"+ + "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strAfterWaitID+"\n"+$3; + $$.bCrossesStates = 1; + } + ; + +statement_waitevent + : k_waitevent wait_expression identifier opt_eventvar ';' { + if (!_bInProcedure) { + yyerror("Cannot have 'autocall' in functions"); + } + CreateInternalHandlerFunction(_strInWaitName, _strInWaitID); + CreateInternalHandlerFunction(_strAfterWaitName, _strAfterWaitID); + _bHasOtherwise = 0; + + $$ = SType(GetLineDirective($1))+$2+";\n"+ + "Jump(STATE_CURRENT, "+_strInWaitID+", FALSE, EBegin());return TRUE;}"+ + "BOOL "+_strCurrentClass+"::"+_strInWaitName+"(const CEntityEvent &__eeInput) {"+ + "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strInWaitID+"\n"+ + "switch(__eeInput.ee_slEvent) {"+ + "case EVENTCODE_EBegin: return TRUE;"+ + "case EVENTCODE_"+$3+": Jump(STATE_CURRENT,"+_strAfterWaitID+", FALSE, __eeInput); return TRUE;"+ + "default: return FALSE; }}"+ + "BOOL "+_strCurrentClass+"::"+_strAfterWaitName+"(const CEntityEvent &__eeInput){"+ + "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strAfterWaitID+"\n"+ + "const "+$3+"&"+$4+"= ("+$3+"&)__eeInput;\n"+$5; + $$.bCrossesStates = 1; + } + ; + + +opt_eventvar + : { + $$ = SType("__e"); + } + | identifier { + $$ = $1; + } + +statement_autocall + : k_autocall jumptarget '(' event_expression ')' identifier opt_eventvar ';' { + if (!_bInProcedure) { + yyerror("Cannot have 'autocall' in functions"); + } + CreateInternalHandlerFunction(_strInWaitName, _strInWaitID); + CreateInternalHandlerFunction(_strAfterWaitName, _strAfterWaitID); + _bHasOtherwise = 0; + + $$ = SType(GetLineDirective($1))+$2+";\n"+ + "Jump(STATE_CURRENT, "+_strInWaitID+", FALSE, EBegin());return TRUE;}"+ + "BOOL "+_strCurrentClass+"::"+_strInWaitName+"(const CEntityEvent &__eeInput) {"+ + "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strInWaitID+"\n"+ + "switch(__eeInput.ee_slEvent) {"+ + "case EVENTCODE_EBegin: Call"+$3+"STATE_CURRENT, "+$2+", "+$4+$5+";return TRUE;"+ + "case EVENTCODE_"+$6+": Jump(STATE_CURRENT,"+_strAfterWaitID+", FALSE, __eeInput); return TRUE;"+ + "default: return FALSE; }}"+ + "BOOL "+_strCurrentClass+"::"+_strAfterWaitName+"(const CEntityEvent &__eeInput){"+ + "\n#undef STATE_CURRENT\n#define STATE_CURRENT "+_strAfterWaitID+"\n"+ + "const "+$6+"&"+$7+"= ("+$6+"&)__eeInput;\n"+$8; + $$.bCrossesStates = 1; + } + ; + +wait_expression + : '(' ')' { + $$ = SType("SetTimerAt(THINKTIME_NEVER)"); + } + | '(' expression ')' { + $$ = SType("SetTimerAfter")+$1+$2+$3; + } + ; + +statement_jump + : k_jump jumptarget '(' event_expression ')' ';' { + if (!_bInProcedure) { + yyerror("Cannot have 'jump' in functions"); + } + $$ = SType(GetLineDirective($1))+"Jump"+$3+"STATE_CURRENT, "+$2+", "+$4+$5+";return TRUE;"; + } + ; + +statement_call + : k_call jumptarget '(' event_expression')' ';' { + if (!_bInProcedure) { + yyerror("Cannot have 'call' in functions"); + } + if (!_bInHandler) { + yyerror("'call' must be inside a 'wait' statement"); + } + $$ = SType(GetLineDirective($1))+"Call"+$3+"STATE_CURRENT, "+$2+", "+$4+$5+";return TRUE;"; + } + ; + +event_expression + : expression { + $$ = $1; + } + | { + $$ = SType("EVoid()"); + } + ; + +jumptarget + : identifier { + $$ = SType("STATE_")+_strCurrentClass+"_"+$1+", TRUE"; + } + | identifier ':' ':' identifier { + $$ = SType("STATE_")+$1+"_"+$4+", FALSE"; + } + ; + +statement_stop + : k_stop ';' { + $$ = SType(GetLineDirective($1))+"UnsetTimer();Jump(STATE_CURRENT," + +_strAfterWaitID+", FALSE, EInternal());"+"return TRUE"+$2; + } + ; +statement_resume + : k_resume ';' { + $$ = SType(GetLineDirective($1))+"return TRUE"+$2; + } + ; +statement_pass + : k_pass ';' { + $$ = SType(GetLineDirective($1))+"return FALSE"+$2; + } + ; +statement_return + : k_return opt_expression ';' { + if (!_bInProcedure) { + $$ = $1+" "+$2+$3; + } else { + if (strlen($2.strString)==0) { + $2 = SType("EVoid()"); + } + $$ = SType(GetLineDirective($1)) + +"Return(STATE_CURRENT,"+$2+");" + +$1+" TRUE"+$3; + } + } + ; +opt_expression + : {$$ = "";} + | expression + ; + +handler + : k_on '(' event_specification ')' ':' '{' statements '}' opt_semicolon { + char strInputEventType[80]; + char strInputEventName[80]; + sscanf($3.strString, "%s %s", strInputEventType, strInputEventName); + + $$ = SType("case")+$2+"EVENTCODE_"+strInputEventType+$4+$5+$6+ + "const "+strInputEventType+"&"+strInputEventName+"= ("+ + strInputEventType+"&)__eeInput;\n"+$7+$8+"ASSERT(FALSE);break;"; + } + | k_otherwise '(' event_specification ')' ':' '{' statements '}' opt_semicolon { + char strInputEventType[80]; + char strInputEventName[80]; + sscanf($3.strString, "%s %s", strInputEventType, strInputEventName); + + $$ = SType("default")+$5+$6+$7+$8+"ASSERT(FALSE);break;"; + _bHasOtherwise = 1; + } + ; +handlers_list + : { $$ = "";} + | handlers_list handler { $$ = $1+$2; } + ; + +%% diff --git a/Sources/Ecc/Scanner.l b/Sources/Ecc/Scanner.l index 554b7e6..d85a499 100644 --- a/Sources/Ecc/Scanner.l +++ b/Sources/Ecc/Scanner.l @@ -1,172 +1,172 @@ -%{ -// rcg10042001 Changed to specify Ecc directory... -#include "Ecc/StdH.h" -#include "Ecc/Main.h" -#include "Ecc/Parser.h" - -#define YY_NEVER_INTERACTIVE 1 - - -int iLastLine = -1; - -#define RETURN(symbolname) \ - if (iLastLine==_iLinesCt || !_bTrackLineInformation){\ - yylval = yytext; \ - } else { \ - char strLine[512]; \ - sprintf(strLine, "\n#line %d \"%s\"\n", _iLinesCt, _strInputFileName);\ - yylval = SType(strLine)+yytext; \ - iLastLine=_iLinesCt; \ - } \ - return symbolname; - -char *_strCppBlock; - -%} - -%x COMMENT -%x CPPBLOCK - -DIGIT [0-9] -HEXDIGIT [0-9A-Fa-f] -IDENTIFIERFIRST [A-Za-z_] -IDENTIFIEROTHER [A-Za-z0-9_] -DOUBLEQUOTE \" -NONEXP_FLT ({DIGIT}+"."{DIGIT}*) -EXP_FLT (({DIGIT}+("."({DIGIT}*)?)?)("E"|"e")("+"|"-")?{DIGIT}+) - -%% - - /* standard cpp-keywords */ -"while" {RETURN(k_while);} -"switch" {RETURN(k_switch);} -"case" {RETURN(k_case);} -"for" {RETURN(k_for);} -"if" {RETURN(k_if);} -"else" {RETURN(k_else);} -"enum" {RETURN(k_enum);} -"class" {RETURN(k_class);} -"do" {RETURN(k_do);} -"void" {RETURN(k_void);} -"const" {RETURN(k_const);} -"inline" {RETURN(k_inline);} -"static" {RETURN(k_static);} -"virtual" {RETURN(k_virtual);} -"return" {RETURN(k_return);} -"autowait" {RETURN(k_autowait);} -"autocall" {RETURN(k_autocall);} -"waitevent" {RETURN(k_waitevent);} - - /* aditional keywords */ -"event" {RETURN(k_event);} -"name" {RETURN(k_name);} -"thumbnail" {RETURN(k_thumbnail);} -"features" {RETURN(k_features);} -"uses" {RETURN(k_uses);} -"export" {RETURN(k_export);} - -"texture" {RETURN(k_texture);} -"sound" {RETURN(k_sound);} -"model" {RETURN(k_model);} - -"properties" {RETURN(k_properties);} -"components" {RETURN(k_components);} -"functions" {RETURN(k_functions);} -"procedures" {RETURN(k_procedures);} - -"wait" {RETURN(k_wait );} -"on" {RETURN(k_on );} -"otherwise" {RETURN(k_otherwise);} - -"call" {RETURN(k_call );} -"jump" {RETURN(k_jump );} -"stop" {RETURN(k_stop );} -"resume" {RETURN(k_resume );} -"pass" {RETURN(k_pass );} - - /* special data types */ -"CTString" {RETURN(k_CTString);} -"CTStringTrans" {RETURN(k_CTStringTrans);} -"CTFileName" {RETURN(k_CTFileName);} -"CTFileNameNoDep" {RETURN(k_CTFileNameNoDep);} -"BOOL" {RETURN(k_BOOL);} -"COLOR" {RETURN(k_COLOR);} -"FLOAT" {RETURN(k_FLOAT);} -"INDEX" {RETURN(k_INDEX);} -"RANGE" {RETURN(k_RANGE);} -"CEntityPointer" {RETURN(k_CEntityPointer);} -"CModelObject" {RETURN(k_CModelObject);} -"CModelInstance" {RETURN(k_CModelInstance);} -"CAnimObject" {RETURN(k_CAnimObject);} -"CSoundObject" {RETURN(k_CSoundObject);} -"CPlacement3D" {RETURN(k_CPlacement3D);} -"FLOATaabbox3D" {RETURN(k_FLOATaabbox3D);} -"FLOATmatrix3D" {RETURN(k_FLOATmatrix3D);} -"FLOATquat3D" {RETURN(k_FLOATquat3D);} -"ANGLE" {RETURN(k_ANGLE);}; -"ANIMATION" {RETURN(k_ANIMATION);}; -"ILLUMINATIONTYPE" {RETURN(k_ILLUMINATIONTYPE);}; -"FLOAT3D" {RETURN(k_FLOAT3D);}; -"ANGLE3D" {RETURN(k_ANGLE3D);}; -"FLOATplane3D" {RETURN(k_FLOATplane3D);}; -"flags" {RETURN(k_FLAGS);}; - - /* single character operators and punctuations */ -";"|"("|")"|"{"|"}"|"="|"+"|"-"|"<"|">"|"!"|"|"|"&"|"*"|"/"|"%"|"^"|"["|"]"|":"|","|"."|"?"|"~" { - RETURN(yytext[0]);} - - /* constants */ -{DIGIT}+ { RETURN(c_int); } -"0x"{HEXDIGIT}+ { RETURN(c_int)}; -{NONEXP_FLT}("f"|"F")? { RETURN(c_int); } -{EXP_FLT}("f"|"F")? { RETURN(c_int); } -(\"[^\n"]+\")|(\"\") { RETURN(c_string); } -(\'[^\n']+\')|(\'\') { RETURN(c_char); } - - /* identifier */ -{IDENTIFIERFIRST}{IDENTIFIEROTHER}* {RETURN(identifier);} - - /* specially bracketed cpp blocks */ -"%{" { - char strLine[512]; - sprintf(strLine, "#line %d \"%s\"\n", _iLinesCt, _strInputFileName ); - _strCppBlock = strdup(strLine); - BEGIN(CPPBLOCK); -} -"%}" { - BEGIN(INITIAL); - yylval = SType(_strCppBlock); - return cppblock; -} -\n { - _iLinesCt++; - _strCppBlock = (SType(_strCppBlock)+yytext).strString; - } -.* { - _strCppBlock = (SType(_strCppBlock)+yytext).strString; -} - - /* eat up comments */ -"/*" { BEGIN(COMMENT); } -"*/" { BEGIN(INITIAL); } -. {} -"//"[^\n]*\n { _iLinesCt++; } - - /* eat up whitespace */ -[ \t]+ { -} - /* eat up linefeeds and count lines in all conditions */ -<*>\n { - _iLinesCt++; - } - /* for all unrecognized characters */ -. { - // report an error - char strError[80]; - sprintf(strError, "Unrecognized character '%c' (ASCII 0x%02x)\n", - yytext[0], yytext[0] ); - yyerror(strError); -} - -%% - +%{ +// rcg10042001 Changed to specify Ecc directory... +#include "Ecc/StdH.h" +#include "Ecc/Main.h" +#include "Ecc/Parser.h" + +#define YY_NEVER_INTERACTIVE 1 + + +int iLastLine = -1; + +#define RETURN(symbolname) \ + if (iLastLine==_iLinesCt || !_bTrackLineInformation){\ + yylval = yytext; \ + } else { \ + char strLine[512]; \ + sprintf(strLine, "\n#line %d \"%s\"\n", _iLinesCt, _strInputFileName);\ + yylval = SType(strLine)+yytext; \ + iLastLine=_iLinesCt; \ + } \ + return symbolname; + +char *_strCppBlock; + +%} + +%x COMMENT +%x CPPBLOCK + +DIGIT [0-9] +HEXDIGIT [0-9A-Fa-f] +IDENTIFIERFIRST [A-Za-z_] +IDENTIFIEROTHER [A-Za-z0-9_] +DOUBLEQUOTE \" +NONEXP_FLT ({DIGIT}+"."{DIGIT}*) +EXP_FLT (({DIGIT}+("."({DIGIT}*)?)?)("E"|"e")("+"|"-")?{DIGIT}+) + +%% + + /* standard cpp-keywords */ +"while" {RETURN(k_while);} +"switch" {RETURN(k_switch);} +"case" {RETURN(k_case);} +"for" {RETURN(k_for);} +"if" {RETURN(k_if);} +"else" {RETURN(k_else);} +"enum" {RETURN(k_enum);} +"class" {RETURN(k_class);} +"do" {RETURN(k_do);} +"void" {RETURN(k_void);} +"const" {RETURN(k_const);} +"inline" {RETURN(k_inline);} +"static" {RETURN(k_static);} +"virtual" {RETURN(k_virtual);} +"return" {RETURN(k_return);} +"autowait" {RETURN(k_autowait);} +"autocall" {RETURN(k_autocall);} +"waitevent" {RETURN(k_waitevent);} + + /* aditional keywords */ +"event" {RETURN(k_event);} +"name" {RETURN(k_name);} +"thumbnail" {RETURN(k_thumbnail);} +"features" {RETURN(k_features);} +"uses" {RETURN(k_uses);} +"export" {RETURN(k_export);} + +"texture" {RETURN(k_texture);} +"sound" {RETURN(k_sound);} +"model" {RETURN(k_model);} + +"properties" {RETURN(k_properties);} +"components" {RETURN(k_components);} +"functions" {RETURN(k_functions);} +"procedures" {RETURN(k_procedures);} + +"wait" {RETURN(k_wait );} +"on" {RETURN(k_on );} +"otherwise" {RETURN(k_otherwise);} + +"call" {RETURN(k_call );} +"jump" {RETURN(k_jump );} +"stop" {RETURN(k_stop );} +"resume" {RETURN(k_resume );} +"pass" {RETURN(k_pass );} + + /* special data types */ +"CTString" {RETURN(k_CTString);} +"CTStringTrans" {RETURN(k_CTStringTrans);} +"CTFileName" {RETURN(k_CTFileName);} +"CTFileNameNoDep" {RETURN(k_CTFileNameNoDep);} +"BOOL" {RETURN(k_BOOL);} +"COLOR" {RETURN(k_COLOR);} +"FLOAT" {RETURN(k_FLOAT);} +"INDEX" {RETURN(k_INDEX);} +"RANGE" {RETURN(k_RANGE);} +"CEntityPointer" {RETURN(k_CEntityPointer);} +"CModelObject" {RETURN(k_CModelObject);} +"CModelInstance" {RETURN(k_CModelInstance);} +"CAnimObject" {RETURN(k_CAnimObject);} +"CSoundObject" {RETURN(k_CSoundObject);} +"CPlacement3D" {RETURN(k_CPlacement3D);} +"FLOATaabbox3D" {RETURN(k_FLOATaabbox3D);} +"FLOATmatrix3D" {RETURN(k_FLOATmatrix3D);} +"FLOATquat3D" {RETURN(k_FLOATquat3D);} +"ANGLE" {RETURN(k_ANGLE);}; +"ANIMATION" {RETURN(k_ANIMATION);}; +"ILLUMINATIONTYPE" {RETURN(k_ILLUMINATIONTYPE);}; +"FLOAT3D" {RETURN(k_FLOAT3D);}; +"ANGLE3D" {RETURN(k_ANGLE3D);}; +"FLOATplane3D" {RETURN(k_FLOATplane3D);}; +"flags" {RETURN(k_FLAGS);}; + + /* single character operators and punctuations */ +";"|"("|")"|"{"|"}"|"="|"+"|"-"|"<"|">"|"!"|"|"|"&"|"*"|"/"|"%"|"^"|"["|"]"|":"|","|"."|"?"|"~" { + RETURN(yytext[0]);} + + /* constants */ +{DIGIT}+ { RETURN(c_int); } +"0x"{HEXDIGIT}+ { RETURN(c_int)}; +{NONEXP_FLT}("f"|"F")? { RETURN(c_int); } +{EXP_FLT}("f"|"F")? { RETURN(c_int); } +(\"[^\n"]+\")|(\"\") { RETURN(c_string); } +(\'[^\n']+\')|(\'\') { RETURN(c_char); } + + /* identifier */ +{IDENTIFIERFIRST}{IDENTIFIEROTHER}* {RETURN(identifier);} + + /* specially bracketed cpp blocks */ +"%{" { + char strLine[512]; + sprintf(strLine, "#line %d \"%s\"\n", _iLinesCt, _strInputFileName ); + _strCppBlock = strdup(strLine); + BEGIN(CPPBLOCK); +} +"%}" { + BEGIN(INITIAL); + yylval = SType(_strCppBlock); + return cppblock; +} +\n { + _iLinesCt++; + _strCppBlock = (SType(_strCppBlock)+yytext).strString; + } +.* { + _strCppBlock = (SType(_strCppBlock)+yytext).strString; +} + + /* eat up comments */ +"/*" { BEGIN(COMMENT); } +"*/" { BEGIN(INITIAL); } +. {} +"//"[^\n]*\n { _iLinesCt++; } + + /* eat up whitespace */ +[ \t]+ { +} + /* eat up linefeeds and count lines in all conditions */ +<*>\n { + _iLinesCt++; + } + /* for all unrecognized characters */ +. { + // report an error + char strError[80]; + sprintf(strError, "Unrecognized character '%c' (ASCII 0x%02x)\n", + yytext[0], yytext[0] ); + yyerror(strError); +} + +%% + diff --git a/Sources/Ecc/StdH.h b/Sources/Ecc/StdH.h index e5dd218..100483c 100644 --- a/Sources/Ecc/StdH.h +++ b/Sources/Ecc/StdH.h @@ -29,5 +29,5 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include -#define _fullpath(x, y, z) realpath(y, x) +#define _fullpath(x, y, z) char *res = realpath(y, x) #endif diff --git a/Sources/Ecc/bison.simple b/Sources/Ecc/bison.simple index 0fb74ce..f45278f 100644 --- a/Sources/Ecc/bison.simple +++ b/Sources/Ecc/bison.simple @@ -1,686 +1,686 @@ -/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "bison.simple" - -/* Skeleton output parser for bison, - Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. - - 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; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -#ifndef alloca -#ifdef __GNUC__ -#define alloca __builtin_alloca -#else /* not GNU C. */ -#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) -#include -#else /* not sparc */ -#if defined (MSDOS) && !defined (__TURBOC__) -#include -#else /* not MSDOS, or __TURBOC__ */ -#if defined(_AIX) -#include - #pragma alloca -#else /* not MSDOS, __TURBOC__, or _AIX */ -#ifdef __hpux -#ifdef __cplusplus -extern "C" { -void *alloca (unsigned int); -}; -#else /* not __cplusplus */ -void *alloca (); -#endif /* not __cplusplus */ -#endif /* __hpux */ -#endif /* not _AIX */ -#endif /* not MSDOS, or __TURBOC__ */ -#endif /* not sparc. */ -#endif /* not GNU C. */ -#endif /* alloca not defined. */ - -/* This is the parser code that is written into each bison parser - when the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ - -/* Note: there must be only one dollar sign in this file. - It is replaced by the list of actions, each action - as one case of the switch. */ - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY -2 -#define YYEOF 0 -#define YYACCEPT return(0) -#define YYABORT return(1) -#define YYERROR goto yyerrlab1 -/* Like YYERROR except do call yyerror. - This remains here temporarily to ease the - transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab -#define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(token, value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { yychar = (token), yylval = (value); \ - yychar1 = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { yyerror ("syntax error: cannot back up"); YYERROR; } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - -#ifndef YYPURE -#define YYLEX yylex() -#endif - -#ifdef YYPURE -#ifdef YYLSP_NEEDED -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval, &yylloc) -#endif -#else /* not YYLSP_NEEDED */ -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval) -#endif -#endif /* not YYLSP_NEEDED */ -#endif - -/* If nonreentrant, generate the variables here */ - -#ifndef YYPURE - -int yychar; /* the lookahead symbol */ -YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ - -#ifdef YYLSP_NEEDED -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ -#endif - -int yynerrs; /* number of parse errors so far */ -#endif /* not YYPURE */ - -#if YYDEBUG != 0 -int yydebug; /* nonzero means print parse trace */ -/* Since this is uninitialized, it does not stop multiple parsers - from coexisting. */ -#endif - -/* YYINITDEPTH indicates the initial size of the parser's stacks */ - -#ifndef YYINITDEPTH -#define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH is the maximum size the stacks can grow to - (effective only if the built-in stack extension method is used). */ - -#if YYMAXDEPTH == 0 -#undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -#define YYMAXDEPTH 10000 -#endif - -/* Prevent warning if -Wstrict-prototypes. */ -#ifdef __GNUC__ -int yyparse (void); -#endif - -#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ -#define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) -#else /* not GNU C or C++ */ -#ifndef __cplusplus - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (from, to, count) - char *from; - char *to; - int count; -{ - register char *f = from; - register char *t = to; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#else /* __cplusplus */ - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (char *from, char *to, int count) -{ - register char *f = from; - register char *t = to; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#endif -#endif - -#line 192 "bison.simple" - -/* The user can define YYPARSE_PARAM as the name of an argument to be passed - into yyparse. The argument should have type void *. - It should actually point to an object. - Grammar actions can access the variable by casting it - to the proper pointer type. */ - -#ifdef YYPARSE_PARAM -#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; -#else -#define YYPARSE_PARAM -#define YYPARSE_PARAM_DECL -#endif - -int -yyparse(YYPARSE_PARAM) - YYPARSE_PARAM_DECL -{ - register int yystate; - register int yyn; - register short *yyssp; - register YYSTYPE *yyvsp; - int yyerrstatus; /* number of tokens to shift before error messages enabled */ - int yychar1 = 0; /* lookahead token as an internal (translated) token number */ - - short yyssa[YYINITDEPTH]; /* the state stack */ - YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ - - short *yyss = yyssa; /* refer to the stacks thru separate pointers */ - YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ - -#ifdef YYLSP_NEEDED - YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - -#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) -#else -#define YYPOPSTACK (yyvsp--, yyssp--) -#endif - - int yystacksize = YYINITDEPTH; - -#ifdef YYPURE - int yychar; - YYSTYPE yylval; - int yynerrs; -#ifdef YYLSP_NEEDED - YYLTYPE yylloc; -#endif -#endif - - YYSTYPE yyval; /* the variable used to return */ - /* semantic values from the action */ - /* routines */ - - int yylen; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Starting parse\n"); -#endif - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss - 1; - yyvsp = yyvs; -#ifdef YYLSP_NEEDED - yylsp = yyls; -#endif - -/* Push a new state, which is found in yystate . */ -/* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. */ -yynewstate: - - *++yyssp = yystate; - - if (yyssp >= yyss + yystacksize - 1) - { - /* Give user a chance to reallocate the stack */ - /* Use copies of these so that the &'s don't force the real ones into memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; -#ifdef YYLSP_NEEDED - YYLTYPE *yyls1 = yyls; -#endif - - /* Get the current used size of the three stacks, in elements. */ - int size = yyssp - yyss + 1; - -#ifdef yyoverflow - /* Each stack pointer address is followed by the size of - the data in use in that stack, in bytes. */ -#ifdef YYLSP_NEEDED - /* This used to be a conditional around just the two extra args, - but that might be undefined if yyoverflow is a macro. */ - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yyls1, size * sizeof (*yylsp), - &yystacksize); -#else - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yystacksize); -#endif - - yyss = yyss1; yyvs = yyvs1; -#ifdef YYLSP_NEEDED - yyls = yyls1; -#endif -#else /* no yyoverflow */ - /* Extend the stack our own way. */ - if (yystacksize >= YYMAXDEPTH) - { - yyerror("parser stack overflow"); - return 2; - } - yystacksize *= 2; - if (yystacksize > YYMAXDEPTH) - yystacksize = YYMAXDEPTH; - yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); - __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); - yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); - __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); -#ifdef YYLSP_NEEDED - yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); - __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); -#endif -#endif /* no yyoverflow */ - - yyssp = yyss + size - 1; - yyvsp = yyvs + size - 1; -#ifdef YYLSP_NEEDED - yylsp = yyls + size - 1; -#endif - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Stack size increased to %d\n", yystacksize); -#endif - - if (yyssp >= yyss + yystacksize - 1) - YYABORT; - } - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Entering state %d\n", yystate); -#endif - - goto yybackup; - yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ - - if (yychar == YYEMPTY) - { -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Reading a token: "); -#endif - yychar = YYLEX; - } - - /* Convert token to internal form (in yychar1) for indexing tables with */ - - if (yychar <= 0) /* This means end of input. */ - { - yychar1 = 0; - yychar = YYEOF; /* Don't call YYLEX any more */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Now at end of input.\n"); -#endif - } - else - { - yychar1 = YYTRANSLATE(yychar); - -#if YYDEBUG != 0 - if (yydebug) - { - fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); - /* Give the individual parser a way to print the precise meaning - of a token, for further debugging info. */ -#ifdef YYPRINT - YYPRINT (stderr, yychar, yylval); -#endif - fprintf (stderr, ")\n"); - } -#endif - } - - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) - goto yydefault; - - yyn = yytable[yyn]; - - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrlab; - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); -#endif - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - /* count tokens shifted since error; after three, turn off error status. */ - if (yyerrstatus) yyerrstatus--; - - yystate = yyn; - goto yynewstate; - -/* Do the default action for the current state. */ -yydefault: - - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - -/* Do a reduction. yyn is the number of a rule to reduce with. */ -yyreduce: - yylen = yyr2[yyn]; - if (yylen > 0) - yyval = yyvsp[1-yylen]; /* implement default value of the action */ - -#if YYDEBUG != 0 - if (yydebug) - { - int i; - - fprintf (stderr, "Reducing via rule %d (line %d), ", - yyn, yyrline[yyn]); - - /* Print the symbols being reduced, and their result. */ - for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) - fprintf (stderr, "%s ", yytname[yyrhs[i]]); - fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); - } -#endif - -$ /* the action file gets copied in in place of this dollarsign */ -#line 487 "bison.simple" - - yyvsp -= yylen; - yyssp -= yylen; -#ifdef YYLSP_NEEDED - yylsp -= yylen; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - - *++yyvsp = yyval; - -#ifdef YYLSP_NEEDED - yylsp++; - if (yylen == 0) - { - yylsp->first_line = yylloc.first_line; - yylsp->first_column = yylloc.first_column; - yylsp->last_line = (yylsp-1)->last_line; - yylsp->last_column = (yylsp-1)->last_column; - yylsp->text = 0; - } - else - { - yylsp->last_line = (yylsp+yylen-1)->last_line; - yylsp->last_column = (yylsp+yylen-1)->last_column; - } -#endif - - /* Now "shift" the result of the reduction. - Determine what state that goes to, - based on the state we popped back to - and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTBASE]; - - goto yynewstate; - -yyerrlab: /* here on detecting error */ - - if (! yyerrstatus) - /* If not already recovering from an error, report this error. */ - { - ++yynerrs; - -#ifdef YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (yyn > YYFLAG && yyn < YYLAST) - { - int size = 0; - char *msg; - int x, count; - - count = 0; - /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - size += strlen(yytname[x]) + 15, count++; - msg = (char *) malloc(size + 15); - if (msg != 0) - { - strcpy(msg, "parse error"); - - if (count < 5) - { - count = 0; - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - { - strcat(msg, count == 0 ? ", expecting `" : " or `"); - strcat(msg, yytname[x]); - strcat(msg, "'"); - count++; - } - } - yyerror(msg); - free(msg); - } - else - yyerror ("parse error; also virtual memory exceeded"); - } - else -#endif /* YYERROR_VERBOSE */ - yyerror("parse error"); - } - - goto yyerrlab1; -yyerrlab1: /* here on error raised explicitly by an action */ - - if (yyerrstatus == 3) - { - /* if just tried and failed to reuse lookahead token after an error, discard it. */ - - /* return failure if at end of input */ - if (yychar == YYEOF) - YYABORT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); -#endif - - yychar = YYEMPTY; - } - - /* Else will try to reuse lookahead token - after shifting the error token. */ - - yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto yyerrhandle; - -yyerrdefault: /* current state does not do anything special for the error token. */ - -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ - if (yyn) goto yydefault; -#endif - -yyerrpop: /* pop the current state because it cannot handle the error token */ - - if (yyssp == yyss) YYABORT; - yyvsp--; - yystate = *--yyssp; -#ifdef YYLSP_NEEDED - yylsp--; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "Error: state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - -yyerrhandle: - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; - - if (yyn == YYFINAL) - YYACCEPT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting error token, "); -#endif - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - yystate = yyn; - goto yynewstate; -} +/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +#line 3 "bison.simple" + +/* Skeleton output parser for bison, + Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + 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; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +#ifndef alloca +#ifdef __GNUC__ +#define alloca __builtin_alloca +#else /* not GNU C. */ +#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) +#include +#else /* not sparc */ +#if defined (MSDOS) && !defined (__TURBOC__) +#include +#else /* not MSDOS, or __TURBOC__ */ +#if defined(_AIX) +#include + #pragma alloca +#else /* not MSDOS, __TURBOC__, or _AIX */ +#ifdef __hpux +#ifdef __cplusplus +extern "C" { +void *alloca (unsigned int); +}; +#else /* not __cplusplus */ +void *alloca (); +#endif /* not __cplusplus */ +#endif /* __hpux */ +#endif /* not _AIX */ +#endif /* not MSDOS, or __TURBOC__ */ +#endif /* not sparc. */ +#endif /* not GNU C. */ +#endif /* alloca not defined. */ + +/* This is the parser code that is written into each bison parser + when the %semantic_parser declaration is not specified in the grammar. + It was written by Richard Stallman by simplifying the hairy parser + used when %semantic_parser is specified. */ + +/* Note: there must be only one dollar sign in this file. + It is replaced by the list of actions, each action + as one case of the switch. */ + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY -2 +#define YYEOF 0 +#define YYACCEPT return(0) +#define YYABORT return(1) +#define YYERROR goto yyerrlab1 +/* Like YYERROR except do call yyerror. + This remains here temporarily to ease the + transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ +#define YYFAIL goto yyerrlab +#define YYRECOVERING() (!!yyerrstatus) +#define YYBACKUP(token, value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { yychar = (token), yylval = (value); \ + yychar1 = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { yyerror ("syntax error: cannot back up"); YYERROR; } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +#ifndef YYPURE +#define YYLEX yylex() +#endif + +#ifdef YYPURE +#ifdef YYLSP_NEEDED +#ifdef YYLEX_PARAM +#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) +#else +#define YYLEX yylex(&yylval, &yylloc) +#endif +#else /* not YYLSP_NEEDED */ +#ifdef YYLEX_PARAM +#define YYLEX yylex(&yylval, YYLEX_PARAM) +#else +#define YYLEX yylex(&yylval) +#endif +#endif /* not YYLSP_NEEDED */ +#endif + +/* If nonreentrant, generate the variables here */ + +#ifndef YYPURE + +int yychar; /* the lookahead symbol */ +YYSTYPE yylval; /* the semantic value of the */ + /* lookahead symbol */ + +#ifdef YYLSP_NEEDED +YYLTYPE yylloc; /* location data for the lookahead */ + /* symbol */ +#endif + +int yynerrs; /* number of parse errors so far */ +#endif /* not YYPURE */ + +#if YYDEBUG != 0 +int yydebug; /* nonzero means print parse trace */ +/* Since this is uninitialized, it does not stop multiple parsers + from coexisting. */ +#endif + +/* YYINITDEPTH indicates the initial size of the parser's stacks */ + +#ifndef YYINITDEPTH +#define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH is the maximum size the stacks can grow to + (effective only if the built-in stack extension method is used). */ + +#if YYMAXDEPTH == 0 +#undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +#define YYMAXDEPTH 10000 +#endif + +/* Prevent warning if -Wstrict-prototypes. */ +#ifdef __GNUC__ +int yyparse (void); +#endif + +#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +#define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) +#else /* not GNU C or C++ */ +#ifndef __cplusplus + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__yy_memcpy (from, to, count) + char *from; + char *to; + int count; +{ + register char *f = from; + register char *t = to; + register int i = count; + + while (i-- > 0) + *t++ = *f++; +} + +#else /* __cplusplus */ + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__yy_memcpy (char *from, char *to, int count) +{ + register char *f = from; + register char *t = to; + register int i = count; + + while (i-- > 0) + *t++ = *f++; +} + +#endif +#endif + +#line 192 "bison.simple" + +/* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. + It should actually point to an object. + Grammar actions can access the variable by casting it + to the proper pointer type. */ + +#ifdef YYPARSE_PARAM +#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; +#else +#define YYPARSE_PARAM +#define YYPARSE_PARAM_DECL +#endif + +int +yyparse(YYPARSE_PARAM) + YYPARSE_PARAM_DECL +{ + register int yystate; + register int yyn; + register short *yyssp; + register YYSTYPE *yyvsp; + int yyerrstatus; /* number of tokens to shift before error messages enabled */ + int yychar1 = 0; /* lookahead token as an internal (translated) token number */ + + short yyssa[YYINITDEPTH]; /* the state stack */ + YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ + + short *yyss = yyssa; /* refer to the stacks thru separate pointers */ + YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ + +#ifdef YYLSP_NEEDED + YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ + YYLTYPE *yyls = yylsa; + YYLTYPE *yylsp; + +#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) +#else +#define YYPOPSTACK (yyvsp--, yyssp--) +#endif + + int yystacksize = YYINITDEPTH; + +#ifdef YYPURE + int yychar; + YYSTYPE yylval; + int yynerrs; +#ifdef YYLSP_NEEDED + YYLTYPE yylloc; +#endif +#endif + + YYSTYPE yyval; /* the variable used to return */ + /* semantic values from the action */ + /* routines */ + + int yylen; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Starting parse\n"); +#endif + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss - 1; + yyvsp = yyvs; +#ifdef YYLSP_NEEDED + yylsp = yyls; +#endif + +/* Push a new state, which is found in yystate . */ +/* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. */ +yynewstate: + + *++yyssp = yystate; + + if (yyssp >= yyss + yystacksize - 1) + { + /* Give user a chance to reallocate the stack */ + /* Use copies of these so that the &'s don't force the real ones into memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; +#ifdef YYLSP_NEEDED + YYLTYPE *yyls1 = yyls; +#endif + + /* Get the current used size of the three stacks, in elements. */ + int size = yyssp - yyss + 1; + +#ifdef yyoverflow + /* Each stack pointer address is followed by the size of + the data in use in that stack, in bytes. */ +#ifdef YYLSP_NEEDED + /* This used to be a conditional around just the two extra args, + but that might be undefined if yyoverflow is a macro. */ + yyoverflow("parser stack overflow", + &yyss1, size * sizeof (*yyssp), + &yyvs1, size * sizeof (*yyvsp), + &yyls1, size * sizeof (*yylsp), + &yystacksize); +#else + yyoverflow("parser stack overflow", + &yyss1, size * sizeof (*yyssp), + &yyvs1, size * sizeof (*yyvsp), + &yystacksize); +#endif + + yyss = yyss1; yyvs = yyvs1; +#ifdef YYLSP_NEEDED + yyls = yyls1; +#endif +#else /* no yyoverflow */ + /* Extend the stack our own way. */ + if (yystacksize >= YYMAXDEPTH) + { + yyerror("parser stack overflow"); + return 2; + } + yystacksize *= 2; + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); + __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); + __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); +#ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); + __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); +#endif +#endif /* no yyoverflow */ + + yyssp = yyss + size - 1; + yyvsp = yyvs + size - 1; +#ifdef YYLSP_NEEDED + yylsp = yyls + size - 1; +#endif + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Stack size increased to %d\n", yystacksize); +#endif + + if (yyssp >= yyss + yystacksize - 1) + YYABORT; + } + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Entering state %d\n", yystate); +#endif + + goto yybackup; + yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* yychar is either YYEMPTY or YYEOF + or a valid token in external form. */ + + if (yychar == YYEMPTY) + { +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Reading a token: "); +#endif + yychar = YYLEX; + } + + /* Convert token to internal form (in yychar1) for indexing tables with */ + + if (yychar <= 0) /* This means end of input. */ + { + yychar1 = 0; + yychar = YYEOF; /* Don't call YYLEX any more */ + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Now at end of input.\n"); +#endif + } + else + { + yychar1 = YYTRANSLATE(yychar); + +#if YYDEBUG != 0 + if (yydebug) + { + fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); + /* Give the individual parser a way to print the precise meaning + of a token, for further debugging info. */ +#ifdef YYPRINT + YYPRINT (stderr, yychar, yylval); +#endif + fprintf (stderr, ")\n"); + } +#endif + } + + yyn += yychar1; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) + goto yydefault; + + yyn = yytable[yyn]; + + /* yyn is what to do for this token type in this state. + Negative => reduce, -yyn is rule number. + Positive => shift, yyn is new state. + New state is final state => don't bother to shift, + just return success. + 0, or most negative number => error. */ + + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrlab; + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); +#endif + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; +#ifdef YYLSP_NEEDED + *++yylsp = yylloc; +#endif + + /* count tokens shifted since error; after three, turn off error status. */ + if (yyerrstatus) yyerrstatus--; + + yystate = yyn; + goto yynewstate; + +/* Do the default action for the current state. */ +yydefault: + + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + +/* Do a reduction. yyn is the number of a rule to reduce with. */ +yyreduce: + yylen = yyr2[yyn]; + if (yylen > 0) + yyval = yyvsp[1-yylen]; /* implement default value of the action */ + +#if YYDEBUG != 0 + if (yydebug) + { + int i; + + fprintf (stderr, "Reducing via rule %d (line %d), ", + yyn, yyrline[yyn]); + + /* Print the symbols being reduced, and their result. */ + for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) + fprintf (stderr, "%s ", yytname[yyrhs[i]]); + fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); + } +#endif + +$ /* the action file gets copied in in place of this dollarsign */ +#line 487 "bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +#ifdef YYLSP_NEEDED + yylsp -= yylen; +#endif + +#if YYDEBUG != 0 + if (yydebug) + { + short *ssp1 = yyss - 1; + fprintf (stderr, "state stack now"); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif + + *++yyvsp = yyval; + +#ifdef YYLSP_NEEDED + yylsp++; + if (yylen == 0) + { + yylsp->first_line = yylloc.first_line; + yylsp->first_column = yylloc.first_column; + yylsp->last_line = (yylsp-1)->last_line; + yylsp->last_column = (yylsp-1)->last_column; + yylsp->text = 0; + } + else + { + yylsp->last_line = (yylsp+yylen-1)->last_line; + yylsp->last_column = (yylsp+yylen-1)->last_column; + } +#endif + + /* Now "shift" the result of the reduction. + Determine what state that goes to, + based on the state we popped back to + and the rule number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTBASE] + *yyssp; + if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTBASE]; + + goto yynewstate; + +yyerrlab: /* here on detecting error */ + + if (! yyerrstatus) + /* If not already recovering from an error, report this error. */ + { + ++yynerrs; + +#ifdef YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (yyn > YYFLAG && yyn < YYLAST) + { + int size = 0; + char *msg; + int x, count; + + count = 0; + /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ + for (x = (yyn < 0 ? -yyn : 0); + x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) + size += strlen(yytname[x]) + 15, count++; + msg = (char *) malloc(size + 15); + if (msg != 0) + { + strcpy(msg, "parse error"); + + if (count < 5) + { + count = 0; + for (x = (yyn < 0 ? -yyn : 0); + x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) + { + strcat(msg, count == 0 ? ", expecting `" : " or `"); + strcat(msg, yytname[x]); + strcat(msg, "'"); + count++; + } + } + yyerror(msg); + free(msg); + } + else + yyerror ("parse error; also virtual memory exceeded"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror("parse error"); + } + + goto yyerrlab1; +yyerrlab1: /* here on error raised explicitly by an action */ + + if (yyerrstatus == 3) + { + /* if just tried and failed to reuse lookahead token after an error, discard it. */ + + /* return failure if at end of input */ + if (yychar == YYEOF) + YYABORT; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); +#endif + + yychar = YYEMPTY; + } + + /* Else will try to reuse lookahead token + after shifting the error token. */ + + yyerrstatus = 3; /* Each real token shifted decrements this */ + + goto yyerrhandle; + +yyerrdefault: /* current state does not do anything special for the error token. */ + +#if 0 + /* This is wrong; only states that explicitly want error tokens + should shift them. */ + yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ + if (yyn) goto yydefault; +#endif + +yyerrpop: /* pop the current state because it cannot handle the error token */ + + if (yyssp == yyss) YYABORT; + yyvsp--; + yystate = *--yyssp; +#ifdef YYLSP_NEEDED + yylsp--; +#endif + +#if YYDEBUG != 0 + if (yydebug) + { + short *ssp1 = yyss - 1; + fprintf (stderr, "Error: state stack now"); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif + +yyerrhandle: + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yyerrdefault; + + yyn += YYTERROR; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) + goto yyerrdefault; + + yyn = yytable[yyn]; + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrpop; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrpop; + + if (yyn == YYFINAL) + YYACCEPT; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Shifting error token, "); +#endif + + *++yyvsp = yylval; +#ifdef YYLSP_NEEDED + *++yylsp = yylloc; +#endif + + yystate = yyn; + goto yynewstate; +}