%{ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include "sal/config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include ObjectStack S; RscTop * pCurClass; sal_uInt32 nCurMask; char szErrBuf[ 100 ]; RSCINST GetVarInst( const RSCINST & rInst, const char * pVarName ) { RSCINST aInst; aInst = rInst.pClass->GetVariable( rInst, pHS->getID( pVarName ), RSCINST() ); if( !aInst.pData ) pTC->pEH->Error( ERR_NOVARIABLENAME, rInst.pClass, RscId() ); return aInst; } void SetNumber( const RSCINST & rInst, const char * pVarName, sal_Int32 lValue ) { RSCINST aInst; aInst = GetVarInst( rInst, pVarName ); if( aInst.pData ) { ERRTYPE aError; aError = aInst.pClass->SetNumber( aInst, lValue ); if( aError.IsError() ) pTC->pEH->Error( aError, aInst.pClass, RscId() ); } } void SetConst( const RSCINST & rInst, const char * pVarName, Atom nValueId, sal_Int32 nVal ) { RSCINST aInst; aInst = GetVarInst( rInst, pVarName ); if( aInst.pData ) { ERRTYPE aError; aError = aInst.pClass->SetConst( aInst, nValueId, nVal ); if( aError.IsError() ) pTC->pEH->Error( aError, aInst.pClass, RscId() ); } } void SetString( const RSCINST & rInst, const char * pVarName, const char * pStr ) { RSCINST aInst; aInst = GetVarInst( rInst, pVarName ); if( aInst.pData ){ ERRTYPE aError; aError = aInst.pClass->SetString( aInst, pStr ); if( aError.IsError() ) pTC->pEH->Error( aError, aInst.pClass, RscId() ); } } RscId MakeRscId( RscExpType aExpType ) { if( !aExpType.IsNothing() ) { sal_Int32 lValue(0); if( !aExpType.Evaluate( &lValue ) ) pTC->pEH->Error( ERR_ZERODIVISION, NULL, RscId() ); if( lValue < 1 || lValue > (sal_Int32)0x7FFF ) { pTC->pEH->Error( ERR_IDRANGE, NULL, RscId(), rtl::OString::number(lValue).getStr() ); } if( aExpType.IsDefinition() ) return RscId( aExpType.aExp.pDef ); else return RscId( lValue ); } return RscId(); } bool DoClassHeader( RSCHEADER * pHeader, bool bMember ) { RSCINST aCopyInst; RscId aName1 = MakeRscId( pHeader->nName1 ); RscId aName2 = MakeRscId( pHeader->nName2 ); if( pHeader->pRefClass ) aCopyInst.pClass = pHeader->pRefClass; else aCopyInst.pClass = pHeader->pClass; if( TYPE_COPY == pHeader->nTyp ) { ObjNode * pCopyObj = aCopyInst.pClass->GetObjNode( aName2 ); if( !pCopyObj ) { rtl::OStringBuffer aMsg( pHS->getString( aCopyInst.pClass->GetId() ) ); aMsg.append(' '); aMsg.append(aName2.GetName()); pTC->pEH->Error( ERR_NOCOPYOBJ, pHeader->pClass, aName1, aMsg.getStr() ); } else aCopyInst.pData = pCopyObj->GetRscObj(); } if( bMember ) { // Angabe von Superklassen oder abgeleiteten Klassen ist jetzt erlaubt if( S.Top().pClass->InHierarchy( pHeader->pClass ) || pHeader->pClass->InHierarchy( S.Top().pClass) ) { if( aCopyInst.IsInst() ) { RSCINST aTmpI( S.Top() ); aTmpI.pClass->Destroy( aTmpI ); aTmpI.pClass->Create( &aTmpI, aCopyInst ); } } else pTC->pEH->Error( ERR_FALSETYPE, S.Top().pClass, aName1, pHS->getString( pHeader->pClass->GetId() ).getStr() ); } else { if( S.IsEmpty() ) { if( (sal_Int32)aName1 < 256 ) pTC->pEH->Error( WRN_GLOBALID, pHeader->pClass, aName1 ); if( aCopyInst.IsInst() ) S.Push( pHeader->pClass->Create( NULL, aCopyInst ) ); else S.Push( pHeader->pClass->Create( NULL, RSCINST() ) ); pTC->pEH->StdOut( ".", RscVerbosityVerbose ); if( !aName1.IsId() ) pTC->pEH->Error( ERR_IDEXPECTED, pHeader->pClass, aName1 ); else { ObjNode * pNode = new ObjNode( aName1, S.Top().pData, pFI->GetFileIndex() ); if( !pHeader->pClass->PutObjNode( pNode ) ) pTC->pEH->Error( ERR_DOUBLEID, pHeader->pClass, aName1 ); } } else { RSCINST aTmpI; ERRTYPE aError; if( (sal_Int32)aName1 >= 256 && aName1.IsId() ) pTC->pEH->Error( WRN_LOCALID, pHeader->pClass, aName1 ); aError = S.Top().pClass->GetElement( S.Top(), aName1, pHeader->pClass, aCopyInst, &aTmpI ); if( aError.IsWarning() ) { pTC->pEH->Error( aError, pHeader->pClass, aName1 ); } else if( aError.IsError() ) { if( ERR_CONT_INVALIDTYPE == aError ) pTC->pEH->Error( aError, S.Top().pClass, aName1, pHS->getString( pHeader->pClass->GetId() ).getStr() ); else pTC->pEH->Error( aError, S.Top().pClass, aName1 ); S.Top().pClass->GetElement( S.Top(), RscId(), pHeader->pClass, RSCINST(), &aTmpI ); if( !aTmpI.IsInst() ) return false; } S.Push( aTmpI ); } } if( TYPE_REF == pHeader->nTyp ) { ERRTYPE aError; aError = S.Top().pClass->SetRef( S.Top(), aName2 ); pTC->pEH->Error( aError, S.Top().pClass, aName1 ); } return true ; } RSCINST GetFirstTupelEle( const RSCINST & rTop ) { // Aufwaertskompatible, Tupel probieren RSCINST aInst; ERRTYPE aErr; aErr = rTop.pClass->GetElement( rTop, RscId(), NULL, RSCINST(), &aInst ); if( !aErr.IsError() ) aInst = aInst.pClass->GetTupelVar( aInst, 0, RSCINST() ); return aInst; } //#define YYDEBUG 1 #ifdef UNX #define YYMAXDEPTH 2000 #else #define YYMAXDEPTH 800 #endif #if defined _MSC_VER #pragma warning(push, 1) #pragma warning(disable:4129 4273 4701 4702) #endif #ifdef __GNUC__ #pragma GCC diagnostic ignored "-Wwrite-strings" #endif %} /* Compilerstack */ %union { Atom varid; struct { Atom hashid; sal_Int32 nValue; } constname; RscTop * pClass; RSCHEADER header; struct { CLASS_DATA pData; RscTop * pClass; } instance; sal_Int32 value; sal_uInt16 ushort; short exp_short; char * string; bool svbool; REF_ENUM copyref; RscDefine * defineele; rtl_TextEncoding charset; RscExpType macrostruct; } /* Token */ %token NUMBER %token SYMBOL %token RSCDEFINE %token STRING %token INCLUDE_STRING %token CHARACTER %token BOOLEAN %token LINE %token AUTO_ID %token NOT %token XSCALE %token YSCALE %token RGB %token GEOMETRY %token POSITION %token DIMENSION %token INZOOMOUTPUTSIZE %token FLOATINGPOS %token DEFINE %token INCLUDE %token MACROTARGET %token DEFAULT %token CLASSNAME %token VARNAME %token CONSTNAME %token CLASS %token EXTENDABLE %token WRITEIFSET %type macro_expression %type id_expression %type long_expression %type string_multiline %type type %type type_base %type
class_header_body %type
class_header %type
var_header_class %type copy_ref %type type_flags %left '|' %left '&' %left LEFTSHIFT RIGHTSHIFT %left '+' '-' %left '*' '/' %left UNARYMINUS %left UNARYPLUS %left ',' %left '(' ')' /* Grammatik */ %start resource_definitions %% resource_definitions : | resource_definitions resource_definition | MACROTARGET macro_expression { RscExpType aExpType; sal_Int32 lValue; aExpType.cUnused = false; aExpType.cType = RSCEXP_NOTHING; pExp = new RscExpression( aExpType, '+', $2 ); if( !pExp->Evaluate( &lValue ) ) { pTC->pEH->Error( ERR_ZERODIVISION, NULL, RscId() ); } delete pExp; } ; resource_definition : line_number | '#' DEFINE SYMBOL macro_expression { bool bError = false; if( $4.IsNumber() ) { if( !pTC->aFileTab.NewDef( pFI->GetFileIndex(), rtl::OString( $3 ), $4.GetLong(), ULONG_MAX ) ) bError = true; } else if( $4.IsDefinition() ) { RscExpType aExpType; RscExpression * pExpr; aExpType.cUnused = false; aExpType.cType = RSCEXP_NOTHING; aExpType.SetLong( 0 ); aExpType.cType = RSCEXP_LONG; pExpr = new RscExpression( aExpType, '+', $4 ); if( !pTC->aFileTab.NewDef( pFI->GetFileIndex(), rtl::OString( $3 ), pExpr, ULONG_MAX ) ) { bError =true; } } else if( $4.IsExpression() ) { if( !pTC->aFileTab.NewDef( pFI->GetFileIndex(), rtl::OString( $3 ), $4.aExp.pExp, ULONG_MAX ) ) { bError = true; } } if( bError ) { pTC->pEH->Error( ERR_DECLAREDEFINE, NULL, RscId(), $3 ); } } | '#' DEFINE RSCDEFINE macro_expression { pTC->pEH->Error( ERR_DOUBLEDEFINE, NULL, RscId(), $3->GetName().getStr() ); } | '#' INCLUDE STRING { } | '#' INCLUDE INCLUDE_STRING { } | class_definition ';' { #ifdef D40 void * pMem; pMem = rtl_allocateMemory( 20000 ); rtl_freeMemory( pMem ); #endif } | new_class_definition_header '{' new_class_definition_body '}' ';' | new_class_definition_header ';' ; new_class_definition_header : CLASS SYMBOL id_expression ':' CLASSNAME { sal_Int32 lType; $3.Evaluate( &lType ); // Klasse anlegen Atom nId = pHS->getID( $2 ); pCurClass = new RscClass( nId, lType, $5 ); nCurMask = 1; pTC->aNmTb.Put( nId, CLASSNAME, pCurClass ); pTC->GetRoot()->Insert( pCurClass ); } | CLASS CLASSNAME id_expression ':' CLASSNAME { pCurClass = $2; nCurMask = 1; } ; new_class_definition_body : | property_definition ';' new_class_definition_body ; property_definition : type_flags type SYMBOL { // Variable anlegen Atom nId = pTC->aNmTb.Put( $3, VARNAME ); pCurClass->SetVariable( nId, $2, NULL, $1, nCurMask ); nCurMask <<= 1; } | type_flags type VARNAME { pCurClass->SetVariable( $3, $2, NULL, $1, nCurMask ); nCurMask <<= 1; } ; type_flags : type_flags EXTENDABLE { $$ = $1 | VAR_EXTENDABLE; } | type_flags WRITEIFSET { $$ = $1 | VAR_SVDYNAMIC; } | { $$ = 0; } ; type : type_base { $$ = $1; } | type_base '[' ']' { if( $1 ) { rtl::OString aTypeName = rtl::OStringBuffer(pHS->getString($1->GetId())). append("[]").makeStringAndClear(); $$ = pTC->SearchType( pHS->getID( aTypeName.getStr(), true ) ); if( !$$ ) { RscCont * pCont; pCont = new RscCont( pHS->getID( aTypeName.getStr() ), RSC_NOTYPE ); pCont->SetTypeClass( $1 ); pTC->InsertType( pCont ); $$ = pCont; } } else { $$ = NULL; } } ; type_base : CLASSNAME { $$ = $1; } | SYMBOL { RscTop * pType = pTC->SearchType( pHS->getID( $1, true ) ); if( !pType ) pTC->pEH->Error( ERR_NOTYPE, pCurClass, RscId() ); $$ = pType; } ; class_definition : class_header class_body { if( TYPE_REF == $1.nTyp ) { pTC->pEH->Error( ERR_REFNOTALLOWED, S.Top().pClass, RscId( $1.nName1 ) ); } S.Pop(); } | class_header { ERRTYPE aError; RscId aRscId( $1.nName1 ); if( TYPE_NOTHING == $1.nTyp && aRscId.IsId() ) aError = S.Top().pClass->SetRef( S.Top(), aRscId ); else if( TYPE_COPY == $1.nTyp ) aError = ERR_COPYNOTALLOWED; if( aError.IsError() || aError.IsWarning() ) pTC->pEH->Error( aError, S.Top().pClass, aRscId ); S.Pop(); } ; class_header : class_header_body { if( !DoClassHeader( &$1, false ) ) return ERR_ERROR; $$ = $1; } ; copy_ref : '<' { $$ = TYPE_COPY; } | ',' { $$ = TYPE_REF; } ; class_header_body : CLASSNAME id_expression copy_ref CLASSNAME id_expression { $$.pClass = $1; $$.nName1 = $2; $$.nTyp = $3; $$.pRefClass = $4; $$.nName2 = $5; } | CLASSNAME id_expression copy_ref id_expression { $$.pClass = $1; $$.nName1 = $2; $$.nTyp = $3; $$.pRefClass = NULL; $$.nName2 = $4; } | CLASSNAME id_expression { $$.pClass = $1; $$.nName1 = $2; $$.nTyp = TYPE_NOTHING; $$.pRefClass = NULL; $$.nName2.cType = RSCEXP_NOTHING; } | CLASSNAME copy_ref id_expression { $$.pClass = $1; $$.nName1.cType = RSCEXP_NOTHING; $$.nTyp = $2; $$.pRefClass = NULL; $$.nName2 = $3; } | CLASSNAME copy_ref CLASSNAME id_expression { $$.pClass = $1; $$.nName1.cType = RSCEXP_NOTHING; $$.nTyp = $2; $$.pRefClass = $3; $$.nName2 = $4; } | CLASSNAME { $$.pClass = $1; $$.nName1.cType = RSCEXP_NOTHING; $$.nTyp = TYPE_NOTHING; $$.nName2.cType = RSCEXP_NOTHING; } ; class_body : '{' var_definitions '}' | '{' '}' | string_multiline { SetString( S.Top(), "TEXT", $1 ); } ; var_definitions : var_definition | var_definitions var_definition ; xy_mapmode : CONSTNAME { SetConst( S.Top(), "_XYMAPMODE", $1.hashid, $1.nValue ); } | ; wh_mapmode : CONSTNAME { SetConst( S.Top(), "_WHMAPMODE", $1.hashid, $1.nValue ); } | ; xywh_mapmode : CONSTNAME { SetConst( S.Top(), "_XYMAPMODE", $1.hashid, $1.nValue ); SetConst( S.Top(), "_WHMAPMODE", $1.hashid, $1.nValue ); } | ; var_definition : line_number | var_header var_body ';' { S.Pop(); } | class_definition ';' | var_header_class class_body ';' { if( TYPE_REF == $1.nTyp ) pTC->pEH->Error( ERR_REFNOTALLOWED, S.Top().pClass, RscId( $1.nName1 ) ); if( S.Top().pClass->GetCount( S.Top() ) ) pTC->pEH->Error( WRN_SUBINMEMBER, S.Top().pClass, RscId( $1.nName1 ) ); S.Pop(); } | var_header_class ';' { ERRTYPE aError; RscId aRscId( $1.nName1 ); if( TYPE_NOTHING == $1.nTyp && aRscId.IsId() ) aError = S.Top().pClass->SetRef( S.Top(), aRscId ); else if( TYPE_COPY == $1.nTyp ) aError = ERR_COPYNOTALLOWED; if( S.Top().pClass->GetCount( S.Top() ) ) aError = WRN_SUBINMEMBER; if( aError.IsError() || aError.IsWarning() ) pTC->pEH->Error( aError, S.Top().pClass, aRscId ); S.Pop(); } | XSCALE '=' '(' long_expression ',' long_expression ')' ';' { SetNumber( S.Top(), "_XNUMERATOR", $4 ); SetNumber( S.Top(), "_XDENOMINATOR", $6 ); } | YSCALE '=' '(' long_expression ',' long_expression ')' ';' { SetNumber( S.Top(), "_YNUMERATOR", $4 ); SetNumber( S.Top(), "_YDENOMINATOR", $6 ); } | RGB '=' '(' long_expression ',' long_expression ',' long_expression ')' ';' { SetNumber( S.Top(), "RED", $4 ); SetNumber( S.Top(), "GREEN", $6 ); SetNumber( S.Top(), "BLUE", $8 ); } | GEOMETRY '=' xywh_mapmode '(' long_expression ',' long_expression ',' long_expression ',' long_expression ')' ';' { SetNumber( S.Top(), "_X", $5 ); SetNumber( S.Top(), "_Y", $7 ); SetNumber( S.Top(), "_WIDTH", $9 ); SetNumber( S.Top(), "_HEIGHT", $11 ); } | POSITION '=' xy_mapmode '(' long_expression ',' long_expression ')' ';' { SetNumber( S.Top(), "_X", $5 ); SetNumber( S.Top(), "_Y", $7 ); } | DIMENSION '=' wh_mapmode '(' long_expression ',' long_expression ')' ';' { SetNumber( S.Top(), "_WIDTH", $5 ); SetNumber( S.Top(), "_HEIGHT", $7 ); } | INZOOMOUTPUTSIZE '=' CONSTNAME '(' long_expression ',' long_expression ')' ';' { SetConst( S.Top(), "_ZOOMINMAPMODE", $3.hashid, $3.nValue ); SetNumber( S.Top(), "_ZOOMINWIDTH", $5 ); SetNumber( S.Top(), "_ZOOMINHEIGHT", $7 ); } | INZOOMOUTPUTSIZE '=' '(' long_expression ',' long_expression ')' ';' { SetNumber( S.Top(), "_ZOOMINWIDTH", $4 ); SetNumber( S.Top(), "_ZOOMINHEIGHT", $6 ); } | FLOATINGPOS '=' CONSTNAME '(' long_expression ',' long_expression ')' ';' { SetConst( S.Top(), "_FLOATINGPOSMAPMODE", $3.hashid, $3.nValue ); SetNumber( S.Top(), "_FLOATINGPOSX", $5 ); SetNumber( S.Top(), "_FLOATINGPOSY", $7 ); } | FLOATINGPOS '=' '(' long_expression ',' long_expression ')' ';' { SetNumber( S.Top(), "_FLOATINGPOSX", $4 ); SetNumber( S.Top(), "_FLOATINGPOSY", $6 ); } ; var_header_class : VARNAME '=' class_header_body { RSCINST aInst; aInst = S.Top().pClass->GetVariable( S.Top(), $1, RSCINST(), false, $3.pClass ); if( aInst.pData ) S.Push( aInst ); else { pTC->pEH->Error( ERR_NOVARIABLENAME, S.Top().pClass, RscId(), pHS->getString( $1 ).getStr() ); return ERR_ERROR; } if( !DoClassHeader( &$3, true ) ) return ERR_ERROR; $$ = $3; } | VARNAME '[' CONSTNAME ']' '=' class_header_body { RSCINST aInst; aInst = S.Top().pClass->GetVariable( S.Top(), $1, RSCINST() ); if( aInst.pData ) { ERRTYPE aError; RSCINST aIdxInst; aError = aInst.pClass->GetArrayEle( aInst, $3.hashid, NULL, &aIdxInst ); if( aError.IsError() || aError.IsWarning() ) pTC->pEH->Error( aError, S.Top().pClass, RscId() ); if( aError.IsError() ) return ERR_ERROR; S.Push( aIdxInst ); } else { pTC->pEH->Error( ERR_NOVARIABLENAME, S.Top().pClass, RscId(), pHS->getString( $1 ).getStr() ); return ERR_ERROR; } if( !DoClassHeader( &$6, true ) ) return ERR_ERROR; $$ = $6; } | VARNAME '[' SYMBOL ']' '=' class_header_body { RSCINST aInst; aInst = S.Top().pClass->GetVariable( S.Top(), $1, RSCINST() ); if( aInst.pData ) { long nNewLang = pTC->AddLanguage( $3 ); ERRTYPE aError; RSCINST aIdxInst; aError = aInst.pClass->GetArrayEle( aInst, nNewLang, NULL, &aIdxInst ); if( aError.IsError() || aError.IsWarning() ) pTC->pEH->Error( aError, S.Top().pClass, RscId() ); if( aError.IsError() ) return ERR_ERROR; S.Push( aIdxInst ); } else { pTC->pEH->Error( ERR_NOVARIABLENAME, S.Top().pClass, RscId(), pHS->getString( $1 ).getStr() ); return ERR_ERROR; } if( !DoClassHeader( &$6, true ) ) return ERR_ERROR; $$ = $6; } ; var_header : VARNAME '=' { RSCINST aInst; aInst = S.Top().pClass->GetVariable( S.Top(), $1, RSCINST() ); if( aInst.pData ) S.Push( aInst ); else { pTC->pEH->Error( ERR_NOVARIABLENAME, S.Top().pClass, RscId(), pHS->getString( $1 ).getStr() ); return ERR_ERROR; } } | VARNAME '[' CONSTNAME ']' '=' { RSCINST aInst; aInst = S.Top().pClass->GetVariable( S.Top(), $1, RSCINST() ); if( aInst.pData ) { ERRTYPE aError; RSCINST aIdxInst; aError = aInst.pClass->GetArrayEle( aInst, $3.hashid, NULL, &aIdxInst ); if( aError.IsError() || aError.IsWarning() ) pTC->pEH->Error( aError, S.Top().pClass, RscId() ); if( aError.IsError() ) return ERR_ERROR; S.Push( aIdxInst ); } else { pTC->pEH->Error( ERR_NOVARIABLENAME, S.Top().pClass, RscId(), pHS->getString( $1 ).getStr() ); return ERR_ERROR; } } | VARNAME '[' SYMBOL ']' '=' { RSCINST aInst; aInst = S.Top().pClass->GetVariable( S.Top(), $1, RSCINST() ); if( aInst.pData ) { long nNewLang = pTC->AddLanguage( $3 ); ERRTYPE aError; RSCINST aIdxInst; aError = aInst.pClass->GetArrayEle( aInst, nNewLang, NULL, &aIdxInst ); if( aError.IsError() || aError.IsWarning() ) pTC->pEH->Error( aError, S.Top().pClass, RscId() ); if( aError.IsError() ) return ERR_ERROR; S.Push( aIdxInst ); } else { pTC->pEH->Error( ERR_NOVARIABLENAME, S.Top().pClass, RscId(), pHS->getString( $1 ).getStr() ); return ERR_ERROR; } } ; tupel_header0 : { RSCINST aInst; aInst = S.Top().pClass->GetTupelVar( S.Top(), 0, RSCINST() ); if( aInst.pData ) S.Push( aInst ); else { pTC->pEH->Error( ERR_NOTUPELNAME, S.Top().pClass, RscId() ); return ERR_ERROR; } } ; tupel_header1 : { RSCINST aInst; aInst = S.Top().pClass->GetTupelVar( S.Top(), 1, RSCINST() ); if( aInst.pData ) S.Push( aInst ); else { pTC->pEH->Error( ERR_NOTUPELNAME, S.Top().pClass, RscId() ); return ERR_ERROR; } } ; tupel_header2 : { RSCINST aInst; aInst = S.Top().pClass->GetTupelVar( S.Top(), 2, RSCINST() ); if( aInst.pData ) S.Push( aInst ); else { pTC->pEH->Error( ERR_NOTUPELNAME, S.Top().pClass, RscId() ); return ERR_ERROR; } } ; tupel_header3 : { RSCINST aInst; aInst = S.Top().pClass->GetTupelVar( S.Top(), 3, RSCINST() ); if( !aInst.pData ) { pTC->pEH->Error( ERR_NOTUPELNAME, S.Top().pClass, RscId() ); return ERR_ERROR; } S.Push( aInst ); } ; tupel_body : var_body { S.Pop(); } ; var_list_header : { ERRTYPE aError; RSCINST aInst; aError = S.Top().pClass->GetElement( S.Top(), RscId(), NULL, RSCINST(), &aInst ); if( aError.IsError() || aError.IsWarning() ) pTC->pEH->Error( aError, S.Top().pClass, RscId() ); if( aError.IsError() ) { // unbedingt Instanz auf den Stack bringen aInst = S.Top().pClass->Create( NULL, RSCINST() ); } S.Push( aInst ); } ; list_body : var_bodycomplex { S.Pop(); } ; list_header : { sal_uInt32 nCount = S.Top().pClass->GetCount( S.Top() ); sal_uInt32 i; for( i = nCount; i > 0; i-- ) S.Top().pClass->DeletePos( S.Top(), i -1 ); } ; list : list var_list_header list_body ';' | list var_bodysimple ';' | list class_definition ';' | list line_number | ; var_bodysimple : macro_expression { sal_Int32 l; ERRTYPE aError; if( !$1.Evaluate( &l ) ) pTC->pEH->Error( ERR_ZERODIVISION, NULL, RscId() ); else { aError = S.Top().pClass->SetRef( S.Top(), RscId( $1 ) ); if( aError.IsError() ) { aError.Clear(); aError = S.Top().pClass->SetNumber( S.Top(), l ); } if( aError.IsError() ) { // Aufwaertskompatible, Tupel probieren RSCINST aInst = GetFirstTupelEle( S.Top() ); if( aInst.pData ) { aError.Clear(); // Fehler zuruecksetzen aError = aInst.pClass->SetRef( aInst, RscId( $1 ) ); if( aError.IsError() ) { aError.Clear(); aError = aInst.pClass->SetNumber( aInst, l ); } } } } if( $1.IsExpression() ) delete $1.aExp.pExp; if( aError.IsError() || aError.IsWarning() ) pTC->pEH->Error( aError, S.Top().pClass, RscId() ); } | CONSTNAME { ERRTYPE aError; aError = S.Top().pClass->SetConst( S.Top(), $1.hashid, $1.nValue ); if( aError.IsError() ) { // Aufwaertskompatible, Tupel probieren RSCINST aInst = GetFirstTupelEle( S.Top() ); if( aInst.pData ) { aError.Clear(); // Fehler zuruecksetzen aError = aInst.pClass->SetConst( aInst, $1.hashid, $1.nValue ); } } if( aError.IsError() || aError.IsWarning() ) pTC->pEH->Error( aError, S.Top().pClass, RscId() ); } | NOT CONSTNAME { ERRTYPE aError; aError = S.Top().pClass->SetNotConst( S.Top(), $2.hashid ); if( aError.IsError() ) { // Aufwaertskompatible, Tupel probieren RSCINST aInst = GetFirstTupelEle( S.Top() ); if( aInst.pData ) { aError.Clear(); // Fehler zuruecksetzen aError = aInst.pClass->SetNotConst( aInst, $2.hashid ); } } if( aError.IsError() || aError.IsWarning() ) pTC->pEH->Error( aError, S.Top().pClass, RscId() ); } | BOOLEAN { ERRTYPE aError; aError = S.Top().pClass->SetBool( S.Top(), $1 ); if( aError.IsError() ) { // Aufwaertskompatible, Tupel probieren RSCINST aInst = GetFirstTupelEle( S.Top() ); if( aInst.pData ) { aError.Clear(); // Fehler zuruecksetzen aError = aInst.pClass->SetBool( aInst, $1 ); } } if( aError.IsError() || aError.IsWarning() ) pTC->pEH->Error( aError, S.Top().pClass, RscId() ); } | string_multiline { ERRTYPE aError; aError = S.Top().pClass->SetString( S.Top(), $1 ); if( aError.IsError() ) { // Aufwaertskompatible, Tupel probieren RSCINST aInst = GetFirstTupelEle( S.Top() ); if( aInst.pData ) { aError.Clear(); // Fehler zuruecksetzen aError = aInst.pClass->SetString( aInst, $1 ); } } if( aError.IsError() || aError.IsWarning() ) pTC->pEH->Error( aError, S.Top().pClass, RscId() ); } | DEFAULT ; var_bodycomplex : '{' list_header list '}' | '<' tupel_header0 tupel_body ';' '>' | '<' tupel_header0 tupel_body ';' tupel_header1 tupel_body ';' '>' | '<' tupel_header0 tupel_body ';' tupel_header1 tupel_body ';' tupel_header2 tupel_body ';' '>' | '<' tupel_header0 tupel_body ';' tupel_header1 tupel_body ';' tupel_header2 tupel_body ';' tupel_header3 tupel_body ';' '>' ; var_body : var_bodysimple | var_bodycomplex ; string_multiline : STRING { $$ = $1; } | string_multiline STRING { rtl::OStringBuffer aBuf( 256 ); aBuf.append( $1 ); aBuf.append( $2 ); $$ = (char*)pStringContainer->putString( aBuf.getStr() ); } ; long_expression : macro_expression { if( !$1.Evaluate( &$$ ) ) pTC->pEH->Error( ERR_ZERODIVISION, NULL, RscId() ); if( $1.IsExpression() ) delete $1.aExp.pExp; } ; macro_expression : RSCDEFINE { $$.cType = RSCEXP_DEF; $$.aExp.pDef = $1; } | NUMBER { $$.cType = RSCEXP_LONG; $$.SetLong( $1 ); } | '-' macro_expression %prec UNARYMINUS { if( $2.IsNumber() ){ $$.cType = $2.cType; $$.SetLong( - $2.GetLong() ); } else { RscExpType aLeftExp; aLeftExp.cType = RSCEXP_NOTHING; $$.cType = RSCEXP_EXP; $$.aExp.pExp = new RscExpression( aLeftExp, '-', $2 ); } } | '+' macro_expression %prec UNARYPLUS { $$ = $2; } | macro_expression '+' macro_expression { if( $1.IsNumber() && $3.IsNumber() ) { $$.cType = RSCEXP_LONG; $$.SetLong( $1.GetLong() + $3.GetLong() ); } else { $$.cType = RSCEXP_EXP; $$.aExp.pExp = new RscExpression( $1, '+', $3 ); } } | macro_expression '-' macro_expression { if( $1.IsNumber() && $3.IsNumber() ) { $$.cType = RSCEXP_LONG; $$.SetLong( $1.GetLong() - $3.GetLong() ); } else { $$.cType = RSCEXP_EXP; $$.aExp.pExp = new RscExpression( $1, '-', $3 ); } } | macro_expression '*' macro_expression { if( $1.IsNumber() && $3.IsNumber() ) { $$.cType = RSCEXP_LONG; $$.SetLong( $1.GetLong() * $3.GetLong() ); } else { $$.cType = RSCEXP_EXP; $$.aExp.pExp = new RscExpression( $1, '*', $3 ); } } | macro_expression '/' macro_expression { if( $1.IsNumber() && $3.IsNumber() ) { if( 0 == $3.GetLong() ) { $$.cType = RSCEXP_EXP; $$.aExp.pExp = new RscExpression( $1, '/', $3 ); } else { $$.cType = RSCEXP_LONG; $$.SetLong( $1.GetLong() / $3.GetLong() ); } } else { $$.cType = RSCEXP_EXP; $$.aExp.pExp = new RscExpression( $1, '/', $3 ); } } | macro_expression '&' macro_expression { if( $1.IsNumber() && $3.IsNumber() ) { $$.cType = RSCEXP_LONG; $$.SetLong( $1.GetLong() & $3.GetLong() ); } else { $$.cType = RSCEXP_EXP; $$.aExp.pExp = new RscExpression( $1, '&', $3 ); } } | macro_expression '|' macro_expression { if( $1.IsNumber() && $3.IsNumber() ) { $$.cType = RSCEXP_LONG; $$.SetLong( $1.GetLong() | $3.GetLong() ); } else { $$.cType = RSCEXP_EXP; $$.aExp.pExp = new RscExpression( $1, '|', $3 ); } } | '(' macro_expression ')' { $$ = $2; } | macro_expression LEFTSHIFT macro_expression { if( $1.IsNumber() && $3.IsNumber() ) { $$.cType = RSCEXP_LONG; $$.SetLong( $1.GetLong() << $3.GetLong() ); } else { $$.cType = RSCEXP_EXP; $$.aExp.pExp = new RscExpression( $1, 'l', $3 ); } } | macro_expression RIGHTSHIFT macro_expression { if( $1.IsNumber() && $3.IsNumber() ) { $$.cType = RSCEXP_LONG; $$.SetLong( $1.GetLong() >> $3.GetLong() ); } else { $$.cType = RSCEXP_EXP; $$.aExp.pExp = new RscExpression( $1, 'r', $3 ); } } ; id_expression : id_expression line_number | macro_expression { // pExpession auswerten und loeschen if( RSCEXP_EXP == $1.cType ) { sal_Int32 lValue; if( !$1.Evaluate( &lValue ) ) pTC->pEH->Error( ERR_ZERODIVISION, NULL, RscId() ); delete $1.aExp.pExp; $$.cType = RSCEXP_LONG; $$.SetLong( lValue ); } else { $$ = $1; } } ; DUMMY_NUMBER : NUMBER { } | { } ; line_number : '#' LINE NUMBER STRING { RscFile * pFName; pFI->SetLineNo( $3 ); pFI->SetFileIndex( pTC->aFileTab.NewCodeFile( rtl::OString( $4 ) ) ); pFName = pTC->aFileTab.Get( pFI->GetFileIndex() ); pFName->bLoaded = true; pFName->bScanned = true; } | '#' NUMBER STRING DUMMY_NUMBER { RscFile * pFName; pFI->SetLineNo( $2 ); pFI->SetFileIndex( pTC->aFileTab.NewCodeFile( rtl::OString( $3 ) ) ); pFName = pTC->aFileTab.Get( pFI->GetFileIndex() ); pFName->bLoaded = true; pFName->bScanned = true; } | '#' NUMBER { pFI->SetLineNo( $2 ); } ; %% #if defined _MSC_VER #pragma warning(pop) #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */