summaryrefslogtreecommitdiff
path: root/include/formula/grammar.hxx
blob: 677087d199342e577aae2f064021279fe9d24a79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_FORMULA_GRAMMAR_HXX
#define INCLUDED_FORMULA_GRAMMAR_HXX

#include <com/sun/star/sheet/FormulaLanguage.hpp>
#include <formula/formuladllapi.h>
#include <sal/types.h>

namespace formula
{

/** Grammars digested by ScCompiler.
 */
class FORMULA_DLLPUBLIC FormulaGrammar
{
public:
    enum AddressConvention{
        CONV_UNSPECIFIED = -1,  /* useful when we want method to choose, must be first */

        /* elements must be sequential and changes should be reflected in ScCompiler::pCharTables */
        CONV_OOO     =  0,  /* 'doc'#sheet.A1:sheet2.B2 */
        CONV_ODF,           /* ['doc'#sheet.A1:sheet2.B2] */
        CONV_XL_A1,         /* [doc]sheet:sheet2!A1:B2 */
        CONV_XL_R1C1,       /* [doc]sheet:sheet2!R1C1:R2C2 */
        CONV_XL_OOX,        /* [#]sheet:sheet2!A1:B2 */

        CONV_LOTUS_A1,      /* external? 3d? A1.B2 <placeholder/> */

        CONV_LAST,   /* for loops, must always be last */

        // not a real address convention, a special case for INDIRECT function interpretation
        // only -> try using CONV_OOO, failing that CONV_XL_A1
        CONV_A1_XL_A1
    };

    //! CONV_UNSPECIFIED is a negative value!
    static const int kConventionOffset = - CONV_UNSPECIFIED + 1;
    // Room for 32k hypothetical languages plus EXTERNAL.
    static const int kConventionShift  = 16;
    // Room for 256 reference conventions.
    static const int kEnglishBit       = (1 << (kConventionShift + 8));
    // Mask off all non-language bits.
    static const int kFlagMask         = ~((~unsigned(0)) << kConventionShift);

    /** Values encoding the formula language plus address reference convention
        plus English parsing/formatting
     */
    //! When adding new values adapt isSupported() below as well.
    enum Grammar
    {
        /// Used only in ScCompiler ctor and in some XML import API context.
        GRAM_UNSPECIFIED    = -1,
        /// ODFF with default ODF A1 bracketed references.
        GRAM_ODFF           = css::sheet::FormulaLanguage::ODFF                 |
                                ((CONV_ODF           +
                                  kConventionOffset) << kConventionShift)       |
                                kEnglishBit,
        /// ODF 1.1 with default ODF A1 bracketed references.
        GRAM_PODF           = css::sheet::FormulaLanguage::ODF_11               |
                                ((CONV_ODF           +
                                  kConventionOffset) << kConventionShift)       |
                                kEnglishBit,
        /// English with default A1 reference style.
        GRAM_ENGLISH        = css::sheet::FormulaLanguage::ENGLISH              |
                                ((CONV_OOO           +
                                  kConventionOffset) << kConventionShift)       |
                                kEnglishBit,
        /// Native with default A1 reference style.
        GRAM_NATIVE         = css::sheet::FormulaLanguage::NATIVE               |
                                ((CONV_OOO           +
                                  kConventionOffset) << kConventionShift),
        /// ODFF with reference style as set in UI, may be A1 or R1C1.
        GRAM_ODFF_UI        = css::sheet::FormulaLanguage::ODFF                 |
                                ((CONV_UNSPECIFIED   +
                                  kConventionOffset) << kConventionShift)       |
                                kEnglishBit,
        /// ODFF with A1 reference style, unbracketed.
        GRAM_ODFF_A1        = css::sheet::FormulaLanguage::ODFF                 |
                                ((CONV_OOO           +
                                  kConventionOffset) << kConventionShift)       |
                                kEnglishBit,
        /// ODF 1.1 with reference style as set in UI, may be A1 or R1C1.
        GRAM_PODF_UI        = css::sheet::FormulaLanguage::ODF_11               |
                                ((CONV_UNSPECIFIED   +
                                  kConventionOffset) << kConventionShift)       |
                                kEnglishBit,
        /// ODF 1.1 with A1 reference style, unbracketed.
        GRAM_PODF_A1        = css::sheet::FormulaLanguage::ODF_11               |
                                ((CONV_OOO           +
                                  kConventionOffset) << kConventionShift)       |
                                kEnglishBit,
        /// Native with reference style as set in UI, may be A1 or R1C1.
        GRAM_NATIVE_UI      = css::sheet::FormulaLanguage::NATIVE               |
                                ((CONV_UNSPECIFIED   +
                                  kConventionOffset) << kConventionShift),
        /// Native with ODF A1 bracketed references. Not very useful but supported.
        GRAM_NATIVE_ODF     = css::sheet::FormulaLanguage::NATIVE               |
                                ((CONV_ODF           +
                                  kConventionOffset) << kConventionShift),
        /// Native with Excel A1 reference style.
        GRAM_NATIVE_XL_A1   = css::sheet::FormulaLanguage::NATIVE               |
                                ((CONV_XL_A1         +
                                  kConventionOffset) << kConventionShift),
        /// Native with Excel R1C1 reference style.
        GRAM_NATIVE_XL_R1C1 = css::sheet::FormulaLanguage::NATIVE               |
                                ((CONV_XL_R1C1       +
                                  kConventionOffset) << kConventionShift),
        /// English with Excel A1 reference style.
        GRAM_ENGLISH_XL_A1   = css::sheet::FormulaLanguage::XL_ENGLISH               |
                                ((CONV_XL_A1         +
                                  kConventionOffset) << kConventionShift)            |
                                kEnglishBit,
        /// English with Excel R1C1 reference style.
        GRAM_ENGLISH_XL_R1C1 = css::sheet::FormulaLanguage::XL_ENGLISH               |
                                ((CONV_XL_R1C1       +
                                  kConventionOffset) << kConventionShift)            |
                                kEnglishBit,
        /// English with Excel OOXML reference style.
        GRAM_ENGLISH_XL_OOX  = css::sheet::FormulaLanguage::XL_ENGLISH               |
                                ((CONV_XL_OOX        +
                                  kConventionOffset) << kConventionShift)            |
                                kEnglishBit,
        /// Excel OOXML with Excel OOXML reference style.
        GRAM_OOXML           = css::sheet::FormulaLanguage::OOXML               |
                                ((CONV_XL_OOX        +
                                  kConventionOffset) << kConventionShift)       |
                                kEnglishBit,
        /// API English with A1 reference style, unbracketed.
        GRAM_API            = css::sheet::FormulaLanguage::API                  |
                                ((CONV_OOO           +
                                  kConventionOffset) << kConventionShift)       |
                                kEnglishBit,
        /// Central definition of the default grammar to be used.
        GRAM_DEFAULT        = GRAM_NATIVE_UI,

        /// Central definition of the default storage grammar to be used.
        GRAM_STORAGE_DEFAULT = GRAM_ODFF,

        /** OpCodeMap set by external filter and merged with reference
            convention plus English bit on top. Plain value acts as
            FormulaLanguage. */
        GRAM_EXTERNAL       = (1 << (kConventionShift - 1))
    };

    /// If English parsing/formatting is associated with a grammar.
    static bool isEnglish( const Grammar eGrammar )
    {
        return (eGrammar & kEnglishBit) != 0;
    }

    /** Compatibility helper for old "bCompileEnglish, bCompileXML" API calls
        to obtain the new grammar. */
    static Grammar mapAPItoGrammar( const bool bEnglish, const bool bXML );

    static bool isSupported( const Grammar eGrammar );

    static sal_Int32 extractFormulaLanguage( const Grammar eGrammar )
    {
        return eGrammar & kFlagMask;
    }

    static AddressConvention extractRefConvention( const Grammar eGrammar )
    {
        return static_cast<AddressConvention>(
                ((eGrammar & ~kEnglishBit) >> kConventionShift) -
                kConventionOffset);
    }

    static Grammar setEnglishBit( const Grammar eGrammar, const bool bEnglish );

    static Grammar mergeToGrammar( const Grammar eGrammar, const AddressConvention eConv );

    /// If grammar is of ODF 1.1
    static bool isPODF( const Grammar eGrammar )
    {
        return extractFormulaLanguage( eGrammar) ==
            css::sheet::FormulaLanguage::ODF_11;
    }

    /// If grammar is of ODFF
    static bool isODFF( const Grammar eGrammar )
    {
        return extractFormulaLanguage( eGrammar) ==
            css::sheet::FormulaLanguage::ODFF;
    }

    /// If grammar is of OOXML
    static bool isOOXML( const Grammar eGrammar )
    {
        return extractFormulaLanguage( eGrammar) ==
            css::sheet::FormulaLanguage::OOXML;
    }

    /** If reference convention is OOXML.

        Note this is not equivalent to isOOXML() as it does not have to be
        FormulaLanguage::OOXML but can be Grammar::GRAM_EXTERNAL merged with
        AddressConvention::CONV_XL_OOX, which is used by various parts of OOXML
        import through the API FormulaParser.
     */
    static bool isRefConventionOOXML( const Grammar eGrammar )
    {
        return extractRefConvention( eGrammar) ==
            FormulaGrammar::AddressConvention::CONV_XL_OOX;
    }

    /// If grammar has an Excel syntax, determined by address convention.
    static bool isExcelSyntax( const Grammar eGrammar )
    {
        AddressConvention eConv = extractRefConvention( eGrammar );
        switch (eConv)
        {
            case FormulaGrammar::AddressConvention::CONV_XL_A1:
            case FormulaGrammar::AddressConvention::CONV_XL_R1C1:
            case FormulaGrammar::AddressConvention::CONV_XL_OOX:
                return true;
            default:
                return false;
        }
    }

};

} // formula


#endif // INCLUDED_FORMULA_GRAMMAR_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */