blob: 4d01f395d522788cff43363db8103f21a00e9322 [file] [log] [blame]
/**************************************************************
*
* 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
%{
#if defined __GNUC__
#pragma GCC system_header
#elif defined __SUNPRO_CC
#pragma disable_warn
#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;
sal_Bool svbool;
REF_ENUM copyref;
RscDefine * defineele;
CharSet charset;
RscExpType macrostruct;
}
/* Token */
%token <value> NUMBER
%token <string> SYMBOL
%token <defineele> RSCDEFINE
%token <string> STRING
%token <string> INCLUDE_STRING
%token <character> CHARACTER
%token <svbool> 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 <pClass> CLASSNAME
%token <varid> VARNAME
%token <constname> CONSTNAME
%token CLASS
%token EXTENDABLE
%token WRITEIFSET
%type <macrostruct> macro_expression
%type <macrostruct> id_expression
%type <value> long_expression
%type <string> string_multiline
%type <pClass> type
%type <pClass> type_base
%type <header> class_header_body
%type <header> class_header
%type <header> var_header_class
%type <copyref> copy_ref
%type <ushort> type_flags
%left '|'
%left '&'
%left LEFTSHIFT RIGHTSHIFT
%left '+' '-'
%left '*' '/'
%left UNARYMINUS
%left UNARYPLUS
%left ','
%left '(' ')'
/* Grammatik */
%start resource_definitions
%%
/********************** D E F I N I T I O N S ****************************/
resource_definitions
:
| resource_definitions resource_definition
| MACROTARGET macro_expression
{
RscExpType aExpType;
sal_Int32 lValue;
aExpType.cType = RSCEXP_NOTHING;
pExp = new RscExpression( aExpType, '+', $2 );
if( !pExp->Evaluate( &lValue ) )
pTC->pEH->Error( ERR_ZERODIVISION, NULL, RscId() );
}
;
resource_definition
: line_number
| '#' DEFINE SYMBOL macro_expression
{
sal_Bool bError = sal_False;
if( $4.IsNumber() ){
if( !pTC->aFileTab.NewDef( pFI->GetFileIndex(),
ByteString( $3 ),
$4.GetLong(), LIST_APPEND ) )
bError = sal_True;
}
else if( $4.IsDefinition() ){
RscExpType aExpType;
RscExpression * pExpr;
aExpType.cType = RSCEXP_NOTHING;
aExpType.SetLong( 0 );
aExpType.cType = RSCEXP_LONG;
pExpr = new RscExpression( aExpType, '+', $4 );
if( !pTC->aFileTab.NewDef( pFI->GetFileIndex(),
ByteString( $3 ), pExpr, LIST_APPEND ) )
bError = sal_True;
}
else if( $4.IsExpression() ){
if( !pTC->aFileTab.NewDef( pFI->GetFileIndex(),
ByteString( $3 ), $4.aExp.pExp,
LIST_APPEND ) )
bError = sal_True;
}
if( bError ){
pTC->pEH->Error( ERR_DECLAREDEFINE, NULL, RscId(), $3 );
}
}
| '#' DEFINE RSCDEFINE macro_expression
{
pTC->pEH->Error( ERR_DOUBLEDEFINE, NULL, RscId(), $3->GetName().GetBuffer() );
}
| '#' 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 )
{
ByteString aTypeName = pHS->getString( $1->GetId() );
aTypeName += "[]";
$$ = pTC->SearchType( pHS->getID( aTypeName.GetBuffer(), true ) );
if( !$$ )
{
RscCont * pCont;
pCont = new RscCont( pHS->getID( aTypeName.GetBuffer() ), 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, sal_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(), sal_False, $3.pClass );
if( aInst.pData )
S.Push( aInst );
else
{
pTC->pEH->Error( ERR_NOVARIABLENAME, S.Top().pClass, RscId(),
pHS->getString( $1 ) );
return( ERR_ERROR );
};
if( !DoClassHeader( &$3, sal_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 ) );
return( ERR_ERROR );
};
if( !DoClassHeader( &$6, sal_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 ) );
return( ERR_ERROR );
};
if( !DoClassHeader( &$6, sal_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 ) );
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 ) );
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 ) );
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
;
/********************** work on yacc stack *******************************/
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( ByteString( $4 ) ) );
pFName = pTC->aFileTab.Get( pFI->GetFileIndex() );
pFName->bLoaded = sal_True;
pFName->bScanned = sal_True;
}
| '#' NUMBER STRING DUMMY_NUMBER
{
RscFile * pFName;
pFI->SetLineNo( $2 );
pFI->SetFileIndex( pTC->aFileTab.NewCodeFile( ByteString( $3 ) ) );
pFName = pTC->aFileTab.Get( pFI->GetFileIndex() );
pFName->bLoaded = sal_True;
pFName->bScanned = sal_True;
}
| '#' NUMBER
{
pFI->SetLineNo( $2 );
}
;