667 lines
27 KiB
C++
667 lines
27 KiB
C++
/*************************************************************************
|
|
*
|
|
* $RCSfile: compiler.hxx,v $
|
|
*
|
|
* $Revision: 1.15 $
|
|
*
|
|
* last change: $Author: hr $ $Date: 2003-03-26 18:03:34 $
|
|
*
|
|
* The Contents of this file are made available subject to the terms of
|
|
* either of the following licenses
|
|
*
|
|
* - GNU Lesser General Public License Version 2.1
|
|
* - Sun Industry Standards Source License Version 1.1
|
|
*
|
|
* Sun Microsystems Inc., October, 2000
|
|
*
|
|
* GNU Lesser General Public License Version 2.1
|
|
* =============================================
|
|
* Copyright 2000 by Sun Microsystems, Inc.
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License version 2.1, as published by the Free Software Foundation.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
* MA 02111-1307 USA
|
|
*
|
|
*
|
|
* Sun Industry Standards Source License Version 1.1
|
|
* =================================================
|
|
* The contents of this file are subject to the Sun Industry Standards
|
|
* Source License Version 1.1 (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.openoffice.org/license.html.
|
|
*
|
|
* Software provided under this License is provided on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
|
|
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
|
|
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
|
|
* See the License for the specific provisions governing your rights and
|
|
* obligations concerning the Software.
|
|
*
|
|
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
|
|
*
|
|
* Copyright: 2000 by Sun Microsystems, Inc.
|
|
*
|
|
* All Rights Reserved.
|
|
*
|
|
* Contributor(s): _______________________________________
|
|
*
|
|
*
|
|
************************************************************************/
|
|
|
|
#ifndef SC_COMPILER_HXX
|
|
#define SC_COMPILER_HXX
|
|
|
|
#include <string.h> // wg. memcpy() und bitte nicht memory.h (WKC)
|
|
|
|
#ifndef _SVMEMPOOL_HXX //autogen
|
|
#include <tools/mempool.hxx>
|
|
#endif
|
|
|
|
#ifndef SC_SCGLOB_HXX
|
|
#include "global.hxx"
|
|
#endif
|
|
|
|
#ifndef SC_TOKEN_HXX
|
|
#include "token.hxx"
|
|
#endif
|
|
|
|
#ifndef _UNOTOOLS_CHARCLASS_HXX
|
|
#include <unotools/charclass.hxx>
|
|
#endif
|
|
|
|
#ifndef _RTL_USTRBUF_HXX_
|
|
#include <rtl/ustrbuf.hxx>
|
|
#endif
|
|
#include <hash_map>
|
|
|
|
//-----------------------------------------------
|
|
|
|
// Konstanten und Datentypen auch fuer externe Module (Interpreter etc.):
|
|
|
|
#define MAXCODE 512 // Maximale Anzahl Tokens
|
|
#define MAXSTRLEN 256 // Maximale Laenge fuer Eingabestring
|
|
// (auch Formeln), "Verlaengerung" durch
|
|
// Namensvergabe moeglich
|
|
#define MAXJUMPCOUNT 32
|
|
#define MAXMATSIZE 100
|
|
#define SC_DOUBLE_MAXVALUE 1.7e307
|
|
|
|
#define errIllegalChar 501
|
|
#define errIllegalArgument 502
|
|
#define errIllegalFPOperation 503
|
|
#define errIllegalParameter 504
|
|
#define errIllegalJump 505
|
|
#define errSeparator 506
|
|
#define errPair 507
|
|
#define errPairExpected 508
|
|
#define errOperatorExpected 509
|
|
#define errVariableExpected 510
|
|
#define errParameterExpected 511
|
|
#define errCodeOverflow 512
|
|
#define errStringOverflow 513
|
|
#define errStackOverflow 514
|
|
#define errUnknownState 515
|
|
#define errUnknownVariable 516
|
|
#define errUnknownOpCode 517
|
|
#define errUnknownStackVariable 518
|
|
#define errNoValue 519
|
|
#define errUnknownToken 520
|
|
#define errNoCode 521
|
|
#define errCircularReference 522
|
|
#define errNoConvergence 523
|
|
#define errNoRef 524
|
|
#define errNoName 525
|
|
#define errDoubleRef 526
|
|
#define errInterpOverflow 527
|
|
// wird nicht angezeigt, temporaer fuer TrackFormulas
|
|
// Zelle haengt von einer ab, die errCircularReference ist
|
|
#define errTrackFromCircRef 528
|
|
// Interpreter internal: existing cell has no value but value queried
|
|
#define errCellNoValue 529
|
|
// Interpreter: needed AddIn not found
|
|
#define errNoAddin 530
|
|
// Interpreter: needed Macro not found
|
|
#define errNoMacro 531
|
|
|
|
#define NOVALUE 0x7fff
|
|
|
|
|
|
// flag values of CharTable
|
|
#define SC_COMPILER_C_ILLEGAL 0x00000000
|
|
#define SC_COMPILER_C_CHAR 0x00000001
|
|
#define SC_COMPILER_C_CHAR_BOOL 0x00000002
|
|
#define SC_COMPILER_C_CHAR_WORD 0x00000004
|
|
#define SC_COMPILER_C_CHAR_VALUE 0x00000008
|
|
#define SC_COMPILER_C_CHAR_STRING 0x00000010
|
|
#define SC_COMPILER_C_CHAR_DONTCARE 0x00000020
|
|
#define SC_COMPILER_C_BOOL 0x00000040
|
|
#define SC_COMPILER_C_WORD 0x00000080 // auch in spstring.cxx dekl.
|
|
#define SC_COMPILER_C_WORD_SEP 0x00000100 // und rangenam.cxx (WORD und CHAR_WORD)
|
|
#define SC_COMPILER_C_VALUE 0x00000200
|
|
#define SC_COMPILER_C_VALUE_SEP 0x00000400
|
|
#define SC_COMPILER_C_VALUE_EXP 0x00000800
|
|
#define SC_COMPILER_C_VALUE_SIGN 0x00001000
|
|
#define SC_COMPILER_C_VALUE_VALUE 0x00002000
|
|
#define SC_COMPILER_C_STRING_SEP 0x00004000
|
|
#define SC_COMPILER_C_NAME_SEP 0x00008000 // es kann nur einen geben! '\''
|
|
#define SC_COMPILER_C_CHAR_IDENT 0x00010000 // identifier (built-in function) start
|
|
#define SC_COMPILER_C_IDENT 0x00020000 // identifier continuation
|
|
|
|
#define SC_COMPILER_FILE_TAB_SEP '#' // 'Doc'#Tab auch in global2.cxx
|
|
|
|
|
|
class ScDocument;
|
|
class ScMatrix;
|
|
class ScRangeData;
|
|
|
|
// Konstanten und Datentypen compilerintern:
|
|
|
|
|
|
#if 0
|
|
/*
|
|
OpCode eOp; // OpCode
|
|
StackVar eType; // type of data
|
|
USHORT nRefCnt; // reference count
|
|
BOOL bRaw; // nicht per Clone auf passende Groesse getrimmt
|
|
*/
|
|
#endif
|
|
|
|
#define SC_TOKEN_FIX_MEMBERS \
|
|
OpCode eOp; \
|
|
StackVar eType; \
|
|
USHORT nRefCnt; \
|
|
BOOL bRaw;
|
|
|
|
struct ScDoubleRawToken
|
|
{
|
|
private:
|
|
SC_TOKEN_FIX_MEMBERS
|
|
public:
|
|
union
|
|
{ // union nur um gleiches Alignment wie ScRawToken sicherzustellen
|
|
double nValue;
|
|
BYTE cByte;
|
|
};
|
|
DECL_FIXEDMEMPOOL_NEWDEL( ScDoubleRawToken );
|
|
};
|
|
|
|
struct ScRawToken
|
|
{
|
|
friend class ScCompiler;
|
|
// Friends, die temporaere Raw-Tokens auf dem Stack benutzen (und deswegen
|
|
// den private dtor brauchen) und wissen, was sie tun..
|
|
friend class ScTokenArray;
|
|
friend class ScInterpreter;
|
|
private:
|
|
SC_TOKEN_FIX_MEMBERS
|
|
public:
|
|
union {
|
|
double nValue;
|
|
ComplRefData aRef;
|
|
BYTE cByte;
|
|
ScMatrix* pMat;
|
|
USHORT nIndex; // Index fuer Name-Tabelle
|
|
sal_Unicode cStr[ MAXSTRLEN+1 ]; // String (bis 255 Zeichen + 0)
|
|
short nJump[MAXJUMPCOUNT+1]; // If/Chose-Token
|
|
};
|
|
|
|
ScRawToken() : bRaw( TRUE ) {}
|
|
private:
|
|
~ScRawToken() {} //! nur via Delete() loeschen
|
|
public:
|
|
DECL_FIXEDMEMPOOL_NEWDEL( ScRawToken );
|
|
StackVar GetType() const { return (StackVar) eType; }
|
|
OpCode GetOpCode() const { return (OpCode) eOp; }
|
|
void NewOpCode( OpCode e ) { eOp = e; }
|
|
void IncRef() { nRefCnt++; }
|
|
void DecRef() { if( !--nRefCnt ) Delete(); }
|
|
USHORT GetRef() const { return nRefCnt; }
|
|
void Delete();
|
|
|
|
// Diese Methoden nur auf Tokens, die nicht im TokenArray stehen,
|
|
// anwenden, da der RefCount auf 0 gesetzt wird!
|
|
void SetOpCode( OpCode eCode );
|
|
void SetString( const sal_Unicode* pStr );
|
|
void SetSingleReference( const SingleRefData& rRef );
|
|
void SetDoubleReference( const ComplRefData& rRef );
|
|
void SetByte( BYTE c );
|
|
void SetDouble( double fVal );
|
|
void SetInt( int nVal );
|
|
void SetName( USHORT n );
|
|
void SetMatrix( ScMatrix* p );
|
|
void SetExternal(const sal_Unicode* pStr);
|
|
// Diese Methoden sind hingegen OK.
|
|
ComplRefData& GetReference();
|
|
void SetReference( ComplRefData& rRef );
|
|
|
|
ScRawToken* Clone() const; // real copy!
|
|
ScToken* CreateToken() const; // create typified token
|
|
void Load30( SvStream& );
|
|
void Load( SvStream&, USHORT nVer );
|
|
|
|
static xub_StrLen GetStrLen( const sal_Unicode* pStr ); // as long as a "string" is an array
|
|
static size_t GetStrLenBytes( xub_StrLen nLen )
|
|
{ return nLen * sizeof(sal_Unicode); }
|
|
static size_t GetStrLenBytes( const sal_Unicode* pStr )
|
|
{ return GetStrLenBytes( GetStrLen( pStr ) ); }
|
|
};
|
|
|
|
|
|
class ScRawTokenRef
|
|
{
|
|
ScRawToken* p;
|
|
public:
|
|
inline ScRawTokenRef() { p = NULL; }
|
|
inline ScRawTokenRef( const ScRawTokenRef& r ) { if( ( p = r.p ) != NULL ) p->IncRef(); }
|
|
inline ScRawTokenRef( ScRawToken *t ) { if( ( p = t ) != NULL ) t->IncRef(); }
|
|
inline void Clear() { if( p ) p->DecRef(); }
|
|
inline ~ScRawTokenRef() { if( p ) p->DecRef(); }
|
|
inline ScRawTokenRef& operator=( const ScRawTokenRef& r ) { return *this = r.p; }
|
|
inline ScRawTokenRef& operator=( ScRawToken* t )
|
|
{ if( t ) t->IncRef(); if( p ) p->DecRef(); p = t; return *this; }
|
|
inline BOOL Is() const { return p != NULL; }
|
|
inline BOOL operator ! () const { return p == NULL; }
|
|
inline ScRawToken* operator&() const { return p; }
|
|
inline ScRawToken* operator->() const { return p; }
|
|
inline ScRawToken& operator*() const { return *p; }
|
|
inline operator ScRawToken*() const { return p; }
|
|
};
|
|
|
|
|
|
enum ScRecalcMode40
|
|
{ // alter RecalcMode bis einschliesslich 4.0
|
|
RC_NORMAL,
|
|
RC_ALWAYS,
|
|
RC_ONLOAD, // immer nach dem Laden
|
|
RC_ONLOAD_ONCE, // einmal nach dem Laden
|
|
RC_FORCED, // auch wenn Zelle nicht sichtbar
|
|
RC_ONREFMOVE // wenn Referenz bewegt wurde (ab SP3, 05.11.97)
|
|
};
|
|
|
|
// neuer (ab 5.0, 14.01.98) RecalcMode Zugriff nur noch noch via TokenArray
|
|
// SetRecalcMode / IsRecalcMode...
|
|
|
|
typedef BYTE ScRecalcMode;
|
|
// von den exklusiven Bits kann nur eins gesetzt sein
|
|
// wird von TokenArray SetRecalcMode... Methoden gehandelt
|
|
#define RECALCMODE_NORMAL 0x01 // exklusiv
|
|
#define RECALCMODE_ALWAYS 0x02 // exklusiv, immer
|
|
#define RECALCMODE_ONLOAD 0x04 // exklusiv, immer nach dem Laden
|
|
#define RECALCMODE_ONLOAD_ONCE 0x08 // exklusiv, einmal nach dem Laden
|
|
#define RECALCMODE_FORCED 0x10 // kombiniert, auch wenn Zelle nicht sichtbar
|
|
#define RECALCMODE_ONREFMOVE 0x20 // kombiniert, wenn Referenz bewegt wurde
|
|
#define RECALCMODE_EMASK 0x0F // Maske der exklusiven Bits
|
|
// werden neue Bits definiert, muessen ExportRecalcMode40 und AddRecalcMode
|
|
// angepasst werden!
|
|
|
|
class ScTokenArray
|
|
{
|
|
friend class ScCompiler;
|
|
friend class ScTokenIterator;
|
|
|
|
ScToken** pCode; // Token code array
|
|
ScToken** pRPN; // RPN array
|
|
USHORT nLen; // Length of token array
|
|
USHORT nRPN; // Length of RPN array
|
|
USHORT nIndex; // Current step index
|
|
USHORT nError; // Error code
|
|
short nRefs; // Count of cell references
|
|
ScRecalcMode nMode; // Flags to indicate when to recalc this code
|
|
BOOL bReplacedSharedFormula; // If code was created by replacing
|
|
// a shared formula, a temporary flag during
|
|
// UpdateReference() until StartListeningTo()
|
|
|
|
void Assign( const ScTokenArray& );
|
|
|
|
ScToken* Add( ScToken* );
|
|
void ImportRecalcMode40( ScRecalcMode40 );
|
|
ScRecalcMode40 ExportRecalcMode40() const;
|
|
inline void SetCombinedBitsRecalcMode( ScRecalcMode nBits )
|
|
{ nMode |= (nBits & ~RECALCMODE_EMASK); }
|
|
inline ScRecalcMode GetCombinedBitsRecalcMode() const
|
|
{ return nMode & ~RECALCMODE_EMASK; }
|
|
inline void SetMaskedRecalcMode( ScRecalcMode nBits )
|
|
{ nMode = GetCombinedBitsRecalcMode() | nBits; }
|
|
// in nMode gesetzte exklusive Bits werden genullt,
|
|
// nVal kann auch kombinierte Bits enthalten,
|
|
// aber nur ein exklusives Bit darf gesetzt sein!
|
|
|
|
BOOL ImplGetReference( ScRange& rRange, BOOL bValidOnly ) const;
|
|
|
|
public:
|
|
ScTokenArray();
|
|
ScTokenArray( const ScTokenArray& ); // Zuweisung mit Referenzen auf Tokens
|
|
~ScTokenArray();
|
|
ScTokenArray* Clone() const; // echte Kopie!
|
|
void Clear();
|
|
void DelRPN();
|
|
ScToken* First() { nIndex = 0; return Next(); }
|
|
ScToken* Next();
|
|
ScToken* GetNextName();
|
|
ScToken* GetNextDBArea();
|
|
ScToken* GetNextReference();
|
|
ScToken* GetNextReferenceRPN();
|
|
ScToken* GetNextReferenceOrName();
|
|
ScToken* GetNextColRowName();
|
|
ScToken* GetNextOpCodeRPN( OpCode );
|
|
ScToken* PeekNext();
|
|
ScToken* PeekPrevNoSpaces(); // nur nach First/Next/Last/Prev !
|
|
ScToken* PeekNextNoSpaces(); // nur nach First/Next/Last/Prev !
|
|
ScToken* FirstRPN() { nIndex = 0; return NextRPN(); }
|
|
ScToken* NextRPN();
|
|
ScToken* LastRPN() { nIndex = nRPN; return PrevRPN(); }
|
|
ScToken* PrevRPN();
|
|
|
|
BOOL HasOpCodeRPN( OpCode ) const;
|
|
BOOL HasName() const; // token of type svIndex
|
|
BOOL HasNameOrColRowName() const; // token of type svIndex or opcode ocColRowName
|
|
BOOL IsReference( ScRange& rRange ) const; // exactly and only one range (valid or deleted)
|
|
BOOL IsValidReference( ScRange& rRange ) const; // exactly and only one valid range (no #REF!s)
|
|
BOOL GetTableOpRefs( // exactly and only one multiple operation
|
|
ScAddress& rFormula,
|
|
ScAddress& rColFirstPos, ScAddress& rColRelPos,
|
|
ScAddress& rRowFirstPos, ScAddress& rRowRelPos,
|
|
BOOL& rbIsMode2 ) const;
|
|
|
|
ScToken** GetArray() const { return pCode; }
|
|
ScToken** GetCode() const { return pRPN; }
|
|
USHORT GetLen() const { return nLen; }
|
|
USHORT GetCodeLen() const { return nRPN; }
|
|
void Reset() { nIndex = 0; }
|
|
USHORT GetError() const { return nError; }
|
|
void SetError( USHORT n ) { nError = n; }
|
|
short GetRefs() const { return nRefs; }
|
|
void SetReplacedSharedFormula( BOOL bVal ) { bReplacedSharedFormula = bVal; }
|
|
BOOL IsReplacedSharedFormula() const { return bReplacedSharedFormula; }
|
|
|
|
inline ScRecalcMode GetRecalcMode() const { return nMode; }
|
|
void AddRecalcMode( ScRecalcMode nBits );
|
|
// Bits werden nicht direkt gesetzt sondern
|
|
// geprueft und evtl. nach Prio behandelt,
|
|
// wenn mehrere exklusive gesetzt sind!
|
|
|
|
inline void ClearRecalcMode() { nMode = RECALCMODE_NORMAL; }
|
|
inline void SetRecalcModeNormal()
|
|
{ SetMaskedRecalcMode( RECALCMODE_NORMAL ); }
|
|
inline void SetRecalcModeAlways()
|
|
{ SetMaskedRecalcMode( RECALCMODE_ALWAYS ); }
|
|
inline void SetRecalcModeOnLoad()
|
|
{ SetMaskedRecalcMode( RECALCMODE_ONLOAD ); }
|
|
inline void SetRecalcModeOnLoadOnce()
|
|
{ SetMaskedRecalcMode( RECALCMODE_ONLOAD_ONCE ); }
|
|
inline void SetRecalcModeForced()
|
|
{ nMode |= RECALCMODE_FORCED; }
|
|
inline void ClearRecalcModeForced()
|
|
{ nMode &= ~RECALCMODE_FORCED; }
|
|
inline void SetRecalcModeOnRefMove()
|
|
{ nMode |= RECALCMODE_ONREFMOVE; }
|
|
inline void ClearRecalcModeOnRefMove()
|
|
{ nMode &= ~RECALCMODE_ONREFMOVE; }
|
|
inline BOOL IsRecalcModeNormal() const
|
|
{ return (nMode & RECALCMODE_NORMAL) != 0; }
|
|
inline BOOL IsRecalcModeAlways() const
|
|
{ return (nMode & RECALCMODE_ALWAYS) != 0; }
|
|
inline BOOL IsRecalcModeOnLoad() const
|
|
{ return (nMode & RECALCMODE_ONLOAD) != 0; }
|
|
inline BOOL IsRecalcModeOnLoadOnce() const
|
|
{ return (nMode & RECALCMODE_ONLOAD_ONCE) != 0; }
|
|
inline BOOL IsRecalcModeForced() const
|
|
{ return (nMode & RECALCMODE_FORCED) != 0; }
|
|
inline BOOL IsRecalcModeOnRefMove() const
|
|
{ return (nMode & RECALCMODE_ONREFMOVE) != 0; }
|
|
|
|
inline OpCode GetOuterFuncOpCode(); // OpCode der aeusseren Funktion
|
|
// ermittelt Ausdehnung direkt angrenzender Refs
|
|
// nur auf echte Funcs wie z.B. GetOuterFuncOpCode() == ocSum anwenden!
|
|
BOOL GetAdjacentExtendOfOuterFuncRefs( USHORT& nExtend,
|
|
const ScAddress& rPos, ScDirection );
|
|
|
|
// Operatoren +,-,*,/,^,&,=,<>,<,>,<=,>=
|
|
// mit DoubleRef in Formel?
|
|
BOOL HasMatrixDoubleRefOps();
|
|
|
|
void Load30( SvStream&, const ScAddress& );
|
|
void Load( SvStream&, USHORT, const ScAddress& );
|
|
void Store( SvStream&, const ScAddress& ) const;
|
|
|
|
ScToken* AddToken( const ScRawToken& );
|
|
ScToken* AddToken( const ScToken& );
|
|
ScToken* AddOpCode( OpCode eCode );
|
|
ScToken* AddString( const sal_Unicode* pStr );
|
|
ScToken* AddString( const String& rStr );
|
|
ScToken* AddDouble( double fVal );
|
|
ScToken* AddSingleReference( const SingleRefData& rRef );
|
|
ScToken* AddDoubleReference( const ComplRefData& rRef );
|
|
ScToken* AddName( USHORT n );
|
|
ScToken* AddMatrix( ScMatrix* p );
|
|
ScToken* AddExternal( const sal_Unicode* pStr );
|
|
ScToken* AddExternal( const String& rStr );
|
|
ScToken* AddColRowName( const SingleRefData& rRef );
|
|
ScToken* AddBad( const sal_Unicode* pStr ); // ocBad with String
|
|
ScToken* AddBad( const String& rStr ); // ocBad with String
|
|
|
|
// Zuweisung mit Referenzen auf Tokens
|
|
ScTokenArray& operator=( const ScTokenArray& );
|
|
|
|
// make 3D references point to old referenced position even if relative
|
|
void ReadjustRelative3DReferences(
|
|
const ScAddress& rOldPos,
|
|
const ScAddress& rNewPos );
|
|
};
|
|
|
|
inline OpCode ScTokenArray::GetOuterFuncOpCode()
|
|
{
|
|
if ( pRPN && nRPN )
|
|
return pRPN[nRPN-1]->GetOpCode();
|
|
return ocNone;
|
|
}
|
|
|
|
struct ImpTokenIterator;
|
|
|
|
class ScTokenIterator
|
|
{
|
|
friend class ScInterpreter; // fuer Jump()
|
|
ImpTokenIterator* pCur;
|
|
void Jump( short nStart, short nNext );
|
|
void Push( ScTokenArray* );
|
|
void Pop();
|
|
public:
|
|
ScTokenIterator( const ScTokenArray& );
|
|
~ScTokenIterator();
|
|
void Reset();
|
|
const ScToken* First();
|
|
const ScToken* Next();
|
|
};
|
|
|
|
struct ScArrayStack;
|
|
|
|
struct ScStringHashCode
|
|
{
|
|
size_t operator()( const String& rStr ) const
|
|
{
|
|
return rtl_ustr_hashCode_WithLength( rStr.GetBuffer(), rStr.Len() );
|
|
}
|
|
};
|
|
typedef ::std::hash_map< String, OpCode, ScStringHashCode, ::std::equal_to< String > > ScOpCodeHashMap;
|
|
|
|
class ScCompiler
|
|
{
|
|
public:
|
|
static String* pSymbolTableNative; // array of native symbols, offset==OpCode
|
|
static String* pSymbolTableEnglish; // array of English symbols, offset==OpCode
|
|
static USHORT nAnzStrings; // count of symbols
|
|
static ScOpCodeHashMap* pSymbolHashMapNative; // hash map of native symbols
|
|
static ScOpCodeHashMap* pSymbolHashMapEnglish; // hash map of English symbols
|
|
private:
|
|
static ULONG* pCharTable; // array of ASCII character flags
|
|
ScDocument* pDoc;
|
|
ScAddress aPos;
|
|
String cFormula; // String -> TokenArray
|
|
String aCorrectedFormula; // autocorrected Formula
|
|
String aCorrectedSymbol; // autocorrected Symbol
|
|
sal_Unicode cSymbol[MAXSTRLEN]; // current Symbol
|
|
String aFormula; // formula source code
|
|
xub_StrLen nSrcPos; // tokenizer position (source code)
|
|
ScTokenArray* pArr;
|
|
ScRawTokenRef pRawToken;
|
|
ScTokenRef pToken;
|
|
OpCode eLastOp;
|
|
ScToken** pCode;
|
|
ScArrayStack* pStack;
|
|
String* pSymbolTable; // which symbol table is used
|
|
ScOpCodeHashMap* pSymbolHashMap; // which symbol hash map is used
|
|
USHORT pc;
|
|
short nNumFmt; // bei CompileTokenArray() gesetzt
|
|
short nMaxTab; // letzte Tabelle im Doc
|
|
short nRecursion; // GetToken Rekursionen
|
|
BOOL glSubTotal; // Merkvariablen fuer Zelle
|
|
BOOL bAutoCorrect; // AutoCorrection ausfuehren
|
|
BOOL bCorrected; // AutoCorrection ausgefuehrt
|
|
BOOL bCompileForFAP; //! kein echtes RPN sondern Namen
|
|
// werden nicht aufgeloest
|
|
BOOL bIgnoreErrors; // bei AutoCorrect und CompileForFAP
|
|
// trotz Fehler RPN erzeugen
|
|
BOOL bCompileXML;
|
|
BOOL bImportXML;
|
|
|
|
BOOL GetToken();
|
|
BOOL NextNewToken();
|
|
OpCode NextToken();
|
|
void PutCode( ScRawToken* );
|
|
void PutCode( ScToken* );
|
|
void Factor();
|
|
void UnionCutLine();
|
|
void Unary();
|
|
void PowLine();
|
|
void MulDivLine();
|
|
void AddSubLine();
|
|
void ConcatLine();
|
|
void CompareLine();
|
|
void NotLine();
|
|
OpCode Expression();
|
|
|
|
String MakeColStr( USHORT nCol );
|
|
void MakeColStr( rtl::OUStringBuffer& rBuffer, USHORT nCol );
|
|
String MakeRowStr( USHORT nRow );
|
|
void MakeRowStr( rtl::OUStringBuffer& rBuffer, USHORT nRow );
|
|
String MakeTabStr( USHORT nTab, String& aDoc );
|
|
String MakeRefStr( ComplRefData& rRefData, BOOL bSingleRef );
|
|
void MakeRefStr( rtl::OUStringBuffer& rBuffer, ComplRefData& rRefData, BOOL bSingleRef );
|
|
|
|
void SetError(USHORT nError);
|
|
xub_StrLen NextSymbol();
|
|
BOOL IsValue( const String& );
|
|
BOOL IsOpCode( const String& );
|
|
BOOL IsOpCode2( const String& );
|
|
BOOL IsString();
|
|
BOOL IsReference( const String& );
|
|
BOOL IsMacro( const String& );
|
|
BOOL IsNamedRange( const String& );
|
|
BOOL IsDBRange( const String& );
|
|
BOOL IsColRowName( const String& );
|
|
void AutoCorrectParsedSymbol();
|
|
void AdjustReference( SingleRefData& r );
|
|
void PushTokenArray( ScTokenArray*, BOOL = FALSE );
|
|
void PopTokenArray();
|
|
void SetRelNameReference();
|
|
public:
|
|
ScCompiler(ScDocument* pDocument, const ScAddress& );
|
|
|
|
ScCompiler( ScDocument* pDocument, const ScAddress&,
|
|
const ScTokenArray& rArr );
|
|
|
|
static void Init();
|
|
static void DeInit();
|
|
static void CheckTabQuotes( String& ); // fuer ScAddress::Format()
|
|
|
|
// schliesst String in Quotes ein, wenn nicht-alphanumerische Zeichen
|
|
// enthalten sind, bestehende Quotes werden escaped
|
|
static BOOL EnQuote( String& );
|
|
// entfernt Quotes, escaped Quotes werden unescaped
|
|
static BOOL DeQuote( String& );
|
|
|
|
//! _entweder_ CompileForFAP _oder_ AutoCorrection, _nicht_ beides
|
|
void SetCompileForFAP( BOOL bVal )
|
|
{ bCompileForFAP = bVal; bIgnoreErrors = bVal; }
|
|
void SetAutoCorrection( BOOL bVal )
|
|
{ bAutoCorrect = bVal; bIgnoreErrors = bVal; }
|
|
void SetCompileEnglish( BOOL bVal ); // use English SymbolTable
|
|
void SetCompileXML( BOOL bVal )
|
|
{ bCompileXML = bVal; }
|
|
void SetImportXML( BOOL bVal )
|
|
{ bImportXML = bVal; }
|
|
BOOL IsCorrected() { return bCorrected; }
|
|
const String& GetCorrectedFormula() { return aCorrectedFormula; }
|
|
ScTokenArray* CompileString( const String& rFormula );
|
|
BOOL CompileTokenArray();
|
|
short GetNumFormatType() { return nNumFmt; }
|
|
|
|
ScToken* CreateStringFromToken( String& rFormula, ScToken* pToken,
|
|
BOOL bAllowArrAdvance = FALSE );
|
|
ScToken* CreateStringFromToken( rtl::OUStringBuffer& rBuffer, ScToken* pToken,
|
|
BOOL bAllowArrAdvance = FALSE );
|
|
void CreateStringFromTokenArray( String& rFormula );
|
|
void CreateStringFromTokenArray( rtl::OUStringBuffer& rBuffer );
|
|
|
|
void MoveRelWrap();
|
|
static void MoveRelWrap( ScTokenArray& rArr, ScDocument* pDoc,
|
|
const ScAddress& rPos );
|
|
|
|
BOOL UpdateNameReference( UpdateRefMode eUpdateRefMode,
|
|
const ScRange&,
|
|
short nDx, short nDy, short nDz,
|
|
BOOL& rChanged);
|
|
|
|
ScRangeData* UpdateReference( UpdateRefMode eUpdateRefMode,
|
|
const ScAddress& rOldPos, const ScRange&,
|
|
short nDx, short nDy, short nDz,
|
|
BOOL& rChanged);
|
|
|
|
/// Only once for converted shared formulas,
|
|
/// token array has to be compiled afterwards.
|
|
void UpdateSharedFormulaReference( UpdateRefMode eUpdateRefMode,
|
|
const ScAddress& rOldPos, const ScRange&,
|
|
short nDx, short nDy, short nDz );
|
|
|
|
ScRangeData* UpdateInsertTab(USHORT nTable, BOOL bIsName );
|
|
ScRangeData* UpdateDeleteTab(USHORT nTable, BOOL bIsMove, BOOL bIsName, BOOL& bCompile);
|
|
ScRangeData* UpdateMoveTab(USHORT nOldPos, USHORT nNewPos, BOOL bIsName );
|
|
|
|
BOOL HasModifiedRange();
|
|
|
|
/// Is the CharTable initialized? If not call Init() yourself!
|
|
static inline BOOL HasCharTable() { return pCharTable != NULL; }
|
|
|
|
/// Access the CharTable flags
|
|
static inline ULONG GetCharTableFlags( sal_Unicode c )
|
|
{ return c < 128 ? pCharTable[ UINT8(c) ] : 0; }
|
|
|
|
/// If the character is allowed as first character in sheet names or references
|
|
static inline BOOL IsCharWordChar( sal_Unicode c )
|
|
{
|
|
return c < 128 ?
|
|
((pCharTable[ UINT8(c) ] & SC_COMPILER_C_CHAR_WORD) == SC_COMPILER_C_CHAR_WORD) :
|
|
ScGlobal::pCharClass->isLetterNumeric( c );
|
|
}
|
|
|
|
/// If the character is allowed in sheet names or references
|
|
static inline BOOL IsWordChar( sal_Unicode c )
|
|
{
|
|
return c < 128 ?
|
|
((pCharTable[ UINT8(c) ] & SC_COMPILER_C_WORD) == SC_COMPILER_C_WORD) :
|
|
ScGlobal::pCharClass->isLetterNumeric( c );
|
|
}
|
|
};
|
|
|
|
#endif
|