summaryrefslogtreecommitdiff
path: root/basic/source/comp
diff options
context:
space:
mode:
authorKurt Zenker <kz@openoffice.org>2008-06-24 15:01:55 +0000
committerKurt Zenker <kz@openoffice.org>2008-06-24 15:01:55 +0000
commite1f4fc2cf9ecec2ae0d09fb0315aea3c025445c3 (patch)
treeba25eb8e9aed5abd007206ee9ca7b170f7c12746 /basic/source/comp
parentca3104c0f5dc3fc236ceae48152893e81b86009f (diff)
INTEGRATION: CWS ab48 (1.21.6); FILE MERGED
2008/06/10 05:10:00 ab 1.21.6.4: RESYNC: (1.21-1.22); FILE MERGED 2008/06/06 06:52:37 ab 1.21.6.3: #i75443# Fixed problem with parsing object chains 2008/04/04 10:57:36 ab 1.21.6.2: #i75443# Support multiple array indices 2008/04/01 09:20:30 ab 1.21.6.1: #i79918#, #i80532# New parameter handling
Diffstat (limited to 'basic/source/comp')
-rw-r--r--basic/source/comp/exprtree.cxx232
1 files changed, 158 insertions, 74 deletions
diff --git a/basic/source/comp/exprtree.cxx b/basic/source/comp/exprtree.cxx
index 83a5ba0f2e69..c0fc76e758bb 100644
--- a/basic/source/comp/exprtree.cxx
+++ b/basic/source/comp/exprtree.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: exprtree.cxx,v $
- * $Revision: 1.22 $
+ * $Revision: 1.23 $
*
* This file is part of OpenOffice.org.
*
@@ -41,11 +41,13 @@
|*
***************************************************************************/
-SbiExpression::SbiExpression( SbiParser* p, SbiExprType t )
+SbiExpression::SbiExpression( SbiParser* p, SbiExprType t, SbiExprMode eMode )
{
pParser = p;
- bError = bByVal = bBased = FALSE;
+ bError = bByVal = bBased = bBracket = FALSE;
+ nParenLevel = 0;
eCurExpr = t;
+ m_eMode = eMode;
pNext = NULL;
pExpr = (t != SbSTDEXPR ) ? Term() : Boolean();
if( t != SbSYMBOL )
@@ -61,7 +63,7 @@ SbiExpression::SbiExpression( SbiParser* p, double n, SbxDataType t )
pParser = p;
eCurExpr = SbOPERAND;
pNext = NULL;
- bError = bByVal = bBased = FALSE;
+ bError = bByVal = bBased = bBracket = FALSE;
pExpr = new SbiExprNode( pParser, n, t );
pExpr->Optimize();
}
@@ -70,7 +72,7 @@ SbiExpression::SbiExpression( SbiParser* p, const String& r )
{
pParser = p;
pNext = NULL;
- bError = bByVal = bBased = FALSE;
+ bError = bByVal = bBased = bBracket = FALSE;
eCurExpr = SbOPERAND;
pExpr = new SbiExprNode( pParser, r );
}
@@ -79,7 +81,7 @@ SbiExpression::SbiExpression( SbiParser* p, const SbiSymDef& r, SbiExprList* pPa
{
pParser = p;
pNext = NULL;
- bError = bByVal = bBased = FALSE;
+ bError = bByVal = bBased = bBracket = FALSE;
eCurExpr = SbOPERAND;
pExpr = new SbiExprNode( pParser, r, SbxVARIANT, pPar );
}
@@ -88,7 +90,7 @@ SbiExpression::SbiExpression( SbiParser* p, SbiToken t )
{
pParser = p;
pNext = NULL;
- bError = bByVal = bBased = FALSE;
+ bError = bByVal = bBased = bBracket = FALSE;
eCurExpr = SbOPERAND;
pExpr = new SbiExprNode( pParser, NULL, t, NULL );
}
@@ -114,7 +116,7 @@ static BOOL DoParametersFollow( SbiParser* p, SbiExprType eCurExpr, SbiToken eTo
// Aber nur, wenn CALL-aehnlich!
if( !p->WhiteSpace() || eCurExpr != SbSYMBOL )
return FALSE;
- if ( eTok == NUMBER || eTok == FIXSTRING
+ if ( eTok == NUMBER || eTok == MINUS || eTok == FIXSTRING
|| eTok == SYMBOL || eTok == COMMA || eTok == DOT )
{
return TRUE;
@@ -178,7 +180,7 @@ static SbiSymDef* AddSym
// Zur Zeit sind sogar Keywords zugelassen (wg. gleichnamiger Dflt-Properties)
-SbiExprNode* SbiExpression::Term()
+SbiExprNode* SbiExpression::Term( void )
{
if( pParser->Peek() == DOT )
{
@@ -211,6 +213,7 @@ SbiExprNode* SbiExpression::Term()
String aSym( pParser->GetSym() );
SbxDataType eType = pParser->GetType();
SbiParameters* pPar = NULL;
+ SbiExprListVector* pvMoreParLcl = NULL;
// Folgen Parameter?
SbiToken eNextTok = pParser->Peek();
// Ist es ein benannter Parameter?
@@ -237,9 +240,23 @@ SbiExprNode* SbiExpression::Term()
if( DoParametersFollow( pParser, eCurExpr, eTok = eNextTok ) )
{
- pPar = new SbiParameters( pParser );
+ bool bStandaloneExpression = (m_eMode == EXPRMODE_STANDALONE);
+ pPar = new SbiParameters( pParser, bStandaloneExpression );
bError |= !pPar->IsValid();
+ if( !bError )
+ bBracket = pPar->IsBracket();
eTok = pParser->Peek();
+
+ // i75443 check for additional sets of parameters
+ while( eTok == LPAREN )
+ {
+ if( pvMoreParLcl == NULL )
+ pvMoreParLcl = new SbiExprListVector();
+ SbiParameters* pAddPar = new SbiParameters( pParser );
+ pvMoreParLcl->push_back( pAddPar );
+ bError |= !pPar->IsValid();
+ eTok = pParser->Peek();
+ }
}
// Es koennte ein Objektteil sein, wenn . oder ! folgt
// Bei . muss aber die Variable bereits definiert sein; wenn pDef
@@ -248,6 +265,7 @@ SbiExprNode* SbiExpression::Term()
&& !pParser->WhiteSpace() );
if( bObj )
{
+ bBracket = FALSE; // Now the bracket for the first term is obsolete
if( eType == SbxVARIANT )
eType = SbxOBJECT;
else
@@ -345,6 +363,7 @@ SbiExprNode* SbiExpression::Term()
if( !pPar )
pPar = new SbiParameters( pParser,FALSE,FALSE );
pNd->aVar.pPar = pPar;
+ pNd->aVar.pvMorePar = pvMoreParLcl;
if( bObj )
{
// AB, 8.1.95: Objekt kann auch vom Typ SbxVARIANT sein
@@ -481,11 +500,30 @@ SbiExprNode* SbiExpression::Operand()
pParser->Next();
pRes = new SbiExprNode( pParser, pParser->GetSym() ); break;
case LPAREN:
+ nParenLevel++;
pParser->Next();
pRes = Boolean();
if( pParser->Peek() != RPAREN )
- pParser->Error( SbERR_BAD_BRACKETS );
- else pParser->Next();
+ {
+ // If there was a LPARAM, it does not belong to the expression
+ if( nParenLevel == 1 && m_eMode == EXPRMODE_LPAREN_PENDING )
+ m_eMode = EXPRMODE_LPAREN_NOT_NEEDED;
+ else
+ pParser->Error( SbERR_BAD_BRACKETS );
+ }
+ else
+ {
+ pParser->Next();
+ if( nParenLevel == 1 && m_eMode == EXPRMODE_LPAREN_PENDING )
+ {
+ SbiToken eTokAfterRParen = pParser->Peek();
+ if( eTokAfterRParen == EQ || eTokAfterRParen == LPAREN || eTokAfterRParen == DOT )
+ m_eMode = EXPRMODE_ARRAY_OR_OBJECT;
+ else
+ m_eMode = EXPRMODE_STANDARD;
+ }
+ }
+ nParenLevel--;
pRes->bComposite = TRUE;
break;
default:
@@ -614,6 +652,8 @@ SbiExprNode* SbiExpression::Comp()
for( ;; )
{
SbiToken eTok = pParser->Peek();
+ if( m_eMode == EXPRMODE_ARRAY_OR_OBJECT )
+ break;
if( eTok != EQ && eTok != NE && eTok != LT
&& eTok != GT && eTok != LE && eTok != GE )
break;
@@ -808,45 +848,85 @@ void SbiExprList::addExpression( SbiExpression* pExpr )
// Dann handelt es sich um eine Funktion ohne Parameter
// respektive um die Angabe eines Arrays als Prozedurparameter.
-SbiParameters::SbiParameters( SbiParser* p, BOOL bConst, BOOL bPar) :
+// #i79918/#i80532: bConst has never been set to true
+// -> reused as bStandaloneExpression
+//SbiParameters::SbiParameters( SbiParser* p, BOOL bConst, BOOL bPar) :
+SbiParameters::SbiParameters( SbiParser* p, BOOL bStandaloneExpression, BOOL bPar) :
SbiExprList( p )
{
- if (bPar)
- {
- SbiExpression *pExpr;
- SbiToken eTok = pParser->Peek();
+ if( !bPar )
+ return;
- // evtl. Klammer auf weg:
- if( eTok == LPAREN )
+ SbiExpression *pExpr;
+ SbiToken eTok = pParser->Peek();
+
+ // evtl. Klammer auf weg:
+ bool bAssumeExprLParenMode = false;
+ bool bAssumeArrayMode = false;
+ if( eTok == LPAREN )
+ {
+ if( bStandaloneExpression )
{
- bBracket = TRUE; pParser->Next(); eTok = pParser->Peek();
+ bAssumeExprLParenMode = true;
+ }
+ else
+ {
+ bBracket = TRUE;
+ pParser->Next();
+ eTok = pParser->Peek();
}
+ }
- // Ende-Test
- if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) )
+ // Ende-Test
+ if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) )
+ {
+ if( eTok == RPAREN )
+ pParser->Next();
+ return;
+ }
+ // Parametertabelle einlesen und in richtiger Folge ablegen!
+ SbiExpression* pLast = NULL;
+ String aName;
+ while( !bError )
+ {
+ aName.Erase();
+ // Fehlendes Argument
+ if( eTok == COMMA )
{
- if( eTok == RPAREN )
- pParser->Next();
- return;
+ pExpr = new SbiExpression( pParser, 0, SbxEMPTY );
+ //if( bConst )
+ // pParser->Error( SbERR_SYNTAX ), bError = TRUE;
}
- // Parametertabelle einlesen und in richtiger Folge ablegen!
- SbiExpression* pLast = NULL;
- String aName;
- while( !bError )
+ // Benannte Argumente: entweder .name= oder name:=
+ else
{
- aName.Erase();
- // Fehlendes Argument
- if( eTok == COMMA )
+ if( bAssumeExprLParenMode )
{
- pExpr = new SbiExpression( pParser, 0, SbxEMPTY );
- if( bConst )
- pParser->Error( SbERR_SYNTAX ), bError = TRUE;
+ pExpr = new SbiExpression( pParser, SbSTDEXPR, EXPRMODE_LPAREN_PENDING );
+ bAssumeExprLParenMode = FALSE;
+
+ SbiExprMode eModeAfter = pExpr->m_eMode;
+ if( eModeAfter == EXPRMODE_LPAREN_NOT_NEEDED )
+ {
+ bBracket = TRUE;
+ }
+ else if( eModeAfter == EXPRMODE_ARRAY_OR_OBJECT )
+ {
+ // Expression "looks" like an array assignment
+ // a(...)[(...)] = ? or a(...).b(...)
+ // RPAREN is already parsed
+ bBracket = TRUE;
+ bAssumeArrayMode = true;
+ eTok = NIL;
+ }
}
- // Benannte Argumente: entweder .name= oder name:=
else
+ pExpr = new SbiExpression( pParser );
+
+ //pExpr = bConst ? new SbiConstExpression( pParser )
+ // : new SbiExpression( pParser );
+ if( !bAssumeArrayMode )
{
- pExpr = bConst ? new SbiConstExpression( pParser )
- : new SbiExpression( pParser );
if( pParser->Peek() == ASSIGN )
{
// VBA mode: name:=
@@ -855,50 +935,54 @@ SbiParameters::SbiParameters( SbiParser* p, BOOL bConst, BOOL bPar) :
delete pExpr;
pParser->Next();
pExpr = new SbiExpression( pParser );
- if( bConst )
- pParser->Error( SbERR_SYNTAX ), bError = TRUE;
+ //if( bConst )
+ // pParser->Error( SbERR_SYNTAX ), bError = TRUE;
}
pExpr->GetName() = aName;
}
- pExpr->pNext = NULL;
- if( !pLast )
- pFirst = pLast = pExpr;
- else
- pLast->pNext = pExpr, pLast = pExpr;
- nExpr++;
- bError |= !pExpr->IsValid();
- // Naechstes Element?
- eTok = pParser->Peek();
- if( eTok != COMMA )
- {
- if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) )
- break;
- pParser->Error( bBracket
- ? SbERR_BAD_BRACKETS
- : SbERR_EXPECTED, COMMA );
- bError = TRUE;
- }
- else
- {
- pParser->Next();
- eTok = pParser->Peek();
- if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) )
- break;
- }
}
- // Schliessende Klammer
- if( eTok == RPAREN )
+ pExpr->pNext = NULL;
+ if( !pLast )
+ pFirst = pLast = pExpr;
+ else
+ pLast->pNext = pExpr, pLast = pExpr;
+ nExpr++;
+ bError |= !pExpr->IsValid();
+
+ if( bAssumeArrayMode )
+ break;
+
+ // Naechstes Element?
+ eTok = pParser->Peek();
+ if( eTok != COMMA )
+ {
+ if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) )
+ break;
+ pParser->Error( bBracket
+ ? SbERR_BAD_BRACKETS
+ : SbERR_EXPECTED, COMMA );
+ bError = TRUE;
+ }
+ else
{
pParser->Next();
- pParser->Peek();
- if( !bBracket )
- {
- pParser->Error( SbERR_BAD_BRACKETS );
- bError = TRUE;
- }
+ eTok = pParser->Peek();
+ if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) )
+ break;
+ }
+ }
+ // Schliessende Klammer
+ if( eTok == RPAREN )
+ {
+ pParser->Next();
+ pParser->Peek();
+ if( !bBracket )
+ {
+ pParser->Error( SbERR_BAD_BRACKETS );
+ bError = TRUE;
}
- nDim = nExpr;
}
+ nDim = nExpr;
}
/***************************************************************************