1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/i18n/plurrule_impl.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,305 @@ 1.4 +/* 1.5 +******************************************************************************* 1.6 +* Copyright (C) 2007-2013, International Business Machines Corporation and 1.7 +* others. All Rights Reserved. 1.8 +******************************************************************************* 1.9 +* 1.10 +* File PLURRULE_IMPL.H 1.11 +* 1.12 +******************************************************************************* 1.13 +*/ 1.14 + 1.15 + 1.16 +#ifndef PLURRULE_IMPLE 1.17 +#define PLURRULE_IMPLE 1.18 + 1.19 +// Internal definitions for the PluralRules implementation. 1.20 + 1.21 +#if !UCONFIG_NO_FORMATTING 1.22 + 1.23 +#include "unicode/format.h" 1.24 +#include "unicode/locid.h" 1.25 +#include "unicode/parseerr.h" 1.26 +#include "unicode/ures.h" 1.27 +#include "unicode/utypes.h" 1.28 +#include "uvector.h" 1.29 +#include "hash.h" 1.30 + 1.31 +class PluralRulesTest; 1.32 + 1.33 +U_NAMESPACE_BEGIN 1.34 + 1.35 +class AndConstraint; 1.36 +class RuleChain; 1.37 + 1.38 +static const UChar DOT = ((UChar)0x002E); 1.39 +static const UChar SINGLE_QUOTE = ((UChar)0x0027); 1.40 +static const UChar SLASH = ((UChar)0x002F); 1.41 +static const UChar BACKSLASH = ((UChar)0x005C); 1.42 +static const UChar SPACE = ((UChar)0x0020); 1.43 +static const UChar EXCLAMATION = ((UChar)0x0021); 1.44 +static const UChar QUOTATION_MARK = ((UChar)0x0022); 1.45 +static const UChar NUMBER_SIGN = ((UChar)0x0023); 1.46 +static const UChar PERCENT_SIGN = ((UChar)0x0025); 1.47 +static const UChar ASTERISK = ((UChar)0x002A); 1.48 +static const UChar COMMA = ((UChar)0x002C); 1.49 +static const UChar HYPHEN = ((UChar)0x002D); 1.50 +static const UChar U_ZERO = ((UChar)0x0030); 1.51 +static const UChar U_ONE = ((UChar)0x0031); 1.52 +static const UChar U_TWO = ((UChar)0x0032); 1.53 +static const UChar U_THREE = ((UChar)0x0033); 1.54 +static const UChar U_FOUR = ((UChar)0x0034); 1.55 +static const UChar U_FIVE = ((UChar)0x0035); 1.56 +static const UChar U_SIX = ((UChar)0x0036); 1.57 +static const UChar U_SEVEN = ((UChar)0x0037); 1.58 +static const UChar U_EIGHT = ((UChar)0x0038); 1.59 +static const UChar U_NINE = ((UChar)0x0039); 1.60 +static const UChar COLON = ((UChar)0x003A); 1.61 +static const UChar SEMI_COLON = ((UChar)0x003B); 1.62 +static const UChar EQUALS = ((UChar)0x003D); 1.63 +static const UChar AT = ((UChar)0x0040); 1.64 +static const UChar CAP_A = ((UChar)0x0041); 1.65 +static const UChar CAP_B = ((UChar)0x0042); 1.66 +static const UChar CAP_R = ((UChar)0x0052); 1.67 +static const UChar CAP_Z = ((UChar)0x005A); 1.68 +static const UChar LOWLINE = ((UChar)0x005F); 1.69 +static const UChar LEFTBRACE = ((UChar)0x007B); 1.70 +static const UChar RIGHTBRACE = ((UChar)0x007D); 1.71 +static const UChar TILDE = ((UChar)0x007E); 1.72 +static const UChar ELLIPSIS = ((UChar)0x2026); 1.73 + 1.74 +static const UChar LOW_A = ((UChar)0x0061); 1.75 +static const UChar LOW_B = ((UChar)0x0062); 1.76 +static const UChar LOW_C = ((UChar)0x0063); 1.77 +static const UChar LOW_D = ((UChar)0x0064); 1.78 +static const UChar LOW_E = ((UChar)0x0065); 1.79 +static const UChar LOW_F = ((UChar)0x0066); 1.80 +static const UChar LOW_G = ((UChar)0x0067); 1.81 +static const UChar LOW_H = ((UChar)0x0068); 1.82 +static const UChar LOW_I = ((UChar)0x0069); 1.83 +static const UChar LOW_J = ((UChar)0x006a); 1.84 +static const UChar LOW_K = ((UChar)0x006B); 1.85 +static const UChar LOW_L = ((UChar)0x006C); 1.86 +static const UChar LOW_M = ((UChar)0x006D); 1.87 +static const UChar LOW_N = ((UChar)0x006E); 1.88 +static const UChar LOW_O = ((UChar)0x006F); 1.89 +static const UChar LOW_P = ((UChar)0x0070); 1.90 +static const UChar LOW_Q = ((UChar)0x0071); 1.91 +static const UChar LOW_R = ((UChar)0x0072); 1.92 +static const UChar LOW_S = ((UChar)0x0073); 1.93 +static const UChar LOW_T = ((UChar)0x0074); 1.94 +static const UChar LOW_U = ((UChar)0x0075); 1.95 +static const UChar LOW_V = ((UChar)0x0076); 1.96 +static const UChar LOW_W = ((UChar)0x0077); 1.97 +static const UChar LOW_Y = ((UChar)0x0079); 1.98 +static const UChar LOW_Z = ((UChar)0x007A); 1.99 + 1.100 + 1.101 +static const int32_t PLURAL_RANGE_HIGH = 0x7fffffff; 1.102 + 1.103 +enum tokenType { 1.104 + none, 1.105 + tNumber, 1.106 + tComma, 1.107 + tSemiColon, 1.108 + tSpace, 1.109 + tColon, 1.110 + tAt, // '@' 1.111 + tDot, 1.112 + tDot2, 1.113 + tEllipsis, 1.114 + tKeyword, 1.115 + tAnd, 1.116 + tOr, 1.117 + tMod, // 'mod' or '%' 1.118 + tNot, // 'not' only. 1.119 + tIn, // 'in' only. 1.120 + tEqual, // '=' only. 1.121 + tNotEqual, // '!=' 1.122 + tTilde, 1.123 + tWithin, 1.124 + tIs, 1.125 + tVariableN, 1.126 + tVariableI, 1.127 + tVariableF, 1.128 + tVariableV, 1.129 + tVariableT, 1.130 + tDecimal, 1.131 + tInteger, 1.132 + tEOF 1.133 +}; 1.134 + 1.135 + 1.136 +class PluralRuleParser: public UMemory { 1.137 +public: 1.138 + PluralRuleParser(); 1.139 + virtual ~PluralRuleParser(); 1.140 + 1.141 + void parse(const UnicodeString &rules, PluralRules *dest, UErrorCode &status); 1.142 + void getNextToken(UErrorCode &status); 1.143 + void checkSyntax(UErrorCode &status); 1.144 + static int32_t getNumberValue(const UnicodeString &token); 1.145 + 1.146 +private: 1.147 + static tokenType getKeyType(const UnicodeString& token, tokenType type); 1.148 + static tokenType charType(UChar ch); 1.149 + static UBool isValidKeyword(const UnicodeString& token); 1.150 + 1.151 + const UnicodeString *ruleSrc; // The rules string. 1.152 + int32_t ruleIndex; // String index in the input rules, the current parse position. 1.153 + UnicodeString token; // Token most recently scanned. 1.154 + tokenType type; 1.155 + tokenType prevType; 1.156 + 1.157 + // The items currently being parsed & built. 1.158 + // Note: currentChain may not be the last RuleChain in the 1.159 + // list because the "other" chain is forced to the end. 1.160 + AndConstraint *curAndConstraint; 1.161 + RuleChain *currentChain; 1.162 + 1.163 + int32_t rangeLowIdx; // Indices in the UVector of ranges of the 1.164 + int32_t rangeHiIdx; // low and hi values currently being parsed. 1.165 + 1.166 + enum EParseState { 1.167 + kKeyword, 1.168 + kExpr, 1.169 + kValue, 1.170 + kRangeList, 1.171 + kSamples 1.172 + }; 1.173 + 1.174 +}; 1.175 + 1.176 +/** 1.177 + * class FixedDecimal serves to communicate the properties 1.178 + * of a formatted number from a decimal formatter to PluralRules::select() 1.179 + * 1.180 + * see DecimalFormat::getFixedDecimal() 1.181 + * @internal 1.182 + */ 1.183 +class U_I18N_API FixedDecimal: public UMemory { 1.184 + public: 1.185 + /** 1.186 + * @param n the number, e.g. 12.345 1.187 + * @param v The number of visible fraction digits, e.g. 3 1.188 + * @param f The fraction digits, e.g. 345 1.189 + */ 1.190 + FixedDecimal(double n, int32_t v, int64_t f); 1.191 + FixedDecimal(double n, int32_t); 1.192 + explicit FixedDecimal(double n); 1.193 + FixedDecimal(); 1.194 + FixedDecimal(const UnicodeString &s, UErrorCode &ec); 1.195 + FixedDecimal(const FixedDecimal &other); 1.196 + 1.197 + double get(tokenType operand) const; 1.198 + int32_t getVisibleFractionDigitCount() const; 1.199 + 1.200 + void init(double n, int32_t v, int64_t f); 1.201 + void init(double n); 1.202 + UBool quickInit(double n); // Try a fast-path only initialization, 1.203 + // return TRUE if successful. 1.204 + void adjustForMinFractionDigits(int32_t min); 1.205 + static int64_t getFractionalDigits(double n, int32_t v); 1.206 + static int32_t decimals(double n); 1.207 + 1.208 + double source; 1.209 + int32_t visibleDecimalDigitCount; 1.210 + int64_t decimalDigits; 1.211 + int64_t decimalDigitsWithoutTrailingZeros; 1.212 + int64_t intValue; 1.213 + UBool hasIntegerValue; 1.214 + UBool isNegative; 1.215 + UBool isNanOrInfinity; 1.216 +}; 1.217 + 1.218 +class AndConstraint : public UMemory { 1.219 +public: 1.220 + typedef enum RuleOp { 1.221 + NONE, 1.222 + MOD 1.223 + } RuleOp; 1.224 + RuleOp op; 1.225 + int32_t opNum; // for mod expressions, the right operand of the mod. 1.226 + int32_t value; // valid for 'is' rules only. 1.227 + UVector32 *rangeList; // for 'in', 'within' rules. Null otherwise. 1.228 + UBool negated; // TRUE for negated rules. 1.229 + UBool integerOnly; // TRUE for 'within' rules. 1.230 + tokenType digitsType; // n | i | v | f constraint. 1.231 + AndConstraint *next; 1.232 + 1.233 + AndConstraint(); 1.234 + AndConstraint(const AndConstraint& other); 1.235 + virtual ~AndConstraint(); 1.236 + AndConstraint* add(); 1.237 + // UBool isFulfilled(double number); 1.238 + UBool isFulfilled(const FixedDecimal &number); 1.239 +}; 1.240 + 1.241 +class OrConstraint : public UMemory { 1.242 +public: 1.243 + AndConstraint *childNode; 1.244 + OrConstraint *next; 1.245 + OrConstraint(); 1.246 + 1.247 + OrConstraint(const OrConstraint& other); 1.248 + virtual ~OrConstraint(); 1.249 + AndConstraint* add(); 1.250 + // UBool isFulfilled(double number); 1.251 + UBool isFulfilled(const FixedDecimal &number); 1.252 +}; 1.253 + 1.254 +class RuleChain : public UMemory { 1.255 +public: 1.256 + UnicodeString fKeyword; 1.257 + RuleChain *fNext; 1.258 + OrConstraint *ruleHeader; 1.259 + UnicodeString fDecimalSamples; // Samples strings from rule source 1.260 + UnicodeString fIntegerSamples; // without @decimal or @integer, otherwise unprocessed. 1.261 + UBool fDecimalSamplesUnbounded; 1.262 + UBool fIntegerSamplesUnbounded; 1.263 + 1.264 + 1.265 + RuleChain(); 1.266 + RuleChain(const RuleChain& other); 1.267 + virtual ~RuleChain(); 1.268 + 1.269 + UnicodeString select(const FixedDecimal &number) const; 1.270 + void dumpRules(UnicodeString& result); 1.271 + UErrorCode getKeywords(int32_t maxArraySize, UnicodeString *keywords, int32_t& arraySize) const; 1.272 + UBool isKeyword(const UnicodeString& keyword) const; 1.273 +}; 1.274 + 1.275 +class PluralKeywordEnumeration : public StringEnumeration { 1.276 +public: 1.277 + PluralKeywordEnumeration(RuleChain *header, UErrorCode& status); 1.278 + virtual ~PluralKeywordEnumeration(); 1.279 + static UClassID U_EXPORT2 getStaticClassID(void); 1.280 + virtual UClassID getDynamicClassID(void) const; 1.281 + virtual const UnicodeString* snext(UErrorCode& status); 1.282 + virtual void reset(UErrorCode& status); 1.283 + virtual int32_t count(UErrorCode& status) const; 1.284 +private: 1.285 + int32_t pos; 1.286 + UVector fKeywordNames; 1.287 +}; 1.288 + 1.289 + 1.290 +class U_I18N_API PluralAvailableLocalesEnumeration: public StringEnumeration { 1.291 + public: 1.292 + PluralAvailableLocalesEnumeration(UErrorCode &status); 1.293 + virtual ~PluralAvailableLocalesEnumeration(); 1.294 + virtual const char* next(int32_t *resultLength, UErrorCode& status); 1.295 + virtual void reset(UErrorCode& status); 1.296 + virtual int32_t count(UErrorCode& status) const; 1.297 + private: 1.298 + UErrorCode fOpenStatus; 1.299 + UResourceBundle *fLocales; 1.300 + UResourceBundle *fRes; 1.301 +}; 1.302 + 1.303 +U_NAMESPACE_END 1.304 + 1.305 +#endif /* #if !UCONFIG_NO_FORMATTING */ 1.306 + 1.307 +#endif // _PLURRULE_IMPL 1.308 +//eof