|
1 /* |
|
2 ******************************************************************************* |
|
3 * Copyright (C) 2007-2013, International Business Machines Corporation and |
|
4 * others. All Rights Reserved. |
|
5 ******************************************************************************* |
|
6 * |
|
7 * File PLURRULE_IMPL.H |
|
8 * |
|
9 ******************************************************************************* |
|
10 */ |
|
11 |
|
12 |
|
13 #ifndef PLURRULE_IMPLE |
|
14 #define PLURRULE_IMPLE |
|
15 |
|
16 // Internal definitions for the PluralRules implementation. |
|
17 |
|
18 #if !UCONFIG_NO_FORMATTING |
|
19 |
|
20 #include "unicode/format.h" |
|
21 #include "unicode/locid.h" |
|
22 #include "unicode/parseerr.h" |
|
23 #include "unicode/ures.h" |
|
24 #include "unicode/utypes.h" |
|
25 #include "uvector.h" |
|
26 #include "hash.h" |
|
27 |
|
28 class PluralRulesTest; |
|
29 |
|
30 U_NAMESPACE_BEGIN |
|
31 |
|
32 class AndConstraint; |
|
33 class RuleChain; |
|
34 |
|
35 static const UChar DOT = ((UChar)0x002E); |
|
36 static const UChar SINGLE_QUOTE = ((UChar)0x0027); |
|
37 static const UChar SLASH = ((UChar)0x002F); |
|
38 static const UChar BACKSLASH = ((UChar)0x005C); |
|
39 static const UChar SPACE = ((UChar)0x0020); |
|
40 static const UChar EXCLAMATION = ((UChar)0x0021); |
|
41 static const UChar QUOTATION_MARK = ((UChar)0x0022); |
|
42 static const UChar NUMBER_SIGN = ((UChar)0x0023); |
|
43 static const UChar PERCENT_SIGN = ((UChar)0x0025); |
|
44 static const UChar ASTERISK = ((UChar)0x002A); |
|
45 static const UChar COMMA = ((UChar)0x002C); |
|
46 static const UChar HYPHEN = ((UChar)0x002D); |
|
47 static const UChar U_ZERO = ((UChar)0x0030); |
|
48 static const UChar U_ONE = ((UChar)0x0031); |
|
49 static const UChar U_TWO = ((UChar)0x0032); |
|
50 static const UChar U_THREE = ((UChar)0x0033); |
|
51 static const UChar U_FOUR = ((UChar)0x0034); |
|
52 static const UChar U_FIVE = ((UChar)0x0035); |
|
53 static const UChar U_SIX = ((UChar)0x0036); |
|
54 static const UChar U_SEVEN = ((UChar)0x0037); |
|
55 static const UChar U_EIGHT = ((UChar)0x0038); |
|
56 static const UChar U_NINE = ((UChar)0x0039); |
|
57 static const UChar COLON = ((UChar)0x003A); |
|
58 static const UChar SEMI_COLON = ((UChar)0x003B); |
|
59 static const UChar EQUALS = ((UChar)0x003D); |
|
60 static const UChar AT = ((UChar)0x0040); |
|
61 static const UChar CAP_A = ((UChar)0x0041); |
|
62 static const UChar CAP_B = ((UChar)0x0042); |
|
63 static const UChar CAP_R = ((UChar)0x0052); |
|
64 static const UChar CAP_Z = ((UChar)0x005A); |
|
65 static const UChar LOWLINE = ((UChar)0x005F); |
|
66 static const UChar LEFTBRACE = ((UChar)0x007B); |
|
67 static const UChar RIGHTBRACE = ((UChar)0x007D); |
|
68 static const UChar TILDE = ((UChar)0x007E); |
|
69 static const UChar ELLIPSIS = ((UChar)0x2026); |
|
70 |
|
71 static const UChar LOW_A = ((UChar)0x0061); |
|
72 static const UChar LOW_B = ((UChar)0x0062); |
|
73 static const UChar LOW_C = ((UChar)0x0063); |
|
74 static const UChar LOW_D = ((UChar)0x0064); |
|
75 static const UChar LOW_E = ((UChar)0x0065); |
|
76 static const UChar LOW_F = ((UChar)0x0066); |
|
77 static const UChar LOW_G = ((UChar)0x0067); |
|
78 static const UChar LOW_H = ((UChar)0x0068); |
|
79 static const UChar LOW_I = ((UChar)0x0069); |
|
80 static const UChar LOW_J = ((UChar)0x006a); |
|
81 static const UChar LOW_K = ((UChar)0x006B); |
|
82 static const UChar LOW_L = ((UChar)0x006C); |
|
83 static const UChar LOW_M = ((UChar)0x006D); |
|
84 static const UChar LOW_N = ((UChar)0x006E); |
|
85 static const UChar LOW_O = ((UChar)0x006F); |
|
86 static const UChar LOW_P = ((UChar)0x0070); |
|
87 static const UChar LOW_Q = ((UChar)0x0071); |
|
88 static const UChar LOW_R = ((UChar)0x0072); |
|
89 static const UChar LOW_S = ((UChar)0x0073); |
|
90 static const UChar LOW_T = ((UChar)0x0074); |
|
91 static const UChar LOW_U = ((UChar)0x0075); |
|
92 static const UChar LOW_V = ((UChar)0x0076); |
|
93 static const UChar LOW_W = ((UChar)0x0077); |
|
94 static const UChar LOW_Y = ((UChar)0x0079); |
|
95 static const UChar LOW_Z = ((UChar)0x007A); |
|
96 |
|
97 |
|
98 static const int32_t PLURAL_RANGE_HIGH = 0x7fffffff; |
|
99 |
|
100 enum tokenType { |
|
101 none, |
|
102 tNumber, |
|
103 tComma, |
|
104 tSemiColon, |
|
105 tSpace, |
|
106 tColon, |
|
107 tAt, // '@' |
|
108 tDot, |
|
109 tDot2, |
|
110 tEllipsis, |
|
111 tKeyword, |
|
112 tAnd, |
|
113 tOr, |
|
114 tMod, // 'mod' or '%' |
|
115 tNot, // 'not' only. |
|
116 tIn, // 'in' only. |
|
117 tEqual, // '=' only. |
|
118 tNotEqual, // '!=' |
|
119 tTilde, |
|
120 tWithin, |
|
121 tIs, |
|
122 tVariableN, |
|
123 tVariableI, |
|
124 tVariableF, |
|
125 tVariableV, |
|
126 tVariableT, |
|
127 tDecimal, |
|
128 tInteger, |
|
129 tEOF |
|
130 }; |
|
131 |
|
132 |
|
133 class PluralRuleParser: public UMemory { |
|
134 public: |
|
135 PluralRuleParser(); |
|
136 virtual ~PluralRuleParser(); |
|
137 |
|
138 void parse(const UnicodeString &rules, PluralRules *dest, UErrorCode &status); |
|
139 void getNextToken(UErrorCode &status); |
|
140 void checkSyntax(UErrorCode &status); |
|
141 static int32_t getNumberValue(const UnicodeString &token); |
|
142 |
|
143 private: |
|
144 static tokenType getKeyType(const UnicodeString& token, tokenType type); |
|
145 static tokenType charType(UChar ch); |
|
146 static UBool isValidKeyword(const UnicodeString& token); |
|
147 |
|
148 const UnicodeString *ruleSrc; // The rules string. |
|
149 int32_t ruleIndex; // String index in the input rules, the current parse position. |
|
150 UnicodeString token; // Token most recently scanned. |
|
151 tokenType type; |
|
152 tokenType prevType; |
|
153 |
|
154 // The items currently being parsed & built. |
|
155 // Note: currentChain may not be the last RuleChain in the |
|
156 // list because the "other" chain is forced to the end. |
|
157 AndConstraint *curAndConstraint; |
|
158 RuleChain *currentChain; |
|
159 |
|
160 int32_t rangeLowIdx; // Indices in the UVector of ranges of the |
|
161 int32_t rangeHiIdx; // low and hi values currently being parsed. |
|
162 |
|
163 enum EParseState { |
|
164 kKeyword, |
|
165 kExpr, |
|
166 kValue, |
|
167 kRangeList, |
|
168 kSamples |
|
169 }; |
|
170 |
|
171 }; |
|
172 |
|
173 /** |
|
174 * class FixedDecimal serves to communicate the properties |
|
175 * of a formatted number from a decimal formatter to PluralRules::select() |
|
176 * |
|
177 * see DecimalFormat::getFixedDecimal() |
|
178 * @internal |
|
179 */ |
|
180 class U_I18N_API FixedDecimal: public UMemory { |
|
181 public: |
|
182 /** |
|
183 * @param n the number, e.g. 12.345 |
|
184 * @param v The number of visible fraction digits, e.g. 3 |
|
185 * @param f The fraction digits, e.g. 345 |
|
186 */ |
|
187 FixedDecimal(double n, int32_t v, int64_t f); |
|
188 FixedDecimal(double n, int32_t); |
|
189 explicit FixedDecimal(double n); |
|
190 FixedDecimal(); |
|
191 FixedDecimal(const UnicodeString &s, UErrorCode &ec); |
|
192 FixedDecimal(const FixedDecimal &other); |
|
193 |
|
194 double get(tokenType operand) const; |
|
195 int32_t getVisibleFractionDigitCount() const; |
|
196 |
|
197 void init(double n, int32_t v, int64_t f); |
|
198 void init(double n); |
|
199 UBool quickInit(double n); // Try a fast-path only initialization, |
|
200 // return TRUE if successful. |
|
201 void adjustForMinFractionDigits(int32_t min); |
|
202 static int64_t getFractionalDigits(double n, int32_t v); |
|
203 static int32_t decimals(double n); |
|
204 |
|
205 double source; |
|
206 int32_t visibleDecimalDigitCount; |
|
207 int64_t decimalDigits; |
|
208 int64_t decimalDigitsWithoutTrailingZeros; |
|
209 int64_t intValue; |
|
210 UBool hasIntegerValue; |
|
211 UBool isNegative; |
|
212 UBool isNanOrInfinity; |
|
213 }; |
|
214 |
|
215 class AndConstraint : public UMemory { |
|
216 public: |
|
217 typedef enum RuleOp { |
|
218 NONE, |
|
219 MOD |
|
220 } RuleOp; |
|
221 RuleOp op; |
|
222 int32_t opNum; // for mod expressions, the right operand of the mod. |
|
223 int32_t value; // valid for 'is' rules only. |
|
224 UVector32 *rangeList; // for 'in', 'within' rules. Null otherwise. |
|
225 UBool negated; // TRUE for negated rules. |
|
226 UBool integerOnly; // TRUE for 'within' rules. |
|
227 tokenType digitsType; // n | i | v | f constraint. |
|
228 AndConstraint *next; |
|
229 |
|
230 AndConstraint(); |
|
231 AndConstraint(const AndConstraint& other); |
|
232 virtual ~AndConstraint(); |
|
233 AndConstraint* add(); |
|
234 // UBool isFulfilled(double number); |
|
235 UBool isFulfilled(const FixedDecimal &number); |
|
236 }; |
|
237 |
|
238 class OrConstraint : public UMemory { |
|
239 public: |
|
240 AndConstraint *childNode; |
|
241 OrConstraint *next; |
|
242 OrConstraint(); |
|
243 |
|
244 OrConstraint(const OrConstraint& other); |
|
245 virtual ~OrConstraint(); |
|
246 AndConstraint* add(); |
|
247 // UBool isFulfilled(double number); |
|
248 UBool isFulfilled(const FixedDecimal &number); |
|
249 }; |
|
250 |
|
251 class RuleChain : public UMemory { |
|
252 public: |
|
253 UnicodeString fKeyword; |
|
254 RuleChain *fNext; |
|
255 OrConstraint *ruleHeader; |
|
256 UnicodeString fDecimalSamples; // Samples strings from rule source |
|
257 UnicodeString fIntegerSamples; // without @decimal or @integer, otherwise unprocessed. |
|
258 UBool fDecimalSamplesUnbounded; |
|
259 UBool fIntegerSamplesUnbounded; |
|
260 |
|
261 |
|
262 RuleChain(); |
|
263 RuleChain(const RuleChain& other); |
|
264 virtual ~RuleChain(); |
|
265 |
|
266 UnicodeString select(const FixedDecimal &number) const; |
|
267 void dumpRules(UnicodeString& result); |
|
268 UErrorCode getKeywords(int32_t maxArraySize, UnicodeString *keywords, int32_t& arraySize) const; |
|
269 UBool isKeyword(const UnicodeString& keyword) const; |
|
270 }; |
|
271 |
|
272 class PluralKeywordEnumeration : public StringEnumeration { |
|
273 public: |
|
274 PluralKeywordEnumeration(RuleChain *header, UErrorCode& status); |
|
275 virtual ~PluralKeywordEnumeration(); |
|
276 static UClassID U_EXPORT2 getStaticClassID(void); |
|
277 virtual UClassID getDynamicClassID(void) const; |
|
278 virtual const UnicodeString* snext(UErrorCode& status); |
|
279 virtual void reset(UErrorCode& status); |
|
280 virtual int32_t count(UErrorCode& status) const; |
|
281 private: |
|
282 int32_t pos; |
|
283 UVector fKeywordNames; |
|
284 }; |
|
285 |
|
286 |
|
287 class U_I18N_API PluralAvailableLocalesEnumeration: public StringEnumeration { |
|
288 public: |
|
289 PluralAvailableLocalesEnumeration(UErrorCode &status); |
|
290 virtual ~PluralAvailableLocalesEnumeration(); |
|
291 virtual const char* next(int32_t *resultLength, UErrorCode& status); |
|
292 virtual void reset(UErrorCode& status); |
|
293 virtual int32_t count(UErrorCode& status) const; |
|
294 private: |
|
295 UErrorCode fOpenStatus; |
|
296 UResourceBundle *fLocales; |
|
297 UResourceBundle *fRes; |
|
298 }; |
|
299 |
|
300 U_NAMESPACE_END |
|
301 |
|
302 #endif /* #if !UCONFIG_NO_FORMATTING */ |
|
303 |
|
304 #endif // _PLURRULE_IMPL |
|
305 //eof |