1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_basic.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include "sbcomp.hxx" 32*cdf0e10cSrcweir #include <basic/sbx.hxx> // w.g. ...IMPL_REF(...sbxvariable) 33*cdf0e10cSrcweir #include "expr.hxx" 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir /*************************************************************************** 36*cdf0e10cSrcweir |* 37*cdf0e10cSrcweir |* SbiExpression 38*cdf0e10cSrcweir |* 39*cdf0e10cSrcweir ***************************************************************************/ 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir SbiExpression::SbiExpression( SbiParser* p, SbiExprType t, 42*cdf0e10cSrcweir SbiExprMode eMode, const KeywordSymbolInfo* pKeywordSymbolInfo ) 43*cdf0e10cSrcweir { 44*cdf0e10cSrcweir pParser = p; 45*cdf0e10cSrcweir bError = bByVal = bBased = bBracket = sal_False; 46*cdf0e10cSrcweir nParenLevel = 0; 47*cdf0e10cSrcweir eCurExpr = t; 48*cdf0e10cSrcweir m_eMode = eMode; 49*cdf0e10cSrcweir pNext = NULL; 50*cdf0e10cSrcweir pExpr = (t != SbSTDEXPR ) ? Term( pKeywordSymbolInfo ) : Boolean(); 51*cdf0e10cSrcweir if( t != SbSYMBOL ) 52*cdf0e10cSrcweir pExpr->Optimize(); 53*cdf0e10cSrcweir if( t == SbLVALUE && !pExpr->IsLvalue() ) 54*cdf0e10cSrcweir p->Error( SbERR_LVALUE_EXPECTED ); 55*cdf0e10cSrcweir if( t == SbOPERAND && !IsVariable() ) 56*cdf0e10cSrcweir p->Error( SbERR_VAR_EXPECTED ); 57*cdf0e10cSrcweir } 58*cdf0e10cSrcweir 59*cdf0e10cSrcweir SbiExpression::SbiExpression( SbiParser* p, double n, SbxDataType t ) 60*cdf0e10cSrcweir { 61*cdf0e10cSrcweir pParser = p; 62*cdf0e10cSrcweir eCurExpr = SbOPERAND; 63*cdf0e10cSrcweir pNext = NULL; 64*cdf0e10cSrcweir bError = bByVal = bBased = bBracket = sal_False; 65*cdf0e10cSrcweir pExpr = new SbiExprNode( pParser, n, t ); 66*cdf0e10cSrcweir pExpr->Optimize(); 67*cdf0e10cSrcweir } 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir SbiExpression::SbiExpression( SbiParser* p, const String& r ) 70*cdf0e10cSrcweir { 71*cdf0e10cSrcweir pParser = p; 72*cdf0e10cSrcweir pNext = NULL; 73*cdf0e10cSrcweir bError = bByVal = bBased = bBracket = sal_False; 74*cdf0e10cSrcweir eCurExpr = SbOPERAND; 75*cdf0e10cSrcweir pExpr = new SbiExprNode( pParser, r ); 76*cdf0e10cSrcweir } 77*cdf0e10cSrcweir 78*cdf0e10cSrcweir SbiExpression::SbiExpression( SbiParser* p, const SbiSymDef& r, SbiExprList* pPar ) 79*cdf0e10cSrcweir { 80*cdf0e10cSrcweir pParser = p; 81*cdf0e10cSrcweir pNext = NULL; 82*cdf0e10cSrcweir bError = bByVal = bBased = bBracket = sal_False; 83*cdf0e10cSrcweir eCurExpr = SbOPERAND; 84*cdf0e10cSrcweir pExpr = new SbiExprNode( pParser, r, SbxVARIANT, pPar ); 85*cdf0e10cSrcweir } 86*cdf0e10cSrcweir 87*cdf0e10cSrcweir SbiExpression::SbiExpression( SbiParser* p, SbiToken t ) 88*cdf0e10cSrcweir { 89*cdf0e10cSrcweir pParser = p; 90*cdf0e10cSrcweir pNext = NULL; 91*cdf0e10cSrcweir bError = bByVal = bBased = bBracket = sal_False; 92*cdf0e10cSrcweir eCurExpr = SbOPERAND; 93*cdf0e10cSrcweir pExpr = new SbiExprNode( pParser, NULL, t, NULL ); 94*cdf0e10cSrcweir } 95*cdf0e10cSrcweir 96*cdf0e10cSrcweir SbiExpression::~SbiExpression() 97*cdf0e10cSrcweir { 98*cdf0e10cSrcweir delete pExpr; 99*cdf0e10cSrcweir } 100*cdf0e10cSrcweir 101*cdf0e10cSrcweir // Einlesen eines kompletten Bezeichners 102*cdf0e10cSrcweir // Ein Bezeichner hat folgende Form: 103*cdf0e10cSrcweir // name[(Parameter)][.Name[(parameter)]]... 104*cdf0e10cSrcweir // Strukturelemente werden ueber das Element pNext verkoppelt, 105*cdf0e10cSrcweir // damit sie nicht im Baum stehen. 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir // Folgen Parameter ohne Klammer? Dies kann eine Zahl, ein String, 108*cdf0e10cSrcweir // ein Symbol oder auch ein Komma sein (wenn der 1. Parameter fehlt) 109*cdf0e10cSrcweir 110*cdf0e10cSrcweir static sal_Bool DoParametersFollow( SbiParser* p, SbiExprType eCurExpr, SbiToken eTok ) 111*cdf0e10cSrcweir { 112*cdf0e10cSrcweir if( eTok == LPAREN ) 113*cdf0e10cSrcweir return sal_True; 114*cdf0e10cSrcweir // Aber nur, wenn CALL-aehnlich! 115*cdf0e10cSrcweir if( !p->WhiteSpace() || eCurExpr != SbSYMBOL ) 116*cdf0e10cSrcweir return sal_False; 117*cdf0e10cSrcweir if ( eTok == NUMBER || eTok == MINUS || eTok == FIXSTRING 118*cdf0e10cSrcweir || eTok == SYMBOL || eTok == COMMA || eTok == DOT || eTok == NOT || eTok == BYVAL ) 119*cdf0e10cSrcweir { 120*cdf0e10cSrcweir return sal_True; 121*cdf0e10cSrcweir } 122*cdf0e10cSrcweir else // check for default params with reserved names ( e.g. names of tokens ) 123*cdf0e10cSrcweir { 124*cdf0e10cSrcweir SbiTokenizer tokens( *(SbiTokenizer*)p ); 125*cdf0e10cSrcweir // Urk the Next() / Peek() symantics are... weird 126*cdf0e10cSrcweir tokens.Next(); 127*cdf0e10cSrcweir if ( tokens.Peek() == ASSIGN ) 128*cdf0e10cSrcweir return sal_True; 129*cdf0e10cSrcweir } 130*cdf0e10cSrcweir return sal_False; 131*cdf0e10cSrcweir } 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir // Definition eines neuen Symbols 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir static SbiSymDef* AddSym 136*cdf0e10cSrcweir ( SbiToken eTok, SbiSymPool& rPool, SbiExprType eCurExpr, 137*cdf0e10cSrcweir const String& rName, SbxDataType eType, SbiParameters* pPar ) 138*cdf0e10cSrcweir { 139*cdf0e10cSrcweir SbiSymDef* pDef; 140*cdf0e10cSrcweir // A= ist keine Prozedur 141*cdf0e10cSrcweir sal_Bool bHasType = sal_Bool( eTok == EQ || eTok == DOT ); 142*cdf0e10cSrcweir if( ( !bHasType && eCurExpr == SbSYMBOL ) || pPar ) 143*cdf0e10cSrcweir { 144*cdf0e10cSrcweir // Dies ist also eine Prozedur 145*cdf0e10cSrcweir // da suche man doch den richtigen Pool raus, da Procs 146*cdf0e10cSrcweir // immer in einem Public-Pool landen muessen 147*cdf0e10cSrcweir SbiSymPool* pPool = &rPool; 148*cdf0e10cSrcweir if( pPool->GetScope() != SbPUBLIC ) 149*cdf0e10cSrcweir pPool = &rPool.GetParser()->aPublics; 150*cdf0e10cSrcweir SbiProcDef* pProc = pPool->AddProc( rName ); 151*cdf0e10cSrcweir 152*cdf0e10cSrcweir // Sonderbehandlung fuer Colls wie Documents(1) 153*cdf0e10cSrcweir if( eCurExpr == SbSTDEXPR ) 154*cdf0e10cSrcweir bHasType = sal_True; 155*cdf0e10cSrcweir 156*cdf0e10cSrcweir pDef = pProc; 157*cdf0e10cSrcweir pDef->SetType( bHasType ? eType : SbxEMPTY ); 158*cdf0e10cSrcweir if( pPar ) 159*cdf0e10cSrcweir { 160*cdf0e10cSrcweir // Dummy-Parameter generieren 161*cdf0e10cSrcweir sal_uInt16 n = 1; 162*cdf0e10cSrcweir for( short i = 0; i < pPar->GetSize(); i++ ) 163*cdf0e10cSrcweir { 164*cdf0e10cSrcweir String aPar = String::CreateFromAscii( "PAR" ); 165*cdf0e10cSrcweir aPar += ++n; 166*cdf0e10cSrcweir pProc->GetParams().AddSym( aPar ); 167*cdf0e10cSrcweir } 168*cdf0e10cSrcweir } 169*cdf0e10cSrcweir } 170*cdf0e10cSrcweir else 171*cdf0e10cSrcweir { 172*cdf0e10cSrcweir // oder ein normales Symbol 173*cdf0e10cSrcweir pDef = rPool.AddSym( rName ); 174*cdf0e10cSrcweir pDef->SetType( eType ); 175*cdf0e10cSrcweir } 176*cdf0e10cSrcweir return pDef; 177*cdf0e10cSrcweir } 178*cdf0e10cSrcweir 179*cdf0e10cSrcweir // Zur Zeit sind sogar Keywords zugelassen (wg. gleichnamiger Dflt-Properties) 180*cdf0e10cSrcweir 181*cdf0e10cSrcweir SbiExprNode* SbiExpression::Term( const KeywordSymbolInfo* pKeywordSymbolInfo ) 182*cdf0e10cSrcweir { 183*cdf0e10cSrcweir if( pParser->Peek() == DOT ) 184*cdf0e10cSrcweir { 185*cdf0e10cSrcweir // eine WITH-Variable 186*cdf0e10cSrcweir SbiExprNode* pWithVar = pParser->GetWithVar(); 187*cdf0e10cSrcweir // #26608: Ans Ende der Node-Kette gehen, um richtiges Objekt zu uebergeben 188*cdf0e10cSrcweir SbiSymDef* pDef = pWithVar ? pWithVar->GetRealVar() : NULL; 189*cdf0e10cSrcweir SbiExprNode* pNd = NULL; 190*cdf0e10cSrcweir if( !pDef ) 191*cdf0e10cSrcweir { 192*cdf0e10cSrcweir pParser->Next(); 193*cdf0e10cSrcweir } 194*cdf0e10cSrcweir else 195*cdf0e10cSrcweir { 196*cdf0e10cSrcweir pNd = ObjTerm( *pDef ); 197*cdf0e10cSrcweir if( pNd ) 198*cdf0e10cSrcweir pNd->SetWithParent( pWithVar ); 199*cdf0e10cSrcweir } 200*cdf0e10cSrcweir if( !pNd ) 201*cdf0e10cSrcweir { 202*cdf0e10cSrcweir pParser->Error( SbERR_UNEXPECTED, DOT ); 203*cdf0e10cSrcweir pNd = new SbiExprNode( pParser, 1.0, SbxDOUBLE ); 204*cdf0e10cSrcweir } 205*cdf0e10cSrcweir return pNd; 206*cdf0e10cSrcweir } 207*cdf0e10cSrcweir 208*cdf0e10cSrcweir SbiToken eTok = (pKeywordSymbolInfo == NULL) ? pParser->Next() : pKeywordSymbolInfo->m_eTok; 209*cdf0e10cSrcweir // Anfang des Parsings merken 210*cdf0e10cSrcweir pParser->LockColumn(); 211*cdf0e10cSrcweir String aSym( (pKeywordSymbolInfo == NULL) ? pParser->GetSym() : pKeywordSymbolInfo->m_aKeywordSymbol ); 212*cdf0e10cSrcweir SbxDataType eType = (pKeywordSymbolInfo == NULL) ? pParser->GetType() : pKeywordSymbolInfo->m_eSbxDataType; 213*cdf0e10cSrcweir SbiParameters* pPar = NULL; 214*cdf0e10cSrcweir SbiExprListVector* pvMoreParLcl = NULL; 215*cdf0e10cSrcweir // Folgen Parameter? 216*cdf0e10cSrcweir SbiToken eNextTok = pParser->Peek(); 217*cdf0e10cSrcweir // Ist es ein benannter Parameter? 218*cdf0e10cSrcweir // Dann einfach eine Stringkonstante erzeugen. Diese wird 219*cdf0e10cSrcweir // im SbiParameters-ctor erkannt und weiterverarbeitet 220*cdf0e10cSrcweir if( eNextTok == ASSIGN ) 221*cdf0e10cSrcweir { 222*cdf0e10cSrcweir pParser->UnlockColumn(); 223*cdf0e10cSrcweir return new SbiExprNode( pParser, aSym ); 224*cdf0e10cSrcweir } 225*cdf0e10cSrcweir // ab hier sind keine Keywords zugelassen! 226*cdf0e10cSrcweir if( pParser->IsKwd( eTok ) ) 227*cdf0e10cSrcweir { 228*cdf0e10cSrcweir if( pParser->IsCompatible() && eTok == INPUT ) 229*cdf0e10cSrcweir { 230*cdf0e10cSrcweir eTok = SYMBOL; 231*cdf0e10cSrcweir } 232*cdf0e10cSrcweir else 233*cdf0e10cSrcweir { 234*cdf0e10cSrcweir pParser->Error( SbERR_SYNTAX ); 235*cdf0e10cSrcweir bError = sal_True; 236*cdf0e10cSrcweir } 237*cdf0e10cSrcweir } 238*cdf0e10cSrcweir 239*cdf0e10cSrcweir if( DoParametersFollow( pParser, eCurExpr, eTok = eNextTok ) ) 240*cdf0e10cSrcweir { 241*cdf0e10cSrcweir bool bStandaloneExpression = (m_eMode == EXPRMODE_STANDALONE); 242*cdf0e10cSrcweir pPar = new SbiParameters( pParser, bStandaloneExpression ); 243*cdf0e10cSrcweir bError |= !pPar->IsValid(); 244*cdf0e10cSrcweir if( !bError ) 245*cdf0e10cSrcweir bBracket = pPar->IsBracket(); 246*cdf0e10cSrcweir eTok = pParser->Peek(); 247*cdf0e10cSrcweir 248*cdf0e10cSrcweir // i75443 check for additional sets of parameters 249*cdf0e10cSrcweir while( eTok == LPAREN ) 250*cdf0e10cSrcweir { 251*cdf0e10cSrcweir if( pvMoreParLcl == NULL ) 252*cdf0e10cSrcweir pvMoreParLcl = new SbiExprListVector(); 253*cdf0e10cSrcweir SbiParameters* pAddPar = new SbiParameters( pParser ); 254*cdf0e10cSrcweir pvMoreParLcl->push_back( pAddPar ); 255*cdf0e10cSrcweir bError |= !pPar->IsValid(); 256*cdf0e10cSrcweir eTok = pParser->Peek(); 257*cdf0e10cSrcweir } 258*cdf0e10cSrcweir } 259*cdf0e10cSrcweir // Es koennte ein Objektteil sein, wenn . oder ! folgt 260*cdf0e10cSrcweir // Bei . muss aber die Variable bereits definiert sein; wenn pDef 261*cdf0e10cSrcweir // nach der Suche NULL ist, isses ein Objekt! 262*cdf0e10cSrcweir sal_Bool bObj = sal_Bool( ( eTok == DOT || eTok == EXCLAM ) 263*cdf0e10cSrcweir && !pParser->WhiteSpace() ); 264*cdf0e10cSrcweir if( bObj ) 265*cdf0e10cSrcweir { 266*cdf0e10cSrcweir bBracket = sal_False; // Now the bracket for the first term is obsolete 267*cdf0e10cSrcweir if( eType == SbxVARIANT ) 268*cdf0e10cSrcweir eType = SbxOBJECT; 269*cdf0e10cSrcweir else 270*cdf0e10cSrcweir { 271*cdf0e10cSrcweir // Name%. geht wirklich nicht! 272*cdf0e10cSrcweir pParser->Error( SbERR_BAD_DECLARATION, aSym ); 273*cdf0e10cSrcweir bError = sal_True; 274*cdf0e10cSrcweir } 275*cdf0e10cSrcweir } 276*cdf0e10cSrcweir // Suche: 277*cdf0e10cSrcweir SbiSymDef* pDef = pParser->pPool->Find( aSym ); 278*cdf0e10cSrcweir if( !pDef ) 279*cdf0e10cSrcweir { 280*cdf0e10cSrcweir // Teil der Runtime-Library? 281*cdf0e10cSrcweir // AB 31.3.1996: In Parser-Methode ausgelagert 282*cdf0e10cSrcweir // (wird auch in SbiParser::DefVar() in DIM.CXX benoetigt) 283*cdf0e10cSrcweir pDef = pParser->CheckRTLForSym( aSym, eType ); 284*cdf0e10cSrcweir 285*cdf0e10cSrcweir // #i109184: Check if symbol is or later will be defined inside module 286*cdf0e10cSrcweir SbModule& rMod = pParser->aGen.GetModule(); 287*cdf0e10cSrcweir SbxArray* pModMethods = rMod.GetMethods(); 288*cdf0e10cSrcweir if( pModMethods->Find( aSym, SbxCLASS_DONTCARE ) ) 289*cdf0e10cSrcweir pDef = NULL; 290*cdf0e10cSrcweir } 291*cdf0e10cSrcweir if( !pDef ) 292*cdf0e10cSrcweir { 293*cdf0e10cSrcweir // Falls ein Punkt angegeben war, isses Teil eines Objekts, 294*cdf0e10cSrcweir // also muss der Returnwert ein Objekt sein 295*cdf0e10cSrcweir if( bObj ) 296*cdf0e10cSrcweir eType = SbxOBJECT; 297*cdf0e10cSrcweir pDef = AddSym( eTok, *pParser->pPool, eCurExpr, aSym, eType, pPar ); 298*cdf0e10cSrcweir // Looks like this is a local ( but undefined variable ) 299*cdf0e10cSrcweir // if it is in a static procedure then make this Symbol 300*cdf0e10cSrcweir // static 301*cdf0e10cSrcweir if ( !bObj && pParser->pProc && pParser->pProc->IsStatic() ) 302*cdf0e10cSrcweir pDef->SetStatic(); 303*cdf0e10cSrcweir } 304*cdf0e10cSrcweir else 305*cdf0e10cSrcweir { 306*cdf0e10cSrcweir 307*cdf0e10cSrcweir // Symbol ist bereits definiert. 308*cdf0e10cSrcweir // Ist es eine Konstante? 309*cdf0e10cSrcweir SbiConstDef* pConst = pDef->GetConstDef(); 310*cdf0e10cSrcweir if( pConst ) 311*cdf0e10cSrcweir { 312*cdf0e10cSrcweir if( pConst->GetType() == SbxSTRING ) 313*cdf0e10cSrcweir return new SbiExprNode( pParser, pConst->GetString() ); 314*cdf0e10cSrcweir else 315*cdf0e10cSrcweir return new SbiExprNode( pParser, pConst->GetValue(), pConst->GetType() ); 316*cdf0e10cSrcweir } 317*cdf0e10cSrcweir // Hat es Dimensionen, 318*cdf0e10cSrcweir // und sind auch Parameter angegeben? 319*cdf0e10cSrcweir // (Wobei 0 Parameter () entsprechen) 320*cdf0e10cSrcweir if( pDef->GetDims() ) 321*cdf0e10cSrcweir { 322*cdf0e10cSrcweir if( pPar && pPar->GetSize() && pPar->GetSize() != pDef->GetDims() ) 323*cdf0e10cSrcweir pParser->Error( SbERR_WRONG_DIMS ); 324*cdf0e10cSrcweir } 325*cdf0e10cSrcweir if( pDef->IsDefinedAs() ) 326*cdf0e10cSrcweir { 327*cdf0e10cSrcweir SbxDataType eDefType = pDef->GetType(); 328*cdf0e10cSrcweir // #119187 Only error if types conflict 329*cdf0e10cSrcweir if( eType >= SbxINTEGER && eType <= SbxSTRING && eType != eDefType ) 330*cdf0e10cSrcweir { 331*cdf0e10cSrcweir // Wie? Erst mit AS definieren und dann einen Suffix nehmen? 332*cdf0e10cSrcweir pParser->Error( SbERR_BAD_DECLARATION, aSym ); 333*cdf0e10cSrcweir bError = sal_True; 334*cdf0e10cSrcweir } 335*cdf0e10cSrcweir else if ( eType == SbxVARIANT ) 336*cdf0e10cSrcweir // Falls nix angegeben, den Typ des Eintrags nehmen 337*cdf0e10cSrcweir // aber nur, wenn die Var nicht mit AS XXX definiert ist 338*cdf0e10cSrcweir // damit erwischen wir n% = 5 : print n 339*cdf0e10cSrcweir eType = eDefType; 340*cdf0e10cSrcweir } 341*cdf0e10cSrcweir // Typcheck bei Variablen: 342*cdf0e10cSrcweir // ist explizit im Scanner etwas anderes angegeben? 343*cdf0e10cSrcweir // Bei Methoden ist dies OK! 344*cdf0e10cSrcweir if( eType != SbxVARIANT && // Variant nimmt alles 345*cdf0e10cSrcweir eType != pDef->GetType() && 346*cdf0e10cSrcweir !pDef->GetProcDef() ) 347*cdf0e10cSrcweir { 348*cdf0e10cSrcweir // Es kann sein, dass pDef ein Objekt beschreibt, das bisher 349*cdf0e10cSrcweir // nur als SbxVARIANT erkannt wurde, dann Typ von pDef aendern 350*cdf0e10cSrcweir // AB, 16.12.95 (Vielleicht noch aehnliche Faelle moeglich ?!?) 351*cdf0e10cSrcweir if( eType == SbxOBJECT && pDef->GetType() == SbxVARIANT ) 352*cdf0e10cSrcweir { 353*cdf0e10cSrcweir pDef->SetType( SbxOBJECT ); 354*cdf0e10cSrcweir } 355*cdf0e10cSrcweir else 356*cdf0e10cSrcweir { 357*cdf0e10cSrcweir pParser->Error( SbERR_BAD_DECLARATION, aSym ); 358*cdf0e10cSrcweir bError = sal_True; 359*cdf0e10cSrcweir } 360*cdf0e10cSrcweir } 361*cdf0e10cSrcweir } 362*cdf0e10cSrcweir SbiExprNode* pNd = new SbiExprNode( pParser, *pDef, eType ); 363*cdf0e10cSrcweir if( !pPar ) 364*cdf0e10cSrcweir pPar = new SbiParameters( pParser,sal_False,sal_False ); 365*cdf0e10cSrcweir pNd->aVar.pPar = pPar; 366*cdf0e10cSrcweir pNd->aVar.pvMorePar = pvMoreParLcl; 367*cdf0e10cSrcweir if( bObj ) 368*cdf0e10cSrcweir { 369*cdf0e10cSrcweir // AB, 8.1.95: Objekt kann auch vom Typ SbxVARIANT sein 370*cdf0e10cSrcweir if( pDef->GetType() == SbxVARIANT ) 371*cdf0e10cSrcweir pDef->SetType( SbxOBJECT ); 372*cdf0e10cSrcweir // Falls wir etwas mit Punkt einscannen, muss der 373*cdf0e10cSrcweir // Typ SbxOBJECT sein 374*cdf0e10cSrcweir if( pDef->GetType() != SbxOBJECT && pDef->GetType() != SbxVARIANT ) 375*cdf0e10cSrcweir { 376*cdf0e10cSrcweir pParser->Error( SbERR_BAD_DECLARATION, aSym ); 377*cdf0e10cSrcweir bError = sal_True; 378*cdf0e10cSrcweir } 379*cdf0e10cSrcweir if( !bError ) 380*cdf0e10cSrcweir pNd->aVar.pNext = ObjTerm( *pDef ); 381*cdf0e10cSrcweir } 382*cdf0e10cSrcweir // Merken der Spalte 1 wieder freigeben 383*cdf0e10cSrcweir pParser->UnlockColumn(); 384*cdf0e10cSrcweir return pNd; 385*cdf0e10cSrcweir } 386*cdf0e10cSrcweir 387*cdf0e10cSrcweir // Aufbau eines Objekt-Terms. Ein derartiger Term ist Teil 388*cdf0e10cSrcweir // eines Ausdrucks, der mit einer Objektvariablen beginnt. 389*cdf0e10cSrcweir 390*cdf0e10cSrcweir SbiExprNode* SbiExpression::ObjTerm( SbiSymDef& rObj ) 391*cdf0e10cSrcweir { 392*cdf0e10cSrcweir pParser->Next(); 393*cdf0e10cSrcweir SbiToken eTok = pParser->Next(); 394*cdf0e10cSrcweir if( eTok != SYMBOL && !pParser->IsKwd( eTok ) && !pParser->IsExtra( eTok ) ) 395*cdf0e10cSrcweir { 396*cdf0e10cSrcweir // #66745 Einige Operatoren koennen in diesem Kontext auch 397*cdf0e10cSrcweir // als Identifier zugelassen werden, wichtig fuer StarOne 398*cdf0e10cSrcweir if( eTok != MOD && eTok != NOT && eTok != AND && eTok != OR && 399*cdf0e10cSrcweir eTok != XOR && eTok != EQV && eTok != IMP && eTok != IS ) 400*cdf0e10cSrcweir { 401*cdf0e10cSrcweir pParser->Error( SbERR_VAR_EXPECTED ); 402*cdf0e10cSrcweir bError = sal_True; 403*cdf0e10cSrcweir } 404*cdf0e10cSrcweir } 405*cdf0e10cSrcweir /* #118410 Allow type for Class methods and RTL object, e.g. RTL.Chr$(97) 406*cdf0e10cSrcweir else 407*cdf0e10cSrcweir { 408*cdf0e10cSrcweir if( pParser->GetType() != SbxVARIANT ) 409*cdf0e10cSrcweir pParser->Error( SbERR_SYNTAX ), bError = sal_True; 410*cdf0e10cSrcweir } 411*cdf0e10cSrcweir */ 412*cdf0e10cSrcweir if( bError ) 413*cdf0e10cSrcweir return NULL; 414*cdf0e10cSrcweir 415*cdf0e10cSrcweir String aSym( pParser->GetSym() ); 416*cdf0e10cSrcweir SbxDataType eType = pParser->GetType(); 417*cdf0e10cSrcweir SbiParameters* pPar = NULL; 418*cdf0e10cSrcweir SbiExprListVector* pvMoreParLcl = NULL; 419*cdf0e10cSrcweir eTok = pParser->Peek(); 420*cdf0e10cSrcweir // Parameter? 421*cdf0e10cSrcweir if( DoParametersFollow( pParser, eCurExpr, eTok ) ) 422*cdf0e10cSrcweir { 423*cdf0e10cSrcweir bool bStandaloneExpression = false; 424*cdf0e10cSrcweir pPar = new SbiParameters( pParser, bStandaloneExpression ); 425*cdf0e10cSrcweir bError |= !pPar->IsValid(); 426*cdf0e10cSrcweir eTok = pParser->Peek(); 427*cdf0e10cSrcweir 428*cdf0e10cSrcweir // i109624 check for additional sets of parameters 429*cdf0e10cSrcweir while( eTok == LPAREN ) 430*cdf0e10cSrcweir { 431*cdf0e10cSrcweir if( pvMoreParLcl == NULL ) 432*cdf0e10cSrcweir pvMoreParLcl = new SbiExprListVector(); 433*cdf0e10cSrcweir SbiParameters* pAddPar = new SbiParameters( pParser ); 434*cdf0e10cSrcweir pvMoreParLcl->push_back( pAddPar ); 435*cdf0e10cSrcweir bError |= !pPar->IsValid(); 436*cdf0e10cSrcweir eTok = pParser->Peek(); 437*cdf0e10cSrcweir } 438*cdf0e10cSrcweir 439*cdf0e10cSrcweir } 440*cdf0e10cSrcweir sal_Bool bObj = sal_Bool( ( eTok == DOT || eTok == EXCLAM ) && !pParser->WhiteSpace() ); 441*cdf0e10cSrcweir if( bObj ) 442*cdf0e10cSrcweir { 443*cdf0e10cSrcweir if( eType == SbxVARIANT ) 444*cdf0e10cSrcweir eType = SbxOBJECT; 445*cdf0e10cSrcweir else 446*cdf0e10cSrcweir { 447*cdf0e10cSrcweir // Name%. geht wirklich nicht! 448*cdf0e10cSrcweir pParser->Error( SbERR_BAD_DECLARATION, aSym ); 449*cdf0e10cSrcweir bError = sal_True; 450*cdf0e10cSrcweir } 451*cdf0e10cSrcweir } 452*cdf0e10cSrcweir 453*cdf0e10cSrcweir // Der Symbol-Pool eines Objekts ist immer PUBLIC 454*cdf0e10cSrcweir SbiSymPool& rPool = rObj.GetPool(); 455*cdf0e10cSrcweir rPool.SetScope( SbPUBLIC ); 456*cdf0e10cSrcweir SbiSymDef* pDef = rPool.Find( aSym ); 457*cdf0e10cSrcweir if( !pDef ) 458*cdf0e10cSrcweir { 459*cdf0e10cSrcweir pDef = AddSym( eTok, rPool, eCurExpr, aSym, eType, pPar ); 460*cdf0e10cSrcweir pDef->SetType( eType ); 461*cdf0e10cSrcweir } 462*cdf0e10cSrcweir 463*cdf0e10cSrcweir SbiExprNode* pNd = new SbiExprNode( pParser, *pDef, eType ); 464*cdf0e10cSrcweir pNd->aVar.pPar = pPar; 465*cdf0e10cSrcweir pNd->aVar.pvMorePar = pvMoreParLcl; 466*cdf0e10cSrcweir if( bObj ) 467*cdf0e10cSrcweir { 468*cdf0e10cSrcweir // Falls wir etwas mit Punkt einscannen, muss der 469*cdf0e10cSrcweir // Typ SbxOBJECT sein 470*cdf0e10cSrcweir 471*cdf0e10cSrcweir // AB, 3.1.96 472*cdf0e10cSrcweir // Es kann sein, dass pDef ein Objekt beschreibt, das bisher 473*cdf0e10cSrcweir // nur als SbxVARIANT erkannt wurde, dann Typ von pDef aendern 474*cdf0e10cSrcweir if( pDef->GetType() == SbxVARIANT ) 475*cdf0e10cSrcweir pDef->SetType( SbxOBJECT ); 476*cdf0e10cSrcweir 477*cdf0e10cSrcweir if( pDef->GetType() != SbxOBJECT ) 478*cdf0e10cSrcweir { 479*cdf0e10cSrcweir pParser->Error( SbERR_BAD_DECLARATION, aSym ); 480*cdf0e10cSrcweir bError = sal_True; 481*cdf0e10cSrcweir } 482*cdf0e10cSrcweir if( !bError ) 483*cdf0e10cSrcweir { 484*cdf0e10cSrcweir pNd->aVar.pNext = ObjTerm( *pDef ); 485*cdf0e10cSrcweir pNd->eType = eType; 486*cdf0e10cSrcweir } 487*cdf0e10cSrcweir } 488*cdf0e10cSrcweir return pNd; 489*cdf0e10cSrcweir } 490*cdf0e10cSrcweir 491*cdf0e10cSrcweir // Als Operanden kommen in Betracht: 492*cdf0e10cSrcweir // Konstante 493*cdf0e10cSrcweir // skalare Variable 494*cdf0e10cSrcweir // Strukturelemente 495*cdf0e10cSrcweir // Array-Elemente 496*cdf0e10cSrcweir // Funktionen 497*cdf0e10cSrcweir // geklammerte Ausdruecke 498*cdf0e10cSrcweir 499*cdf0e10cSrcweir SbiExprNode* SbiExpression::Operand( bool bUsedForTypeOf ) 500*cdf0e10cSrcweir { 501*cdf0e10cSrcweir SbiExprNode *pRes; 502*cdf0e10cSrcweir SbiToken eTok; 503*cdf0e10cSrcweir 504*cdf0e10cSrcweir // Operand testen: 505*cdf0e10cSrcweir switch( eTok = pParser->Peek() ) 506*cdf0e10cSrcweir { 507*cdf0e10cSrcweir case SYMBOL: 508*cdf0e10cSrcweir pRes = Term(); 509*cdf0e10cSrcweir // process something like "IF Not r Is Nothing Then .." 510*cdf0e10cSrcweir if( !bUsedForTypeOf && pParser->IsVBASupportOn() && pParser->Peek() == IS ) 511*cdf0e10cSrcweir { 512*cdf0e10cSrcweir eTok = pParser->Next(); 513*cdf0e10cSrcweir pRes = new SbiExprNode( pParser, pRes, eTok, Like() ); 514*cdf0e10cSrcweir } 515*cdf0e10cSrcweir break; 516*cdf0e10cSrcweir case DOT: // .with 517*cdf0e10cSrcweir pRes = Term(); break; 518*cdf0e10cSrcweir case NUMBER: 519*cdf0e10cSrcweir pParser->Next(); 520*cdf0e10cSrcweir pRes = new SbiExprNode( pParser, pParser->GetDbl(), pParser->GetType() ); 521*cdf0e10cSrcweir break; 522*cdf0e10cSrcweir case FIXSTRING: 523*cdf0e10cSrcweir pParser->Next(); 524*cdf0e10cSrcweir pRes = new SbiExprNode( pParser, pParser->GetSym() ); break; 525*cdf0e10cSrcweir case LPAREN: 526*cdf0e10cSrcweir pParser->Next(); 527*cdf0e10cSrcweir if( nParenLevel == 0 && m_eMode == EXPRMODE_LPAREN_PENDING && pParser->Peek() == RPAREN ) 528*cdf0e10cSrcweir { 529*cdf0e10cSrcweir m_eMode = EXPRMODE_EMPTY_PAREN; 530*cdf0e10cSrcweir pRes = new SbiExprNode(); // Dummy node 531*cdf0e10cSrcweir pParser->Next(); 532*cdf0e10cSrcweir break; 533*cdf0e10cSrcweir } 534*cdf0e10cSrcweir nParenLevel++; 535*cdf0e10cSrcweir pRes = Boolean(); 536*cdf0e10cSrcweir if( pParser->Peek() != RPAREN ) 537*cdf0e10cSrcweir { 538*cdf0e10cSrcweir // If there was a LPARAM, it does not belong to the expression 539*cdf0e10cSrcweir if( nParenLevel == 1 && m_eMode == EXPRMODE_LPAREN_PENDING ) 540*cdf0e10cSrcweir m_eMode = EXPRMODE_LPAREN_NOT_NEEDED; 541*cdf0e10cSrcweir else 542*cdf0e10cSrcweir pParser->Error( SbERR_BAD_BRACKETS ); 543*cdf0e10cSrcweir } 544*cdf0e10cSrcweir else 545*cdf0e10cSrcweir { 546*cdf0e10cSrcweir pParser->Next(); 547*cdf0e10cSrcweir if( nParenLevel == 1 && m_eMode == EXPRMODE_LPAREN_PENDING ) 548*cdf0e10cSrcweir { 549*cdf0e10cSrcweir SbiToken eTokAfterRParen = pParser->Peek(); 550*cdf0e10cSrcweir if( eTokAfterRParen == EQ || eTokAfterRParen == LPAREN || eTokAfterRParen == DOT ) 551*cdf0e10cSrcweir m_eMode = EXPRMODE_ARRAY_OR_OBJECT; 552*cdf0e10cSrcweir else 553*cdf0e10cSrcweir m_eMode = EXPRMODE_STANDARD; 554*cdf0e10cSrcweir } 555*cdf0e10cSrcweir } 556*cdf0e10cSrcweir nParenLevel--; 557*cdf0e10cSrcweir pRes->bComposite = sal_True; 558*cdf0e10cSrcweir break; 559*cdf0e10cSrcweir default: 560*cdf0e10cSrcweir // Zur Zeit sind Keywords hier OK! 561*cdf0e10cSrcweir if( pParser->IsKwd( eTok ) ) 562*cdf0e10cSrcweir pRes = Term(); 563*cdf0e10cSrcweir else 564*cdf0e10cSrcweir { 565*cdf0e10cSrcweir pParser->Next(); 566*cdf0e10cSrcweir pRes = new SbiExprNode( pParser, 1.0, SbxDOUBLE ); // bei Fehlern 567*cdf0e10cSrcweir pParser->Error( SbERR_UNEXPECTED, eTok ); 568*cdf0e10cSrcweir } 569*cdf0e10cSrcweir } 570*cdf0e10cSrcweir return pRes; 571*cdf0e10cSrcweir } 572*cdf0e10cSrcweir 573*cdf0e10cSrcweir SbiExprNode* SbiExpression::Unary() 574*cdf0e10cSrcweir { 575*cdf0e10cSrcweir SbiExprNode* pNd; 576*cdf0e10cSrcweir SbiToken eTok = pParser->Peek(); 577*cdf0e10cSrcweir switch( eTok ) 578*cdf0e10cSrcweir { 579*cdf0e10cSrcweir case MINUS: 580*cdf0e10cSrcweir eTok = NEG; 581*cdf0e10cSrcweir pParser->Next(); 582*cdf0e10cSrcweir pNd = new SbiExprNode( pParser, Unary(), eTok, NULL ); 583*cdf0e10cSrcweir break; 584*cdf0e10cSrcweir case NOT: 585*cdf0e10cSrcweir if( pParser->IsVBASupportOn() ) 586*cdf0e10cSrcweir { 587*cdf0e10cSrcweir pNd = Operand(); 588*cdf0e10cSrcweir } 589*cdf0e10cSrcweir else 590*cdf0e10cSrcweir { 591*cdf0e10cSrcweir pParser->Next(); 592*cdf0e10cSrcweir pNd = new SbiExprNode( pParser, Unary(), eTok, NULL ); 593*cdf0e10cSrcweir } 594*cdf0e10cSrcweir break; 595*cdf0e10cSrcweir case PLUS: 596*cdf0e10cSrcweir pParser->Next(); 597*cdf0e10cSrcweir pNd = Unary(); 598*cdf0e10cSrcweir break; 599*cdf0e10cSrcweir case TYPEOF: 600*cdf0e10cSrcweir { 601*cdf0e10cSrcweir pParser->Next(); 602*cdf0e10cSrcweir bool bUsedForTypeOf = true; 603*cdf0e10cSrcweir SbiExprNode* pObjNode = Operand( bUsedForTypeOf ); 604*cdf0e10cSrcweir pParser->TestToken( IS ); 605*cdf0e10cSrcweir String aDummy; 606*cdf0e10cSrcweir SbiSymDef* pTypeDef = new SbiSymDef( aDummy ); 607*cdf0e10cSrcweir pParser->TypeDecl( *pTypeDef, sal_True ); 608*cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pObjNode, pTypeDef->GetTypeId() ); 609*cdf0e10cSrcweir break; 610*cdf0e10cSrcweir } 611*cdf0e10cSrcweir case NEW: 612*cdf0e10cSrcweir { 613*cdf0e10cSrcweir pParser->Next(); 614*cdf0e10cSrcweir String aStr; 615*cdf0e10cSrcweir SbiSymDef* pTypeDef = new SbiSymDef( aStr ); 616*cdf0e10cSrcweir pParser->TypeDecl( *pTypeDef, sal_True ); 617*cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pTypeDef->GetTypeId() ); 618*cdf0e10cSrcweir break; 619*cdf0e10cSrcweir } 620*cdf0e10cSrcweir default: 621*cdf0e10cSrcweir pNd = Operand(); 622*cdf0e10cSrcweir } 623*cdf0e10cSrcweir return pNd; 624*cdf0e10cSrcweir } 625*cdf0e10cSrcweir 626*cdf0e10cSrcweir SbiExprNode* SbiExpression::Exp() 627*cdf0e10cSrcweir { 628*cdf0e10cSrcweir SbiExprNode* pNd = Unary(); 629*cdf0e10cSrcweir if( m_eMode != EXPRMODE_EMPTY_PAREN ) 630*cdf0e10cSrcweir { 631*cdf0e10cSrcweir while( pParser->Peek() == EXPON ) { 632*cdf0e10cSrcweir SbiToken eTok = pParser->Next(); 633*cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pNd, eTok, Unary() ); 634*cdf0e10cSrcweir } 635*cdf0e10cSrcweir } 636*cdf0e10cSrcweir return pNd; 637*cdf0e10cSrcweir } 638*cdf0e10cSrcweir 639*cdf0e10cSrcweir SbiExprNode* SbiExpression::MulDiv() 640*cdf0e10cSrcweir { 641*cdf0e10cSrcweir SbiExprNode* pNd = Exp(); 642*cdf0e10cSrcweir if( m_eMode != EXPRMODE_EMPTY_PAREN ) 643*cdf0e10cSrcweir { 644*cdf0e10cSrcweir for( ;; ) 645*cdf0e10cSrcweir { 646*cdf0e10cSrcweir SbiToken eTok = pParser->Peek(); 647*cdf0e10cSrcweir if( eTok != MUL && eTok != DIV ) 648*cdf0e10cSrcweir break; 649*cdf0e10cSrcweir eTok = pParser->Next(); 650*cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pNd, eTok, Exp() ); 651*cdf0e10cSrcweir } 652*cdf0e10cSrcweir } 653*cdf0e10cSrcweir return pNd; 654*cdf0e10cSrcweir } 655*cdf0e10cSrcweir 656*cdf0e10cSrcweir SbiExprNode* SbiExpression::IntDiv() 657*cdf0e10cSrcweir { 658*cdf0e10cSrcweir SbiExprNode* pNd = MulDiv(); 659*cdf0e10cSrcweir if( m_eMode != EXPRMODE_EMPTY_PAREN ) 660*cdf0e10cSrcweir { 661*cdf0e10cSrcweir while( pParser->Peek() == IDIV ) { 662*cdf0e10cSrcweir SbiToken eTok = pParser->Next(); 663*cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pNd, eTok, MulDiv() ); 664*cdf0e10cSrcweir } 665*cdf0e10cSrcweir } 666*cdf0e10cSrcweir return pNd; 667*cdf0e10cSrcweir } 668*cdf0e10cSrcweir 669*cdf0e10cSrcweir SbiExprNode* SbiExpression::Mod() 670*cdf0e10cSrcweir { 671*cdf0e10cSrcweir SbiExprNode* pNd = IntDiv(); 672*cdf0e10cSrcweir if( m_eMode != EXPRMODE_EMPTY_PAREN ) 673*cdf0e10cSrcweir { 674*cdf0e10cSrcweir while( pParser->Peek() == MOD ) { 675*cdf0e10cSrcweir SbiToken eTok = pParser->Next(); 676*cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pNd, eTok, IntDiv() ); 677*cdf0e10cSrcweir } 678*cdf0e10cSrcweir } 679*cdf0e10cSrcweir return pNd; 680*cdf0e10cSrcweir } 681*cdf0e10cSrcweir 682*cdf0e10cSrcweir SbiExprNode* SbiExpression::AddSub() 683*cdf0e10cSrcweir { 684*cdf0e10cSrcweir SbiExprNode* pNd = Mod(); 685*cdf0e10cSrcweir if( m_eMode != EXPRMODE_EMPTY_PAREN ) 686*cdf0e10cSrcweir { 687*cdf0e10cSrcweir for( ;; ) 688*cdf0e10cSrcweir { 689*cdf0e10cSrcweir SbiToken eTok = pParser->Peek(); 690*cdf0e10cSrcweir if( eTok != PLUS && eTok != MINUS ) 691*cdf0e10cSrcweir break; 692*cdf0e10cSrcweir eTok = pParser->Next(); 693*cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pNd, eTok, Mod() ); 694*cdf0e10cSrcweir } 695*cdf0e10cSrcweir } 696*cdf0e10cSrcweir return pNd; 697*cdf0e10cSrcweir } 698*cdf0e10cSrcweir 699*cdf0e10cSrcweir SbiExprNode* SbiExpression::Cat() 700*cdf0e10cSrcweir { 701*cdf0e10cSrcweir SbiExprNode* pNd = AddSub(); 702*cdf0e10cSrcweir if( m_eMode != EXPRMODE_EMPTY_PAREN ) 703*cdf0e10cSrcweir { 704*cdf0e10cSrcweir for( ;; ) 705*cdf0e10cSrcweir { 706*cdf0e10cSrcweir SbiToken eTok = pParser->Peek(); 707*cdf0e10cSrcweir if( eTok != CAT ) 708*cdf0e10cSrcweir break; 709*cdf0e10cSrcweir eTok = pParser->Next(); 710*cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pNd, eTok, AddSub() ); 711*cdf0e10cSrcweir } 712*cdf0e10cSrcweir } 713*cdf0e10cSrcweir return pNd; 714*cdf0e10cSrcweir } 715*cdf0e10cSrcweir 716*cdf0e10cSrcweir SbiExprNode* SbiExpression::Comp() 717*cdf0e10cSrcweir { 718*cdf0e10cSrcweir SbiExprNode* pNd = Cat(); 719*cdf0e10cSrcweir if( m_eMode != EXPRMODE_EMPTY_PAREN ) 720*cdf0e10cSrcweir { 721*cdf0e10cSrcweir short nCount = 0; 722*cdf0e10cSrcweir for( ;; ) 723*cdf0e10cSrcweir { 724*cdf0e10cSrcweir SbiToken eTok = pParser->Peek(); 725*cdf0e10cSrcweir if( m_eMode == EXPRMODE_ARRAY_OR_OBJECT ) 726*cdf0e10cSrcweir break; 727*cdf0e10cSrcweir if( eTok != EQ && eTok != NE && eTok != LT 728*cdf0e10cSrcweir && eTok != GT && eTok != LE && eTok != GE ) 729*cdf0e10cSrcweir break; 730*cdf0e10cSrcweir eTok = pParser->Next(); 731*cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pNd, eTok, Cat() ); 732*cdf0e10cSrcweir nCount++; 733*cdf0e10cSrcweir } 734*cdf0e10cSrcweir } 735*cdf0e10cSrcweir return pNd; 736*cdf0e10cSrcweir } 737*cdf0e10cSrcweir 738*cdf0e10cSrcweir SbiExprNode* SbiExpression::VBA_Not() 739*cdf0e10cSrcweir { 740*cdf0e10cSrcweir SbiExprNode* pNd = NULL; 741*cdf0e10cSrcweir 742*cdf0e10cSrcweir SbiToken eTok = pParser->Peek(); 743*cdf0e10cSrcweir if( eTok == NOT ) 744*cdf0e10cSrcweir { 745*cdf0e10cSrcweir pParser->Next(); 746*cdf0e10cSrcweir pNd = new SbiExprNode( pParser, VBA_Not(), eTok, NULL ); 747*cdf0e10cSrcweir } 748*cdf0e10cSrcweir else 749*cdf0e10cSrcweir { 750*cdf0e10cSrcweir pNd = Comp(); 751*cdf0e10cSrcweir } 752*cdf0e10cSrcweir return pNd; 753*cdf0e10cSrcweir } 754*cdf0e10cSrcweir 755*cdf0e10cSrcweir SbiExprNode* SbiExpression::Like() 756*cdf0e10cSrcweir { 757*cdf0e10cSrcweir SbiExprNode* pNd = pParser->IsVBASupportOn() ? VBA_Not() : Comp(); 758*cdf0e10cSrcweir if( m_eMode != EXPRMODE_EMPTY_PAREN ) 759*cdf0e10cSrcweir { 760*cdf0e10cSrcweir short nCount = 0; 761*cdf0e10cSrcweir while( pParser->Peek() == LIKE ) { 762*cdf0e10cSrcweir SbiToken eTok = pParser->Next(); 763*cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pNd, eTok, Comp() ), nCount++; 764*cdf0e10cSrcweir } 765*cdf0e10cSrcweir // Mehrere Operatoren hintereinander gehen nicht 766*cdf0e10cSrcweir if( nCount > 1 ) 767*cdf0e10cSrcweir { 768*cdf0e10cSrcweir pParser->Error( SbERR_SYNTAX ); 769*cdf0e10cSrcweir bError = sal_True; 770*cdf0e10cSrcweir } 771*cdf0e10cSrcweir } 772*cdf0e10cSrcweir return pNd; 773*cdf0e10cSrcweir } 774*cdf0e10cSrcweir 775*cdf0e10cSrcweir SbiExprNode* SbiExpression::Boolean() 776*cdf0e10cSrcweir { 777*cdf0e10cSrcweir SbiExprNode* pNd = Like(); 778*cdf0e10cSrcweir if( m_eMode != EXPRMODE_EMPTY_PAREN ) 779*cdf0e10cSrcweir { 780*cdf0e10cSrcweir for( ;; ) 781*cdf0e10cSrcweir { 782*cdf0e10cSrcweir SbiToken eTok = pParser->Peek(); 783*cdf0e10cSrcweir if( eTok != AND && eTok != OR && eTok != XOR 784*cdf0e10cSrcweir && eTok != EQV && eTok != IMP && eTok != IS ) 785*cdf0e10cSrcweir break; 786*cdf0e10cSrcweir eTok = pParser->Next(); 787*cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pNd, eTok, Like() ); 788*cdf0e10cSrcweir } 789*cdf0e10cSrcweir } 790*cdf0e10cSrcweir return pNd; 791*cdf0e10cSrcweir } 792*cdf0e10cSrcweir 793*cdf0e10cSrcweir /*************************************************************************** 794*cdf0e10cSrcweir |* 795*cdf0e10cSrcweir |* SbiConstExpression 796*cdf0e10cSrcweir |* 797*cdf0e10cSrcweir ***************************************************************************/ 798*cdf0e10cSrcweir 799*cdf0e10cSrcweir // Parsing einer Expression, die sich zu einer numerischen 800*cdf0e10cSrcweir // Konstanten verarbeiten laesst. 801*cdf0e10cSrcweir 802*cdf0e10cSrcweir SbiConstExpression::SbiConstExpression( SbiParser* p ) : SbiExpression( p ) 803*cdf0e10cSrcweir { 804*cdf0e10cSrcweir if( pExpr->IsConstant() ) 805*cdf0e10cSrcweir { 806*cdf0e10cSrcweir eType = pExpr->GetType(); 807*cdf0e10cSrcweir if( pExpr->IsNumber() ) 808*cdf0e10cSrcweir { 809*cdf0e10cSrcweir nVal = pExpr->nVal; 810*cdf0e10cSrcweir } 811*cdf0e10cSrcweir else 812*cdf0e10cSrcweir { 813*cdf0e10cSrcweir nVal = 0; 814*cdf0e10cSrcweir aVal = pExpr->aStrVal; 815*cdf0e10cSrcweir } 816*cdf0e10cSrcweir } 817*cdf0e10cSrcweir else 818*cdf0e10cSrcweir { 819*cdf0e10cSrcweir // #40204 Spezialbehandlung fuer sal_Bool-Konstanten 820*cdf0e10cSrcweir sal_Bool bIsBool = sal_False; 821*cdf0e10cSrcweir if( pExpr->eNodeType == SbxVARVAL ) 822*cdf0e10cSrcweir { 823*cdf0e10cSrcweir SbiSymDef* pVarDef = pExpr->GetVar(); 824*cdf0e10cSrcweir 825*cdf0e10cSrcweir // Ist es eine sal_Bool-Konstante? 826*cdf0e10cSrcweir sal_Bool bBoolVal = sal_False; 827*cdf0e10cSrcweir if( pVarDef->GetName().EqualsIgnoreCaseAscii( "true" ) ) 828*cdf0e10cSrcweir //if( pVarDef->GetName().ICompare( "true" ) == COMPARE_EQUAL ) 829*cdf0e10cSrcweir { 830*cdf0e10cSrcweir bIsBool = sal_True; 831*cdf0e10cSrcweir bBoolVal = sal_True; 832*cdf0e10cSrcweir } 833*cdf0e10cSrcweir else if( pVarDef->GetName().EqualsIgnoreCaseAscii( "false" ) ) 834*cdf0e10cSrcweir //else if( pVarDef->GetName().ICompare( "false" ) == COMPARE_EQUAL ) 835*cdf0e10cSrcweir { 836*cdf0e10cSrcweir bIsBool = sal_True; 837*cdf0e10cSrcweir bBoolVal = sal_False; 838*cdf0e10cSrcweir } 839*cdf0e10cSrcweir 840*cdf0e10cSrcweir // Wenn es ein sal_Bool ist, Node austauschen 841*cdf0e10cSrcweir if( bIsBool ) 842*cdf0e10cSrcweir { 843*cdf0e10cSrcweir delete pExpr; 844*cdf0e10cSrcweir pExpr = new SbiExprNode( pParser, (bBoolVal ? SbxTRUE : SbxFALSE), SbxINTEGER ); 845*cdf0e10cSrcweir eType = pExpr->GetType(); 846*cdf0e10cSrcweir nVal = pExpr->nVal; 847*cdf0e10cSrcweir } 848*cdf0e10cSrcweir } 849*cdf0e10cSrcweir 850*cdf0e10cSrcweir if( !bIsBool ) 851*cdf0e10cSrcweir { 852*cdf0e10cSrcweir pParser->Error( SbERR_SYNTAX ); 853*cdf0e10cSrcweir eType = SbxDOUBLE; 854*cdf0e10cSrcweir nVal = 0; 855*cdf0e10cSrcweir } 856*cdf0e10cSrcweir } 857*cdf0e10cSrcweir } 858*cdf0e10cSrcweir 859*cdf0e10cSrcweir short SbiConstExpression::GetShortValue() 860*cdf0e10cSrcweir { 861*cdf0e10cSrcweir if( eType == SbxSTRING ) 862*cdf0e10cSrcweir { 863*cdf0e10cSrcweir SbxVariableRef refConv = new SbxVariable; 864*cdf0e10cSrcweir refConv->PutString( aVal ); 865*cdf0e10cSrcweir return refConv->GetInteger(); 866*cdf0e10cSrcweir } 867*cdf0e10cSrcweir else 868*cdf0e10cSrcweir { 869*cdf0e10cSrcweir double n = nVal; 870*cdf0e10cSrcweir if( n > 0 ) n += .5; else n -= .5; 871*cdf0e10cSrcweir if( n > SbxMAXINT ) n = SbxMAXINT, pParser->Error( SbERR_OUT_OF_RANGE ); 872*cdf0e10cSrcweir else 873*cdf0e10cSrcweir if( n < SbxMININT ) n = SbxMININT, pParser->Error( SbERR_OUT_OF_RANGE ); 874*cdf0e10cSrcweir return (short) n; 875*cdf0e10cSrcweir } 876*cdf0e10cSrcweir } 877*cdf0e10cSrcweir 878*cdf0e10cSrcweir 879*cdf0e10cSrcweir /*************************************************************************** 880*cdf0e10cSrcweir |* 881*cdf0e10cSrcweir |* SbiExprList 882*cdf0e10cSrcweir |* 883*cdf0e10cSrcweir ***************************************************************************/ 884*cdf0e10cSrcweir 885*cdf0e10cSrcweir SbiExprList::SbiExprList( SbiParser* p ) 886*cdf0e10cSrcweir { 887*cdf0e10cSrcweir pParser = p; 888*cdf0e10cSrcweir pFirst = NULL; 889*cdf0e10cSrcweir nExpr = 890*cdf0e10cSrcweir nDim = 0; 891*cdf0e10cSrcweir bError = 892*cdf0e10cSrcweir bBracket = sal_False; 893*cdf0e10cSrcweir } 894*cdf0e10cSrcweir 895*cdf0e10cSrcweir SbiExprList::~SbiExprList() 896*cdf0e10cSrcweir { 897*cdf0e10cSrcweir SbiExpression* p = pFirst; 898*cdf0e10cSrcweir while( p ) 899*cdf0e10cSrcweir { 900*cdf0e10cSrcweir SbiExpression* q = p->pNext; 901*cdf0e10cSrcweir delete p; 902*cdf0e10cSrcweir p = q; 903*cdf0e10cSrcweir } 904*cdf0e10cSrcweir } 905*cdf0e10cSrcweir 906*cdf0e10cSrcweir // Parameter anfordern (ab 0) 907*cdf0e10cSrcweir 908*cdf0e10cSrcweir SbiExpression* SbiExprList::Get( short n ) 909*cdf0e10cSrcweir { 910*cdf0e10cSrcweir SbiExpression* p = pFirst; 911*cdf0e10cSrcweir while( n-- && p ) 912*cdf0e10cSrcweir p = p->pNext; 913*cdf0e10cSrcweir return p; 914*cdf0e10cSrcweir } 915*cdf0e10cSrcweir 916*cdf0e10cSrcweir void SbiExprList::addExpression( SbiExpression* pExpr ) 917*cdf0e10cSrcweir { 918*cdf0e10cSrcweir SbiExpression* p = pFirst; 919*cdf0e10cSrcweir while( p && p->pNext ) 920*cdf0e10cSrcweir p = p->pNext; 921*cdf0e10cSrcweir 922*cdf0e10cSrcweir p->pNext = pExpr; 923*cdf0e10cSrcweir } 924*cdf0e10cSrcweir 925*cdf0e10cSrcweir 926*cdf0e10cSrcweir /*************************************************************************** 927*cdf0e10cSrcweir |* 928*cdf0e10cSrcweir |* SbiParameters 929*cdf0e10cSrcweir |* 930*cdf0e10cSrcweir ***************************************************************************/ 931*cdf0e10cSrcweir 932*cdf0e10cSrcweir // Parsender Konstruktor: 933*cdf0e10cSrcweir // Die Parameterliste wird komplett geparst. 934*cdf0e10cSrcweir // "Prozedurname()" ist OK. 935*cdf0e10cSrcweir // Dann handelt es sich um eine Funktion ohne Parameter 936*cdf0e10cSrcweir // respektive um die Angabe eines Arrays als Prozedurparameter. 937*cdf0e10cSrcweir 938*cdf0e10cSrcweir // #i79918/#i80532: bConst has never been set to true 939*cdf0e10cSrcweir // -> reused as bStandaloneExpression 940*cdf0e10cSrcweir //SbiParameters::SbiParameters( SbiParser* p, sal_Bool bConst, sal_Bool bPar) : 941*cdf0e10cSrcweir SbiParameters::SbiParameters( SbiParser* p, sal_Bool bStandaloneExpression, sal_Bool bPar) : 942*cdf0e10cSrcweir SbiExprList( p ) 943*cdf0e10cSrcweir { 944*cdf0e10cSrcweir if( !bPar ) 945*cdf0e10cSrcweir return; 946*cdf0e10cSrcweir 947*cdf0e10cSrcweir SbiExpression *pExpr; 948*cdf0e10cSrcweir SbiToken eTok = pParser->Peek(); 949*cdf0e10cSrcweir 950*cdf0e10cSrcweir // evtl. Klammer auf weg: 951*cdf0e10cSrcweir bool bAssumeExprLParenMode = false; 952*cdf0e10cSrcweir bool bAssumeArrayMode = false; 953*cdf0e10cSrcweir if( eTok == LPAREN ) 954*cdf0e10cSrcweir { 955*cdf0e10cSrcweir if( bStandaloneExpression ) 956*cdf0e10cSrcweir { 957*cdf0e10cSrcweir bAssumeExprLParenMode = true; 958*cdf0e10cSrcweir } 959*cdf0e10cSrcweir else 960*cdf0e10cSrcweir { 961*cdf0e10cSrcweir bBracket = sal_True; 962*cdf0e10cSrcweir pParser->Next(); 963*cdf0e10cSrcweir eTok = pParser->Peek(); 964*cdf0e10cSrcweir } 965*cdf0e10cSrcweir } 966*cdf0e10cSrcweir 967*cdf0e10cSrcweir // Ende-Test 968*cdf0e10cSrcweir if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) ) 969*cdf0e10cSrcweir { 970*cdf0e10cSrcweir if( eTok == RPAREN ) 971*cdf0e10cSrcweir pParser->Next(); 972*cdf0e10cSrcweir return; 973*cdf0e10cSrcweir } 974*cdf0e10cSrcweir // Parametertabelle einlesen und in richtiger Folge ablegen! 975*cdf0e10cSrcweir SbiExpression* pLast = NULL; 976*cdf0e10cSrcweir String aName; 977*cdf0e10cSrcweir while( !bError ) 978*cdf0e10cSrcweir { 979*cdf0e10cSrcweir aName.Erase(); 980*cdf0e10cSrcweir // Fehlendes Argument 981*cdf0e10cSrcweir if( eTok == COMMA ) 982*cdf0e10cSrcweir { 983*cdf0e10cSrcweir pExpr = new SbiExpression( pParser, 0, SbxEMPTY ); 984*cdf0e10cSrcweir //if( bConst ) 985*cdf0e10cSrcweir // pParser->Error( SbERR_SYNTAX ), bError = sal_True; 986*cdf0e10cSrcweir } 987*cdf0e10cSrcweir // Benannte Argumente: entweder .name= oder name:= 988*cdf0e10cSrcweir else 989*cdf0e10cSrcweir { 990*cdf0e10cSrcweir bool bByVal = false; 991*cdf0e10cSrcweir if( eTok == BYVAL ) 992*cdf0e10cSrcweir { 993*cdf0e10cSrcweir bByVal = true; 994*cdf0e10cSrcweir pParser->Next(); 995*cdf0e10cSrcweir eTok = pParser->Peek(); 996*cdf0e10cSrcweir } 997*cdf0e10cSrcweir 998*cdf0e10cSrcweir if( bAssumeExprLParenMode ) 999*cdf0e10cSrcweir { 1000*cdf0e10cSrcweir pExpr = new SbiExpression( pParser, SbSTDEXPR, EXPRMODE_LPAREN_PENDING ); 1001*cdf0e10cSrcweir bAssumeExprLParenMode = sal_False; 1002*cdf0e10cSrcweir 1003*cdf0e10cSrcweir SbiExprMode eModeAfter = pExpr->m_eMode; 1004*cdf0e10cSrcweir if( eModeAfter == EXPRMODE_LPAREN_NOT_NEEDED ) 1005*cdf0e10cSrcweir { 1006*cdf0e10cSrcweir bBracket = sal_True; 1007*cdf0e10cSrcweir } 1008*cdf0e10cSrcweir else if( eModeAfter == EXPRMODE_ARRAY_OR_OBJECT ) 1009*cdf0e10cSrcweir { 1010*cdf0e10cSrcweir // Expression "looks" like an array assignment 1011*cdf0e10cSrcweir // a(...)[(...)] = ? or a(...).b(...) 1012*cdf0e10cSrcweir // RPAREN is already parsed 1013*cdf0e10cSrcweir bBracket = sal_True; 1014*cdf0e10cSrcweir bAssumeArrayMode = true; 1015*cdf0e10cSrcweir eTok = NIL; 1016*cdf0e10cSrcweir } 1017*cdf0e10cSrcweir else if( eModeAfter == EXPRMODE_EMPTY_PAREN ) 1018*cdf0e10cSrcweir { 1019*cdf0e10cSrcweir bBracket = sal_True; 1020*cdf0e10cSrcweir delete pExpr; 1021*cdf0e10cSrcweir if( bByVal ) 1022*cdf0e10cSrcweir pParser->Error( SbERR_LVALUE_EXPECTED ); 1023*cdf0e10cSrcweir return; 1024*cdf0e10cSrcweir } 1025*cdf0e10cSrcweir } 1026*cdf0e10cSrcweir else 1027*cdf0e10cSrcweir pExpr = new SbiExpression( pParser ); 1028*cdf0e10cSrcweir 1029*cdf0e10cSrcweir if( bByVal && pExpr->IsLvalue() ) 1030*cdf0e10cSrcweir pExpr->SetByVal(); 1031*cdf0e10cSrcweir 1032*cdf0e10cSrcweir //pExpr = bConst ? new SbiConstExpression( pParser ) 1033*cdf0e10cSrcweir // : new SbiExpression( pParser ); 1034*cdf0e10cSrcweir if( !bAssumeArrayMode ) 1035*cdf0e10cSrcweir { 1036*cdf0e10cSrcweir if( pParser->Peek() == ASSIGN ) 1037*cdf0e10cSrcweir { 1038*cdf0e10cSrcweir // VBA mode: name:= 1039*cdf0e10cSrcweir // SbiExpression::Term() hat einen String daraus gemacht 1040*cdf0e10cSrcweir aName = pExpr->GetString(); 1041*cdf0e10cSrcweir delete pExpr; 1042*cdf0e10cSrcweir pParser->Next(); 1043*cdf0e10cSrcweir pExpr = new SbiExpression( pParser ); 1044*cdf0e10cSrcweir //if( bConst ) 1045*cdf0e10cSrcweir // pParser->Error( SbERR_SYNTAX ), bError = sal_True; 1046*cdf0e10cSrcweir } 1047*cdf0e10cSrcweir pExpr->GetName() = aName; 1048*cdf0e10cSrcweir } 1049*cdf0e10cSrcweir } 1050*cdf0e10cSrcweir pExpr->pNext = NULL; 1051*cdf0e10cSrcweir if( !pLast ) 1052*cdf0e10cSrcweir pFirst = pLast = pExpr; 1053*cdf0e10cSrcweir else 1054*cdf0e10cSrcweir pLast->pNext = pExpr, pLast = pExpr; 1055*cdf0e10cSrcweir nExpr++; 1056*cdf0e10cSrcweir bError |= !pExpr->IsValid(); 1057*cdf0e10cSrcweir 1058*cdf0e10cSrcweir if( bAssumeArrayMode ) 1059*cdf0e10cSrcweir break; 1060*cdf0e10cSrcweir 1061*cdf0e10cSrcweir // Naechstes Element? 1062*cdf0e10cSrcweir eTok = pParser->Peek(); 1063*cdf0e10cSrcweir if( eTok != COMMA ) 1064*cdf0e10cSrcweir { 1065*cdf0e10cSrcweir if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) ) 1066*cdf0e10cSrcweir break; 1067*cdf0e10cSrcweir pParser->Error( bBracket 1068*cdf0e10cSrcweir ? SbERR_BAD_BRACKETS 1069*cdf0e10cSrcweir : SbERR_EXPECTED, COMMA ); 1070*cdf0e10cSrcweir bError = sal_True; 1071*cdf0e10cSrcweir } 1072*cdf0e10cSrcweir else 1073*cdf0e10cSrcweir { 1074*cdf0e10cSrcweir pParser->Next(); 1075*cdf0e10cSrcweir eTok = pParser->Peek(); 1076*cdf0e10cSrcweir if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) ) 1077*cdf0e10cSrcweir break; 1078*cdf0e10cSrcweir } 1079*cdf0e10cSrcweir } 1080*cdf0e10cSrcweir // Schliessende Klammer 1081*cdf0e10cSrcweir if( eTok == RPAREN ) 1082*cdf0e10cSrcweir { 1083*cdf0e10cSrcweir pParser->Next(); 1084*cdf0e10cSrcweir pParser->Peek(); 1085*cdf0e10cSrcweir if( !bBracket ) 1086*cdf0e10cSrcweir { 1087*cdf0e10cSrcweir pParser->Error( SbERR_BAD_BRACKETS ); 1088*cdf0e10cSrcweir bError = sal_True; 1089*cdf0e10cSrcweir } 1090*cdf0e10cSrcweir } 1091*cdf0e10cSrcweir nDim = nExpr; 1092*cdf0e10cSrcweir } 1093*cdf0e10cSrcweir 1094*cdf0e10cSrcweir /*************************************************************************** 1095*cdf0e10cSrcweir |* 1096*cdf0e10cSrcweir |* SbiDimList 1097*cdf0e10cSrcweir |* 1098*cdf0e10cSrcweir ***************************************************************************/ 1099*cdf0e10cSrcweir 1100*cdf0e10cSrcweir // Parsender Konstruktor: 1101*cdf0e10cSrcweir // Eine Liste von Array-Dimensionen wird geparst. Die Ausdruecke werden 1102*cdf0e10cSrcweir // auf numerisch getestet. Das bCONST-Bit wird gesetzt, wenn alle Ausdruecke 1103*cdf0e10cSrcweir // Integer-Konstanten sind. 1104*cdf0e10cSrcweir 1105*cdf0e10cSrcweir SbiDimList::SbiDimList( SbiParser* p ) : SbiExprList( p ) 1106*cdf0e10cSrcweir { 1107*cdf0e10cSrcweir bConst = sal_True; 1108*cdf0e10cSrcweir 1109*cdf0e10cSrcweir if( pParser->Next() != LPAREN ) 1110*cdf0e10cSrcweir { 1111*cdf0e10cSrcweir pParser->Error( SbERR_EXPECTED, LPAREN ); 1112*cdf0e10cSrcweir bError = sal_True; return; 1113*cdf0e10cSrcweir } 1114*cdf0e10cSrcweir 1115*cdf0e10cSrcweir if( pParser->Peek() != RPAREN ) 1116*cdf0e10cSrcweir { 1117*cdf0e10cSrcweir SbiExpression *pExpr1, *pExpr2, *pLast = NULL; 1118*cdf0e10cSrcweir SbiToken eTok; 1119*cdf0e10cSrcweir for( ;; ) 1120*cdf0e10cSrcweir { 1121*cdf0e10cSrcweir pExpr1 = new SbiExpression( pParser ); 1122*cdf0e10cSrcweir eTok = pParser->Next(); 1123*cdf0e10cSrcweir if( eTok == TO ) 1124*cdf0e10cSrcweir { 1125*cdf0e10cSrcweir pExpr2 = new SbiExpression( pParser ); 1126*cdf0e10cSrcweir eTok = pParser->Next(); 1127*cdf0e10cSrcweir bConst &= pExpr1->IsIntConstant() & pExpr2->IsIntConstant(); 1128*cdf0e10cSrcweir bError |= !pExpr1->IsValid(); 1129*cdf0e10cSrcweir bError |= !pExpr2->IsValid(); 1130*cdf0e10cSrcweir pExpr1->pNext = pExpr2; 1131*cdf0e10cSrcweir if( !pLast ) 1132*cdf0e10cSrcweir pFirst = pExpr1; 1133*cdf0e10cSrcweir else 1134*cdf0e10cSrcweir pLast->pNext = pExpr1; 1135*cdf0e10cSrcweir pLast = pExpr2; 1136*cdf0e10cSrcweir nExpr += 2; 1137*cdf0e10cSrcweir } 1138*cdf0e10cSrcweir else 1139*cdf0e10cSrcweir { 1140*cdf0e10cSrcweir // Nur eine Dim-Angabe 1141*cdf0e10cSrcweir pExpr1->SetBased(); 1142*cdf0e10cSrcweir pExpr1->pNext = NULL; 1143*cdf0e10cSrcweir bConst &= pExpr1->IsIntConstant(); 1144*cdf0e10cSrcweir bError |= !pExpr1->IsValid(); 1145*cdf0e10cSrcweir if( !pLast ) 1146*cdf0e10cSrcweir pFirst = pLast = pExpr1; 1147*cdf0e10cSrcweir else 1148*cdf0e10cSrcweir pLast->pNext = pExpr1, pLast = pExpr1; 1149*cdf0e10cSrcweir nExpr++; 1150*cdf0e10cSrcweir } 1151*cdf0e10cSrcweir nDim++; 1152*cdf0e10cSrcweir if( eTok == RPAREN ) break; 1153*cdf0e10cSrcweir if( eTok != COMMA ) 1154*cdf0e10cSrcweir { 1155*cdf0e10cSrcweir pParser->Error( SbERR_BAD_BRACKETS ); 1156*cdf0e10cSrcweir pParser->Next(); 1157*cdf0e10cSrcweir break; 1158*cdf0e10cSrcweir } 1159*cdf0e10cSrcweir } 1160*cdf0e10cSrcweir } 1161*cdf0e10cSrcweir else pParser->Next(); 1162*cdf0e10cSrcweir } 1163*cdf0e10cSrcweir 1164