10596faeddefbf198de137d5e893708495ab1584cFredrik Roubert// © 2016 and later: Unicode, Inc. and others.
264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html
385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/*
485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*******************************************************************************
58de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert* Copyright (C) 2007-2016, International Business Machines Corporation and
685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho* others. All Rights Reserved.
785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*******************************************************************************
885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*
985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho* File PLURRULE_IMPL.H
1085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*
1185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*******************************************************************************
1285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*/
1385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
1485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
150b3ec0516c035ea443fdc334025048597c740be1Markus Scherer#ifndef PLURRULE_IMPL
160b3ec0516c035ea443fdc334025048597c740be1Markus Scherer#define PLURRULE_IMPL
1785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
18b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Internal definitions for the PluralRules implementation.
19b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
200b3ec0516c035ea443fdc334025048597c740be1Markus Scherer#include "unicode/utypes.h"
210b3ec0516c035ea443fdc334025048597c740be1Markus Scherer
2285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if !UCONFIG_NO_FORMATTING
2385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
2485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "unicode/format.h"
2585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "unicode/locid.h"
2685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "unicode/parseerr.h"
270596faeddefbf198de137d5e893708495ab1584cFredrik Roubert#include "unicode/strenum.h"
2859d709d503bab6e2b61931737e662dd293b40578ccornelius#include "unicode/ures.h"
2985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "uvector.h"
3085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "hash.h"
31ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert#include "uassert.h"
3285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
3359d709d503bab6e2b61931737e662dd293b40578ccorneliusclass PluralRulesTest;
3459d709d503bab6e2b61931737e662dd293b40578ccornelius
3585bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoU_NAMESPACE_BEGIN
3685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
3759d709d503bab6e2b61931737e662dd293b40578ccorneliusclass AndConstraint;
3859d709d503bab6e2b61931737e662dd293b40578ccorneliusclass RuleChain;
39c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertclass DigitInterval;
408de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubertclass PluralRules;
41c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertclass VisibleDigits;
4259d709d503bab6e2b61931737e662dd293b40578ccornelius
4359d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar DOT             = ((UChar)0x002E);
4459d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar SINGLE_QUOTE    = ((UChar)0x0027);
4559d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar SLASH           = ((UChar)0x002F);
4659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar BACKSLASH       = ((UChar)0x005C);
4759d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar SPACE           = ((UChar)0x0020);
4859d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar EXCLAMATION     = ((UChar)0x0021);
4959d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar QUOTATION_MARK  = ((UChar)0x0022);
5059d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar NUMBER_SIGN     = ((UChar)0x0023);
5159d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar PERCENT_SIGN    = ((UChar)0x0025);
5259d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar ASTERISK        = ((UChar)0x002A);
5359d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar COMMA           = ((UChar)0x002C);
5459d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar HYPHEN          = ((UChar)0x002D);
5559d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar U_ZERO          = ((UChar)0x0030);
5659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar U_ONE           = ((UChar)0x0031);
5759d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar U_TWO           = ((UChar)0x0032);
5859d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar U_THREE         = ((UChar)0x0033);
5959d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar U_FOUR          = ((UChar)0x0034);
6059d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar U_FIVE          = ((UChar)0x0035);
6159d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar U_SIX           = ((UChar)0x0036);
6259d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar U_SEVEN         = ((UChar)0x0037);
6359d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar U_EIGHT         = ((UChar)0x0038);
6459d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar U_NINE          = ((UChar)0x0039);
6559d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar COLON           = ((UChar)0x003A);
6659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar SEMI_COLON      = ((UChar)0x003B);
6759d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar EQUALS          = ((UChar)0x003D);
6859d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar AT              = ((UChar)0x0040);
6959d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar CAP_A           = ((UChar)0x0041);
7059d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar CAP_B           = ((UChar)0x0042);
7159d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar CAP_R           = ((UChar)0x0052);
7259d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar CAP_Z           = ((UChar)0x005A);
7359d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOWLINE         = ((UChar)0x005F);
7459d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LEFTBRACE       = ((UChar)0x007B);
7559d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar RIGHTBRACE      = ((UChar)0x007D);
7659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar TILDE           = ((UChar)0x007E);
7759d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar ELLIPSIS        = ((UChar)0x2026);
7859d709d503bab6e2b61931737e662dd293b40578ccornelius
7959d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_A           = ((UChar)0x0061);
8059d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_B           = ((UChar)0x0062);
8159d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_C           = ((UChar)0x0063);
8259d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_D           = ((UChar)0x0064);
8359d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_E           = ((UChar)0x0065);
8459d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_F           = ((UChar)0x0066);
8559d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_G           = ((UChar)0x0067);
8659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_H           = ((UChar)0x0068);
8759d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_I           = ((UChar)0x0069);
8859d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_J           = ((UChar)0x006a);
8959d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_K           = ((UChar)0x006B);
9059d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_L           = ((UChar)0x006C);
9159d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_M           = ((UChar)0x006D);
9259d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_N           = ((UChar)0x006E);
9359d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_O           = ((UChar)0x006F);
9459d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_P           = ((UChar)0x0070);
9559d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_Q           = ((UChar)0x0071);
9659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_R           = ((UChar)0x0072);
9759d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_S           = ((UChar)0x0073);
9859d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_T           = ((UChar)0x0074);
9959d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_U           = ((UChar)0x0075);
10059d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_V           = ((UChar)0x0076);
10159d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_W           = ((UChar)0x0077);
10259d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_Y           = ((UChar)0x0079);
10359d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_Z           = ((UChar)0x007A);
10459d709d503bab6e2b61931737e662dd293b40578ccornelius
10559d709d503bab6e2b61931737e662dd293b40578ccornelius
10659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const int32_t PLURAL_RANGE_HIGH = 0x7fffffff;
10759d709d503bab6e2b61931737e662dd293b40578ccornelius
10859d709d503bab6e2b61931737e662dd293b40578ccorneliusenum tokenType {
10985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho  none,
11085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho  tNumber,
11185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho  tComma,
11285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho  tSemiColon,
11385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho  tSpace,
11485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho  tColon,
11559d709d503bab6e2b61931737e662dd293b40578ccornelius  tAt,           // '@'
11685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho  tDot,
11759d709d503bab6e2b61931737e662dd293b40578ccornelius  tDot2,
11859d709d503bab6e2b61931737e662dd293b40578ccornelius  tEllipsis,
11985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho  tKeyword,
12085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho  tAnd,
12185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho  tOr,
12259d709d503bab6e2b61931737e662dd293b40578ccornelius  tMod,          // 'mod' or '%'
12359d709d503bab6e2b61931737e662dd293b40578ccornelius  tNot,          //  'not' only.
12459d709d503bab6e2b61931737e662dd293b40578ccornelius  tIn,           //  'in'  only.
12559d709d503bab6e2b61931737e662dd293b40578ccornelius  tEqual,        //  '='   only.
12659d709d503bab6e2b61931737e662dd293b40578ccornelius  tNotEqual,     //  '!='
12759d709d503bab6e2b61931737e662dd293b40578ccornelius  tTilde,
12885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho  tWithin,
12985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho  tIs,
13059d709d503bab6e2b61931737e662dd293b40578ccornelius  tVariableN,
13159d709d503bab6e2b61931737e662dd293b40578ccornelius  tVariableI,
13259d709d503bab6e2b61931737e662dd293b40578ccornelius  tVariableF,
13359d709d503bab6e2b61931737e662dd293b40578ccornelius  tVariableV,
13459d709d503bab6e2b61931737e662dd293b40578ccornelius  tVariableT,
13559d709d503bab6e2b61931737e662dd293b40578ccornelius  tDecimal,
13659d709d503bab6e2b61931737e662dd293b40578ccornelius  tInteger,
13759d709d503bab6e2b61931737e662dd293b40578ccornelius  tEOF
13859d709d503bab6e2b61931737e662dd293b40578ccornelius};
13959d709d503bab6e2b61931737e662dd293b40578ccornelius
14085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
14159d709d503bab6e2b61931737e662dd293b40578ccorneliusclass PluralRuleParser: public UMemory {
14285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hopublic:
14359d709d503bab6e2b61931737e662dd293b40578ccornelius    PluralRuleParser();
14459d709d503bab6e2b61931737e662dd293b40578ccornelius    virtual ~PluralRuleParser();
14559d709d503bab6e2b61931737e662dd293b40578ccornelius
14659d709d503bab6e2b61931737e662dd293b40578ccornelius    void parse(const UnicodeString &rules, PluralRules *dest, UErrorCode &status);
14759d709d503bab6e2b61931737e662dd293b40578ccornelius    void getNextToken(UErrorCode &status);
14859d709d503bab6e2b61931737e662dd293b40578ccornelius    void checkSyntax(UErrorCode &status);
14959d709d503bab6e2b61931737e662dd293b40578ccornelius    static int32_t getNumberValue(const UnicodeString &token);
15059d709d503bab6e2b61931737e662dd293b40578ccornelius
15185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoprivate:
15259d709d503bab6e2b61931737e662dd293b40578ccornelius    static tokenType getKeyType(const UnicodeString& token, tokenType type);
15359d709d503bab6e2b61931737e662dd293b40578ccornelius    static tokenType charType(UChar ch);
15459d709d503bab6e2b61931737e662dd293b40578ccornelius    static UBool isValidKeyword(const UnicodeString& token);
15559d709d503bab6e2b61931737e662dd293b40578ccornelius
15659d709d503bab6e2b61931737e662dd293b40578ccornelius    const UnicodeString  *ruleSrc;  // The rules string.
15759d709d503bab6e2b61931737e662dd293b40578ccornelius    int32_t        ruleIndex;       // String index in the input rules, the current parse position.
15859d709d503bab6e2b61931737e662dd293b40578ccornelius    UnicodeString  token;           // Token most recently scanned.
15959d709d503bab6e2b61931737e662dd293b40578ccornelius    tokenType      type;
16059d709d503bab6e2b61931737e662dd293b40578ccornelius    tokenType      prevType;
16159d709d503bab6e2b61931737e662dd293b40578ccornelius
16259d709d503bab6e2b61931737e662dd293b40578ccornelius                                    // The items currently being parsed & built.
16359d709d503bab6e2b61931737e662dd293b40578ccornelius                                    // Note: currentChain may not be the last RuleChain in the
16459d709d503bab6e2b61931737e662dd293b40578ccornelius                                    //       list because the "other" chain is forced to the end.
16559d709d503bab6e2b61931737e662dd293b40578ccornelius    AndConstraint *curAndConstraint;
16659d709d503bab6e2b61931737e662dd293b40578ccornelius    RuleChain     *currentChain;
16759d709d503bab6e2b61931737e662dd293b40578ccornelius
16859d709d503bab6e2b61931737e662dd293b40578ccornelius    int32_t        rangeLowIdx;     // Indices in the UVector of ranges of the
16959d709d503bab6e2b61931737e662dd293b40578ccornelius    int32_t        rangeHiIdx;      //    low and hi values currently being parsed.
17059d709d503bab6e2b61931737e662dd293b40578ccornelius
17159d709d503bab6e2b61931737e662dd293b40578ccornelius    enum EParseState {
17259d709d503bab6e2b61931737e662dd293b40578ccornelius       kKeyword,
17359d709d503bab6e2b61931737e662dd293b40578ccornelius       kExpr,
17459d709d503bab6e2b61931737e662dd293b40578ccornelius       kValue,
17559d709d503bab6e2b61931737e662dd293b40578ccornelius       kRangeList,
17659d709d503bab6e2b61931737e662dd293b40578ccornelius       kSamples
17759d709d503bab6e2b61931737e662dd293b40578ccornelius    };
17859d709d503bab6e2b61931737e662dd293b40578ccornelius
17959d709d503bab6e2b61931737e662dd293b40578ccornelius};
18059d709d503bab6e2b61931737e662dd293b40578ccornelius
181ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubertenum PluralOperand {
182ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    /**
183ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    * The double value of the entire number.
184ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    */
185ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    PLURAL_OPERAND_N,
186ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert
187ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    /**
188ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     * The integer value, with the fraction digits truncated off.
189ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     */
190ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    PLURAL_OPERAND_I,
191ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert
192ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    /**
193ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     * All visible fraction digits as an integer, including trailing zeros.
194ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     */
195ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    PLURAL_OPERAND_F,
196ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert
197ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    /**
198ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     * Visible fraction digits as an integer, not including trailing zeros.
199ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     */
200ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    PLURAL_OPERAND_T,
201ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert
202ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    /**
203ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     * Number of visible fraction digits.
204ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     */
205ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    PLURAL_OPERAND_V,
206ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert
207ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    /**
208ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     * Number of visible fraction digits, not including trailing zeros.
209ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     */
210ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    PLURAL_OPERAND_W,
211ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert
212ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    /**
213ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     * THIS OPERAND IS DEPRECATED AND HAS BEEN REMOVED FROM THE SPEC.
214ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     *
215ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     * <p>Returns the integer value, but will fail if the number has fraction digits.
216ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     * That is, using "j" instead of "i" is like implicitly adding "v is 0".
217ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     *
218ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     * <p>For example, "j is 3" is equivalent to "i is 3 and v is 0": it matches
219ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     * "3" but not "3.1" or "3.0".
220ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     */
221ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    PLURAL_OPERAND_J
222ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert};
223ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert
224ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert/**
225ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * Converts from the tokenType enum to PluralOperand. Asserts that the given
226ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * tokenType can be mapped to a PluralOperand.
227ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert */
228ffdc27edd5503111189fc11165c5a11289a71f79Fredrik RoubertPluralOperand tokenTypeToPluralOperand(tokenType tt);
229ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert
230ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert/**
231ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * An interface to FixedDecimal, allowing for other implementations.
232ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * @internal
233ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert */
234ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubertclass U_I18N_API IFixedDecimal {
235ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert  public:
236ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    virtual ~IFixedDecimal();
237ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert
238ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    /**
239ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     * Returns the value corresponding to the specified operand (n, i, f, t, v, or w).
240ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     * If the operand is 'n', returns a double; otherwise, returns an integer.
241ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert     */
242ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    virtual double getPluralOperand(PluralOperand operand) const = 0;
243ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert
244ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    virtual bool isNaN() const = 0;
245ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert
246ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    virtual bool isInfinite() const = 0;
247ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert};
248ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert
24959d709d503bab6e2b61931737e662dd293b40578ccornelius/**
25059d709d503bab6e2b61931737e662dd293b40578ccornelius * class FixedDecimal serves to communicate the properties
25159d709d503bab6e2b61931737e662dd293b40578ccornelius * of a formatted number from a decimal formatter to PluralRules::select()
25259d709d503bab6e2b61931737e662dd293b40578ccornelius *
25359d709d503bab6e2b61931737e662dd293b40578ccornelius * see DecimalFormat::getFixedDecimal()
25459d709d503bab6e2b61931737e662dd293b40578ccornelius * @internal
25559d709d503bab6e2b61931737e662dd293b40578ccornelius */
256ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubertclass U_I18N_API FixedDecimal: public IFixedDecimal, public UObject {
25759d709d503bab6e2b61931737e662dd293b40578ccornelius  public:
25859d709d503bab6e2b61931737e662dd293b40578ccornelius    /**
25959d709d503bab6e2b61931737e662dd293b40578ccornelius      * @param n   the number, e.g. 12.345
26059d709d503bab6e2b61931737e662dd293b40578ccornelius      * @param v   The number of visible fraction digits, e.g. 3
26159d709d503bab6e2b61931737e662dd293b40578ccornelius      * @param f   The fraction digits, e.g. 345
26259d709d503bab6e2b61931737e662dd293b40578ccornelius      */
26359d709d503bab6e2b61931737e662dd293b40578ccornelius    FixedDecimal(double  n, int32_t v, int64_t f);
26459d709d503bab6e2b61931737e662dd293b40578ccornelius    FixedDecimal(double n, int32_t);
26559d709d503bab6e2b61931737e662dd293b40578ccornelius    explicit FixedDecimal(double n);
266c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert    explicit FixedDecimal(const VisibleDigits &n);
26759d709d503bab6e2b61931737e662dd293b40578ccornelius    FixedDecimal();
268ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    ~FixedDecimal() U_OVERRIDE;
26959d709d503bab6e2b61931737e662dd293b40578ccornelius    FixedDecimal(const UnicodeString &s, UErrorCode &ec);
27059d709d503bab6e2b61931737e662dd293b40578ccornelius    FixedDecimal(const FixedDecimal &other);
27159d709d503bab6e2b61931737e662dd293b40578ccornelius
272ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    double getPluralOperand(PluralOperand operand) const U_OVERRIDE;
273ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    bool isNaN() const U_OVERRIDE;
274ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    bool isInfinite() const U_OVERRIDE;
275ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert
276ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    bool isNanOrInfinity() const;  // used in decimfmtimpl.cpp
277ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert
27859d709d503bab6e2b61931737e662dd293b40578ccornelius    int32_t getVisibleFractionDigitCount() const;
27959d709d503bab6e2b61931737e662dd293b40578ccornelius
28059d709d503bab6e2b61931737e662dd293b40578ccornelius    void init(double n, int32_t v, int64_t f);
28159d709d503bab6e2b61931737e662dd293b40578ccornelius    void init(double n);
28259d709d503bab6e2b61931737e662dd293b40578ccornelius    UBool quickInit(double n);  // Try a fast-path only initialization,
28359d709d503bab6e2b61931737e662dd293b40578ccornelius                                //    return TRUE if successful.
28459d709d503bab6e2b61931737e662dd293b40578ccornelius    void adjustForMinFractionDigits(int32_t min);
28559d709d503bab6e2b61931737e662dd293b40578ccornelius    static int64_t getFractionalDigits(double n, int32_t v);
28659d709d503bab6e2b61931737e662dd293b40578ccornelius    static int32_t decimals(double n);
28759d709d503bab6e2b61931737e662dd293b40578ccornelius
28859d709d503bab6e2b61931737e662dd293b40578ccornelius    double      source;
28959d709d503bab6e2b61931737e662dd293b40578ccornelius    int32_t     visibleDecimalDigitCount;
29059d709d503bab6e2b61931737e662dd293b40578ccornelius    int64_t     decimalDigits;
29159d709d503bab6e2b61931737e662dd293b40578ccornelius    int64_t     decimalDigitsWithoutTrailingZeros;
29259d709d503bab6e2b61931737e662dd293b40578ccornelius    int64_t     intValue;
29359d709d503bab6e2b61931737e662dd293b40578ccornelius    UBool       hasIntegerValue;
29459d709d503bab6e2b61931737e662dd293b40578ccornelius    UBool       isNegative;
295ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    UBool       _isNaN;
296ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    UBool       _isInfinite;
29785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
29885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
29985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoclass AndConstraint : public UMemory  {
30085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hopublic:
30185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    typedef enum RuleOp {
30285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        NONE,
30385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        MOD
30485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } RuleOp;
30585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    RuleOp  op;
30659d709d503bab6e2b61931737e662dd293b40578ccornelius    int32_t opNum;           // for mod expressions, the right operand of the mod.
30759d709d503bab6e2b61931737e662dd293b40578ccornelius    int32_t     value;       // valid for 'is' rules only.
30859d709d503bab6e2b61931737e662dd293b40578ccornelius    UVector32   *rangeList;  // for 'in', 'within' rules. Null otherwise.
30959d709d503bab6e2b61931737e662dd293b40578ccornelius    UBool   negated;           // TRUE for negated rules.
31059d709d503bab6e2b61931737e662dd293b40578ccornelius    UBool   integerOnly;     // TRUE for 'within' rules.
31159d709d503bab6e2b61931737e662dd293b40578ccornelius    tokenType digitsType;    // n | i | v | f constraint.
31285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    AndConstraint *next;
313b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
31485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    AndConstraint();
31585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    AndConstraint(const AndConstraint& other);
31685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    virtual ~AndConstraint();
31785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    AndConstraint* add();
31859d709d503bab6e2b61931737e662dd293b40578ccornelius    // UBool isFulfilled(double number);
319ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    UBool isFulfilled(const IFixedDecimal &number);
32085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
32185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
32285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoclass OrConstraint : public UMemory  {
32385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hopublic:
32485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    AndConstraint *childNode;
32585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    OrConstraint *next;
32685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    OrConstraint();
327b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
32885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    OrConstraint(const OrConstraint& other);
32985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    virtual ~OrConstraint();
33085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    AndConstraint* add();
33159d709d503bab6e2b61931737e662dd293b40578ccornelius    // UBool isFulfilled(double number);
332ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    UBool isFulfilled(const IFixedDecimal &number);
33385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
33485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
33585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoclass RuleChain : public UMemory  {
33685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hopublic:
33759d709d503bab6e2b61931737e662dd293b40578ccornelius    UnicodeString   fKeyword;
33859d709d503bab6e2b61931737e662dd293b40578ccornelius    RuleChain      *fNext;
33959d709d503bab6e2b61931737e662dd293b40578ccornelius    OrConstraint   *ruleHeader;
34059d709d503bab6e2b61931737e662dd293b40578ccornelius    UnicodeString   fDecimalSamples;  // Samples strings from rule source
34159d709d503bab6e2b61931737e662dd293b40578ccornelius    UnicodeString   fIntegerSamples;  //   without @decimal or @integer, otherwise unprocessed.
34259d709d503bab6e2b61931737e662dd293b40578ccornelius    UBool           fDecimalSamplesUnbounded;
34359d709d503bab6e2b61931737e662dd293b40578ccornelius    UBool           fIntegerSamplesUnbounded;
34459d709d503bab6e2b61931737e662dd293b40578ccornelius
34559d709d503bab6e2b61931737e662dd293b40578ccornelius
34685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    RuleChain();
34785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    RuleChain(const RuleChain& other);
34885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    virtual ~RuleChain();
34959d709d503bab6e2b61931737e662dd293b40578ccornelius
350ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert    UnicodeString select(const IFixedDecimal &number) const;
35159d709d503bab6e2b61931737e662dd293b40578ccornelius    void          dumpRules(UnicodeString& result);
35259d709d503bab6e2b61931737e662dd293b40578ccornelius    UErrorCode    getKeywords(int32_t maxArraySize, UnicodeString *keywords, int32_t& arraySize) const;
35359d709d503bab6e2b61931737e662dd293b40578ccornelius    UBool         isKeyword(const UnicodeString& keyword) const;
35485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
35585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
35685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoclass PluralKeywordEnumeration : public StringEnumeration {
35785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hopublic:
35885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    PluralKeywordEnumeration(RuleChain *header, UErrorCode& status);
35985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    virtual ~PluralKeywordEnumeration();
36085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    static UClassID U_EXPORT2 getStaticClassID(void);
36185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    virtual UClassID getDynamicClassID(void) const;
36285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    virtual const UnicodeString* snext(UErrorCode& status);
36385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    virtual void reset(UErrorCode& status);
36485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    virtual int32_t count(UErrorCode& status) const;
36585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoprivate:
36659d709d503bab6e2b61931737e662dd293b40578ccornelius    int32_t         pos;
36759d709d503bab6e2b61931737e662dd293b40578ccornelius    UVector         fKeywordNames;
36859d709d503bab6e2b61931737e662dd293b40578ccornelius};
36959d709d503bab6e2b61931737e662dd293b40578ccornelius
37059d709d503bab6e2b61931737e662dd293b40578ccornelius
37159d709d503bab6e2b61931737e662dd293b40578ccorneliusclass U_I18N_API PluralAvailableLocalesEnumeration: public StringEnumeration {
37259d709d503bab6e2b61931737e662dd293b40578ccornelius  public:
37359d709d503bab6e2b61931737e662dd293b40578ccornelius    PluralAvailableLocalesEnumeration(UErrorCode &status);
37459d709d503bab6e2b61931737e662dd293b40578ccornelius    virtual ~PluralAvailableLocalesEnumeration();
37559d709d503bab6e2b61931737e662dd293b40578ccornelius    virtual const char* next(int32_t *resultLength, UErrorCode& status);
37659d709d503bab6e2b61931737e662dd293b40578ccornelius    virtual void reset(UErrorCode& status);
37759d709d503bab6e2b61931737e662dd293b40578ccornelius    virtual int32_t count(UErrorCode& status) const;
37859d709d503bab6e2b61931737e662dd293b40578ccornelius  private:
37959d709d503bab6e2b61931737e662dd293b40578ccornelius    UErrorCode      fOpenStatus;
38059d709d503bab6e2b61931737e662dd293b40578ccornelius    UResourceBundle *fLocales;
38159d709d503bab6e2b61931737e662dd293b40578ccornelius    UResourceBundle *fRes;
38285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
38385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
38485bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoU_NAMESPACE_END
38585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
38685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif /* #if !UCONFIG_NO_FORMATTING */
38785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
38885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif // _PLURRULE_IMPL
38985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//eof
390