/src/libreoffice/include/formula/FormulaCompiler.hxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | |
20 | | #pragma once |
21 | | |
22 | | #include <memory> |
23 | | #include <unordered_map> |
24 | | #include <vector> |
25 | | #include <optional> |
26 | | |
27 | | #include <com/sun/star/uno/Sequence.hxx> |
28 | | #include <formula/formuladllapi.h> |
29 | | #include <formula/grammar.hxx> |
30 | | #include <formula/opcode.hxx> |
31 | | #include <formula/tokenarray.hxx> |
32 | | #include <formula/types.hxx> |
33 | | #include <formula/paramclass.hxx> |
34 | | #include <rtl/ustrbuf.hxx> |
35 | | #include <rtl/ustring.hxx> |
36 | | #include <sal/types.h> |
37 | | #include <tools/debug.hxx> |
38 | | #include <unotools/saveopt.hxx> |
39 | | |
40 | 80.1k | #define FORMULA_MAXJUMPCOUNT 32 /* maximum number of jumps (ocChoose) */ |
41 | 36.9M | #define FORMULA_MAXTOKENS 8192 /* maximum number of tokens in formula */ |
42 | 3.04M | #define FORMULA_MAXPARAMS 255 /* maximum number of parameters per function (byte) */ |
43 | 4.03M | #define FORMULA_MAXPARAMSII 8 /* maximum number of parameters for functions that have implicit intersection ranges */ |
44 | | |
45 | | |
46 | | namespace com::sun::star { |
47 | | namespace sheet { |
48 | | struct FormulaOpCodeMapEntry; |
49 | | struct FormulaToken; |
50 | | } |
51 | | } |
52 | | |
53 | | class CharClass; |
54 | | enum class FormulaError : sal_uInt16; |
55 | | enum class SvNumFormatType : sal_Int16; |
56 | | |
57 | | namespace formula |
58 | | { |
59 | | |
60 | | struct FormulaArrayStack |
61 | | { |
62 | | FormulaArrayStack* pNext; |
63 | | FormulaTokenArray* pArr; |
64 | | FormulaTokenRef mpLastToken; |
65 | | sal_uInt16 nIndex; |
66 | | bool bTemp; |
67 | | }; |
68 | | |
69 | | typedef std::unordered_map< OUString, OpCode > OpCodeHashMap; |
70 | | typedef std::unordered_map< OUString, OUString > ExternalHashMap; |
71 | | |
72 | | class FORMULA_DLLPUBLIC FormulaCompiler |
73 | | { |
74 | | private: |
75 | | FormulaCompiler(const FormulaCompiler&) = delete; |
76 | | FormulaCompiler& operator=(const FormulaCompiler&) = delete; |
77 | | public: |
78 | | FormulaCompiler(bool bComputeII = false, bool bMatrixFlag = false); |
79 | | FormulaCompiler(FormulaTokenArray& _rArr, bool bComputeII = false, bool bMatrixFlag = false); |
80 | | virtual ~FormulaCompiler(); |
81 | | |
82 | | /** Mappings from strings to OpCodes and vice versa. */ |
83 | | class FORMULA_DLLPUBLIC OpCodeMap final |
84 | | { |
85 | | OpCodeHashMap maHashMap; /// Hash map of symbols, OUString -> OpCode |
86 | | std::unique_ptr<OUString[]> mpTable; /// Array of symbols, OpCode -> OUString, offset==OpCode |
87 | | ExternalHashMap maExternalHashMap; /// Hash map of ocExternal, Filter String -> AddIn String |
88 | | ExternalHashMap maReverseExternalHashMap; /// Hash map of ocExternal, AddIn String -> Filter String |
89 | | FormulaGrammar::Grammar meGrammar; /// Grammar, language and reference convention |
90 | | sal_uInt16 mnSymbols; /// Count of OpCode symbols |
91 | | bool mbCore : 1; /// If mapping was setup by core, not filters |
92 | | bool mbEnglish : 1; /// If English symbols and external names |
93 | | bool mbEnglishLocale : 1; /// If English locale for numbers |
94 | | |
95 | | OpCodeMap( const OpCodeMap& ) = delete; |
96 | | OpCodeMap& operator=( const OpCodeMap& ) = delete; |
97 | | |
98 | | public: |
99 | | |
100 | | OpCodeMap(sal_uInt16 nSymbols, bool bCore, FormulaGrammar::Grammar eGrammar ) : |
101 | 10.8k | maHashMap(nSymbols), |
102 | 10.8k | mpTable( new OUString[ nSymbols ]), |
103 | 10.8k | meGrammar( eGrammar), |
104 | 10.8k | mnSymbols( nSymbols), |
105 | 10.8k | mbCore( bCore), |
106 | 10.8k | mbEnglish ( FormulaGrammar::isEnglish(eGrammar) ), |
107 | 10.8k | mbEnglishLocale ( mbEnglish ) |
108 | 10.8k | { |
109 | 10.8k | } |
110 | | |
111 | | /** Copy mappings from r into this map, effectively replacing this map. |
112 | | |
113 | | Override known legacy bad function names with |
114 | | correct ones if the conditions can be derived from the |
115 | | current maps. |
116 | | */ |
117 | | void copyFrom( const OpCodeMap& r ); |
118 | | |
119 | | /// Get the symbol String -> OpCode hash map for finds. |
120 | 15.6M | const OpCodeHashMap& getHashMap() const { return maHashMap; } |
121 | | |
122 | | /// Get the symbol String -> AddIn String hash map for finds. |
123 | 1.82M | const ExternalHashMap& getExternalHashMap() const { return maExternalHashMap; } |
124 | | |
125 | | /// Get the AddIn String -> symbol String hash map for finds. |
126 | 290 | const ExternalHashMap& getReverseExternalHashMap() const { return maReverseExternalHashMap; } |
127 | | |
128 | | /// Get the symbol string matching an OpCode. |
129 | | const OUString& getSymbol( const OpCode eOp ) const |
130 | 38.4M | { |
131 | 38.4M | DBG_ASSERT( sal_uInt16(eOp) < mnSymbols, "OpCodeMap::getSymbol: OpCode out of range"); |
132 | 38.4M | if (sal_uInt16(eOp) < mnSymbols) |
133 | 38.4M | return mpTable[ eOp ]; |
134 | 0 | static OUString s_sEmpty; |
135 | 0 | return s_sEmpty; |
136 | 38.4M | } |
137 | | |
138 | | /// Get the first character of the symbol string matching an OpCode. |
139 | 31.9M | sal_Unicode getSymbolChar( const OpCode eOp ) const { return getSymbol(eOp)[0]; }; |
140 | | |
141 | | /// Get the grammar. |
142 | 2.38M | FormulaGrammar::Grammar getGrammar() const { return meGrammar; } |
143 | | |
144 | | /// Get the symbol count. |
145 | 2.22M | sal_uInt16 getSymbolCount() const { return mnSymbols; } |
146 | | |
147 | | /** Are these English symbols, as opposed to native language (which may |
148 | | be English as well)? */ |
149 | 2.93M | bool isEnglish() const { return mbEnglish; } |
150 | | |
151 | | /** Are inline numbers parsed/formatted in en-US locale, as opposed |
152 | | to default locale? */ |
153 | 27.9M | bool isEnglishLocale() const { return mbEnglishLocale; } |
154 | | |
155 | | /// Is it an ODF 1.1 compatibility mapping? |
156 | 1.25M | bool isPODF() const { return FormulaGrammar::isPODF( meGrammar); } |
157 | | |
158 | | /* TODO: add isAPI() once a FormulaLanguage was added. */ |
159 | | |
160 | | /// Is it an ODFF / ODF 1.2 mapping? |
161 | 1.35M | bool isODFF() const { return FormulaGrammar::isODFF( meGrammar); } |
162 | | |
163 | | /// Is it an OOXML mapping? |
164 | 1.29M | bool isOOXML() const { return FormulaGrammar::isOOXML( meGrammar); } |
165 | | |
166 | | /// Does it have external symbol/name mappings? |
167 | 1.35M | bool hasExternals() const { return !maExternalHashMap.empty(); } |
168 | | |
169 | | /// Put entry of symbol String and OpCode pair. |
170 | | void putOpCode( const OUString & rStr, const OpCode eOp, const CharClass* pCharClass ); |
171 | | |
172 | | /// Put entry of symbol String and AddIn international String pair. |
173 | | void putExternal( const OUString & rSymbol, const OUString & rAddIn ); |
174 | | |
175 | | /** Put entry of symbol String and AddIn international String pair, |
176 | | not warning just info as used for AddIn collection and setting up |
177 | | alias names. */ |
178 | | void putExternalSoftly( const OUString & rSymbol, const OUString & rAddIn ); |
179 | | |
180 | | /// Core implementation of XFormulaOpCodeMapper::getMappings() |
181 | | css::uno::Sequence< css::sheet::FormulaToken > |
182 | | createSequenceOfFormulaTokens(const FormulaCompiler& _rCompiler, |
183 | | const css::uno::Sequence< OUString >& rNames ) const; |
184 | | |
185 | | /// Core implementation of XFormulaOpCodeMapper::getAvailableMappings() |
186 | | css::uno::Sequence< css::sheet::FormulaOpCodeMapEntry > |
187 | | createSequenceOfAvailableMappings( const FormulaCompiler& _rCompiler,const sal_Int32 nGroup ) const; |
188 | | |
189 | | /** The value used in createSequenceOfAvailableMappings() and thus in |
190 | | XFormulaOpCodeMapper::getMappings() for an unknown symbol. */ |
191 | 21.6k | static sal_Int32 getOpCodeUnknown() { return -1; } |
192 | | |
193 | | private: |
194 | | |
195 | | /** Conditionally put a mapping in copyFrom() context. |
196 | | |
197 | | Does NOT check eOp range! |
198 | | */ |
199 | | void putCopyOpCode( const OUString& rSymbol, OpCode eOp, const CharClass* pCharClass ); |
200 | | }; |
201 | | |
202 | | public: |
203 | | typedef std::shared_ptr< const OpCodeMap > OpCodeMapPtr; |
204 | | typedef std::shared_ptr< OpCodeMap > NonConstOpCodeMapPtr; |
205 | | |
206 | | protected: |
207 | | /** Get finalized OpCodeMap for formula language. |
208 | | |
209 | | Creates/returns a singleton instance of an OpCodeMap that contains |
210 | | external AddIn mappings if the derived class supports them. Do not call |
211 | | at this base class as it results in a permanent mapping without AddIns |
212 | | even for derived classes (unless it is for the implementation of the |
213 | | temporary GetOpCodeMap()). |
214 | | |
215 | | @param nLanguage |
216 | | One of css::sheet::FormulaLanguage constants. |
217 | | @return Map for nLanguage. If nLanguage is unknown, a NULL map is returned. |
218 | | */ |
219 | | OpCodeMapPtr GetFinalOpCodeMap( const sal_Int32 nLanguage ) const; |
220 | | |
221 | | public: |
222 | | /** Get OpCodeMap for formula language. |
223 | | |
224 | | Returns either the finalized OpCodeMap (created by GetFinalOpCodeMap() |
225 | | of a derived class) for nLanguage if there is such, or if not then a |
226 | | temporary map of which its singleton is reset immediately and the |
227 | | temporary will get destroyed by the caller's scope. A temporary map |
228 | | created at this base class does *not* contain AddIn mappings. |
229 | | |
230 | | @param nLanguage |
231 | | One of css::sheet::FormulaLanguage constants. |
232 | | @return Map for nLanguage. If nLanguage is unknown, a NULL map is returned. |
233 | | */ |
234 | | OpCodeMapPtr GetOpCodeMap( const sal_Int32 nLanguage ) const; |
235 | | |
236 | | /** Destroy the singleton OpCodeMap for formula language. |
237 | | |
238 | | This unconditionally destroys the underlying singleton instance of the |
239 | | map to be reinitialized again later on the next GetOpCodeMap() call. |
240 | | Use if the base class FormulaCompiler::GetOpCodeMap() was called and |
241 | | created the map (i.e. HasOpCodeMap() before returned false) and later a |
242 | | derived class like ScCompiler shall initialize it including AddIns. |
243 | | |
244 | | @param nLanguage |
245 | | One of css::sheet::FormulaLanguage constants. |
246 | | */ |
247 | | void DestroyOpCodeMap( const sal_Int32 nLanguage ); |
248 | | |
249 | | /** Whether the singleton OpCodeMap for formula language exists already. |
250 | | |
251 | | @param nLanguage |
252 | | One of css::sheet::FormulaLanguage constants. |
253 | | */ |
254 | | bool HasOpCodeMap( const sal_Int32 nLanguage ) const; |
255 | | |
256 | | /** Create an internal symbol map from API mapping. |
257 | | @param bEnglish |
258 | | Use English number parser / formatter instead of native. |
259 | | */ |
260 | | static OpCodeMapPtr CreateOpCodeMap( |
261 | | const css::uno::Sequence< const css::sheet::FormulaOpCodeMapEntry > & rMapping, |
262 | | bool bEnglish ); |
263 | | |
264 | | /** Get current OpCodeMap in effect. */ |
265 | 42.2k | const OpCodeMapPtr& GetCurrentOpCodeMap() const { return mxSymbols; } |
266 | | |
267 | | /** Get OpCode for English symbol. |
268 | | Used in XFunctionAccess to create token array. |
269 | | @param rName |
270 | | Symbol to lookup. MUST be upper case. |
271 | | */ |
272 | | OpCode GetEnglishOpCode( const OUString& rName ) const; |
273 | | |
274 | | FormulaError GetErrorConstant( const OUString& rName ) const; |
275 | | void AppendErrorConstant( OUStringBuffer& rBuffer, FormulaError nError ) const; |
276 | | |
277 | | void EnableJumpCommandReorder( bool bEnable ); |
278 | | void EnableStopOnError( bool bEnable ); |
279 | | |
280 | | static bool IsOpCodeVolatile( OpCode eOp ); |
281 | | static bool IsOpCodeJumpCommand( OpCode eOp ); |
282 | | |
283 | | static bool DeQuote( OUString& rStr ); |
284 | | |
285 | | |
286 | | static const OUString& GetNativeSymbol( OpCode eOp ); |
287 | | static sal_Unicode GetNativeSymbolChar( OpCode eOp ); |
288 | | static bool IsMatrixFunction(OpCode _eOpCode); // if a function _always_ returns a Matrix |
289 | | |
290 | 1.41M | SvNumFormatType GetNumFormatType() const { return nNumFmt; } |
291 | | bool CompileTokenArray(); |
292 | | |
293 | | void CreateStringFromTokenArray( OUString& rFormula ); |
294 | | void CreateStringFromTokenArray( OUStringBuffer& rBuffer ); |
295 | | const FormulaToken* CreateStringFromToken( OUString& rFormula, const FormulaToken* pToken ); |
296 | | const FormulaToken* CreateStringFromToken( OUStringBuffer& rBuffer, const FormulaToken* pToken, |
297 | | bool bAllowArrAdvance = false ); |
298 | | |
299 | | void AppendBoolean( OUStringBuffer& rBuffer, bool bVal ) const; |
300 | | void AppendDouble( OUStringBuffer& rBuffer, double fVal ) const; |
301 | | static void AppendString( OUStringBuffer& rBuffer, const OUString & rStr ); |
302 | | |
303 | | /** Set symbol map corresponding to one of predefined formula::FormulaGrammar::Grammar, |
304 | | including an address reference convention. */ |
305 | 12.8M | FormulaGrammar::Grammar GetGrammar() const { return meGrammar; } |
306 | | |
307 | | /** Whether current symbol set and grammar need transformation of Table |
308 | | structured references to A1 style references when writing / exporting |
309 | | (creating strings). |
310 | | */ |
311 | | bool NeedsTableRefTransformation() const; |
312 | | |
313 | | /** If a parameter nParam (0-based) is to be forced to array for OpCode |
314 | | eOp, i.e. classified as ParamClass::ForceArray or |
315 | | ParamClass::ReferenceOrForceArray type. */ |
316 | | virtual formula::ParamClass GetForceArrayParameter( const FormulaToken* pToken, sal_uInt16 nParam ) const; |
317 | | |
318 | | static void UpdateSeparatorsNative( const OUString& rSep, const OUString& rArrayColSep, const OUString& rArrayRowSep ); |
319 | | static void ResetNativeSymbols(); |
320 | | static void SetNativeSymbols( const OpCodeMapPtr& xMap ); |
321 | | |
322 | | /** Sets the implicit intersection compute flag */ |
323 | 0 | void SetComputeIIFlag(bool bSet) { mbComputeII = bSet; } |
324 | | |
325 | | /** Sets the matrix flag for the formula*/ |
326 | 0 | void SetMatrixFlag(bool bSet) { mbMatrixFlag = bSet; } |
327 | | |
328 | | /** Separators mapped when loading opcodes from the resource, values other |
329 | | than RESOURCE_BASE may override the resource strings. Used by OpCodeList |
330 | | implementation via loadSymbols(). |
331 | | */ |
332 | | enum class SeparatorType |
333 | | { |
334 | | RESOURCE_BASE, |
335 | | SEMICOLON_BASE |
336 | | }; |
337 | | |
338 | | protected: |
339 | | virtual OUString FindAddInFunction( const OUString& rUpperName, bool bLocalFirst ) const; |
340 | | virtual void fillFromAddInCollectionUpperName( const NonConstOpCodeMapPtr& xMap ) const; |
341 | | virtual void fillFromAddInMap( const NonConstOpCodeMapPtr& xMap, FormulaGrammar::Grammar _eGrammar ) const; |
342 | | virtual void fillFromAddInCollectionEnglishName( const NonConstOpCodeMapPtr& xMap ) const; |
343 | | virtual void fillFromAddInCollectionExcelName( const NonConstOpCodeMapPtr& xMap ) const; |
344 | | virtual void fillAddInToken(::std::vector< css::sheet::FormulaOpCodeMapEntry >& _rVec, bool _bIsEnglish) const; |
345 | | |
346 | | virtual void SetError(FormulaError nError); |
347 | | virtual FormulaTokenRef ExtendRangeReference( FormulaToken & rTok1, FormulaToken & rTok2 ); |
348 | | virtual bool HandleExternalReference(const FormulaToken& _aToken); |
349 | | virtual bool HandleStringName(); |
350 | | virtual bool HandleRange(); |
351 | | virtual bool HandleColRowName(); |
352 | | virtual bool HandleDbData(); |
353 | | virtual bool HandleTableRef(); |
354 | | |
355 | | virtual void CreateStringFromExternal( OUStringBuffer& rBuffer, const FormulaToken* pToken ) const; |
356 | | virtual void CreateStringFromSingleRef( OUStringBuffer& rBuffer, const FormulaToken* pToken ) const; |
357 | | virtual void CreateStringFromDoubleRef( OUStringBuffer& rBuffer, const FormulaToken* pToken ) const; |
358 | | virtual void CreateStringFromMatrix( OUStringBuffer& rBuffer, const FormulaToken* pToken ) const; |
359 | | virtual void CreateStringFromIndex( OUStringBuffer& rBuffer, const FormulaToken* pToken ) const; |
360 | | virtual void LocalizeString( OUString& rName ) const; // modify rName - input: exact name |
361 | | virtual bool GetExcelName( OUString& rName ) const; // modify rName - input: exact name |
362 | | |
363 | | bool GetToken(); |
364 | | OpCode NextToken(); |
365 | | void PutCode( FormulaTokenRef& ); |
366 | | void Factor(); |
367 | | void RangeLine(); |
368 | | void UnionLine(); |
369 | | void IntersectionLine(); |
370 | | void UnaryLine(); |
371 | | void PostOpLine(); |
372 | | void PowLine(); |
373 | | void MulDivLine(); |
374 | | void AddSubLine(); |
375 | | void ConcatLine(); |
376 | | void CompareLine(); |
377 | | OpCode Expression(); |
378 | | void PopTokenArray(); |
379 | | void PushTokenArray( FormulaTokenArray*, bool ); |
380 | | |
381 | | bool MergeRangeReference( FormulaToken * * const pCode1, FormulaToken * const * const pCode2 ); |
382 | | |
383 | | // Returns whether the opcode has implicit intersection ranges as parameters. |
384 | | // Called for (most) opcodes to possibly handle implicit intersection for the parameters. |
385 | | virtual void HandleIIOpCode(FormulaToken* /*token*/, |
386 | 0 | FormulaToken*** /*pppToken*/, sal_uInt8 /*nNumParams*/) {} |
387 | | |
388 | | // Called from CompileTokenArray() after RPN code generation is done. |
389 | 0 | virtual void PostProcessCode() {} |
390 | | |
391 | 0 | virtual void AnnotateOperands() {} |
392 | | |
393 | | OUString aCorrectedFormula; // autocorrected Formula |
394 | | OUString aCorrectedSymbol; // autocorrected Symbol |
395 | | |
396 | | OpCodeMapPtr mxSymbols; // which symbols are used |
397 | | |
398 | | FormulaTokenRef mpToken; // current token |
399 | | FormulaTokenRef pCurrentFactorToken; // current factor token (of Factor() method) |
400 | | sal_uInt16 nCurrentFactorParam; // current factor token's parameter, 1-based |
401 | | FormulaTokenArray* pArr; |
402 | | FormulaTokenArrayPlainIterator maArrIterator; |
403 | | FormulaTokenRef mpLastToken; // last token |
404 | | |
405 | | FormulaToken** pCode; |
406 | | FormulaArrayStack* pStack; |
407 | | |
408 | | OpCode eLastOp; |
409 | | short nRecursion; // GetToken() recursions |
410 | | SvNumFormatType nNumFmt; // set during CompileTokenArray() |
411 | | sal_uInt16 pc; // program counter |
412 | | |
413 | | FormulaGrammar::Grammar meGrammar; // The grammar used, language plus convention. |
414 | | |
415 | | bool bAutoCorrect; // whether to apply AutoCorrection |
416 | | bool bCorrected; // AutoCorrection was applied |
417 | | bool glSubTotal; // if code contains one or more subtotal functions |
418 | | bool needsRPNTokenCheck; // whether to make FormulaTokenArray check all tokens at the end |
419 | | |
420 | | bool mbJumpCommandReorder; /// Whether or not to reorder RPN for jump commands. |
421 | | bool mbStopOnError; /// Whether to stop compilation on first encountered error. |
422 | | |
423 | | bool mbComputeII; // whether to attempt computing implicit intersection ranges while building the RPN array. |
424 | | bool mbMatrixFlag; // whether the formula is a matrix formula (needed for II computation) |
425 | | |
426 | | struct LambdaFunc |
427 | | { |
428 | | bool bInLambdaFunction = false; |
429 | | short nBracketPos = 0; |
430 | | short nParaPos = 0; |
431 | | short nParaCount = 3; // minimum required parameter count: 3 |
432 | | std::unordered_set<OUString> aNameSet; |
433 | | } m_aLambda; |
434 | | |
435 | | // ODF version at time of saving. Set by ScXMLExport::WriteCell(). |
436 | | std::optional< SvtSaveOptions::ODFSaneDefaultVersion > m_oODFSavingVersion; |
437 | | |
438 | | public: |
439 | | enum InitSymbols |
440 | | { |
441 | | ASK = 0, |
442 | | INIT, |
443 | | DESTROY |
444 | | }; |
445 | | |
446 | | private: |
447 | | bool InitSymbolsNative( InitSymbols ) const; /// only SymbolsNative, on first document creation |
448 | | bool InitSymbolsEnglish( InitSymbols ) const; /// only SymbolsEnglish, maybe later |
449 | | bool InitSymbolsPODF( InitSymbols ) const; /// only SymbolsPODF, on demand |
450 | | bool InitSymbolsAPI( InitSymbols ) const; /// only SymbolsAPI, on demand |
451 | | bool InitSymbolsODFF( InitSymbols ) const; /// only SymbolsODFF, on demand |
452 | | bool InitSymbolsEnglishXL( InitSymbols ) const; /// only SymbolsEnglishXL, on demand |
453 | | bool InitSymbolsOOXML( InitSymbols ) const; /// only SymbolsOOXML, on demand |
454 | | |
455 | | void loadSymbols(const std::pair<const char*, int>* pSymbols, FormulaGrammar::Grammar eGrammar, NonConstOpCodeMapPtr& rxMap, |
456 | | SeparatorType eSepType = SeparatorType::SEMICOLON_BASE) const; |
457 | | |
458 | | /** Check pCurrentFactorToken for nParam's (0-based) ForceArray types and |
459 | | set ForceArray at rCurr if so. Set nParam+1 as 1-based |
460 | | nCurrentFactorParam for subsequent ForceArrayOperator() calls. |
461 | | */ |
462 | | void CheckSetForceArrayParameter( FormulaTokenRef const & rCurr, sal_uInt8 nParam ); |
463 | | |
464 | | void ForceArrayOperator( FormulaTokenRef const & rCurr ); |
465 | | |
466 | | class CurrentFactor |
467 | | { |
468 | | FormulaTokenRef pPrevFac; |
469 | | sal_uInt16 nPrevParam; |
470 | | FormulaCompiler* pCompiler; |
471 | | CurrentFactor( const CurrentFactor& ) = delete; |
472 | | CurrentFactor& operator=( const CurrentFactor& ) = delete; |
473 | | public: |
474 | | explicit CurrentFactor( FormulaCompiler* pComp ) |
475 | 7.47M | : pPrevFac( pComp->pCurrentFactorToken ) |
476 | 7.47M | , nPrevParam( pComp->nCurrentFactorParam ) |
477 | 7.47M | , pCompiler( pComp ) |
478 | 7.47M | {} |
479 | | ~CurrentFactor() |
480 | 7.47M | { |
481 | 7.47M | pCompiler->pCurrentFactorToken = pPrevFac; |
482 | 7.47M | pCompiler->nCurrentFactorParam = nPrevParam; |
483 | 7.47M | } |
484 | | // yes, this operator= may modify the RValue |
485 | | void operator=( FormulaTokenRef const & r ) |
486 | 3.13M | { |
487 | 3.13M | pCompiler->ForceArrayOperator( r ); |
488 | 3.13M | pCompiler->pCurrentFactorToken = r; |
489 | 3.13M | pCompiler->nCurrentFactorParam = 0; |
490 | 3.13M | } |
491 | | void operator=( FormulaToken* p ) |
492 | 0 | { |
493 | 0 | FormulaTokenRef xTemp( p ); |
494 | 0 | *this = xTemp; |
495 | 0 | } |
496 | | operator FormulaTokenRef&() |
497 | 3.11M | { return pCompiler->pCurrentFactorToken; } |
498 | | FormulaToken* operator->() |
499 | 5.17M | { return pCompiler->pCurrentFactorToken.operator->(); } |
500 | | operator FormulaToken*() |
501 | 1.64M | { return operator->(); } |
502 | | }; |
503 | | |
504 | | |
505 | | mutable NonConstOpCodeMapPtr mxSymbolsODFF; // ODFF symbols |
506 | | mutable NonConstOpCodeMapPtr mxSymbolsPODF; // ODF 1.1 symbols |
507 | | mutable NonConstOpCodeMapPtr mxSymbolsAPI; // XFunctionAccess API symbols |
508 | | mutable NonConstOpCodeMapPtr mxSymbolsNative; // native symbols |
509 | | mutable NonConstOpCodeMapPtr mxSymbolsEnglish; // English symbols |
510 | | mutable NonConstOpCodeMapPtr mxSymbolsEnglishXL; // English Excel symbols (for VBA formula parsing) |
511 | | mutable NonConstOpCodeMapPtr mxSymbolsOOXML; // Excel OOXML symbols |
512 | | |
513 | | static FormulaTokenArray smDummyTokenArray; |
514 | | }; |
515 | | |
516 | | } // formula |
517 | | |
518 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |