From 79f4944ecd2eb2e9aa2859fd5c794280bf36fe4c Mon Sep 17 00:00:00 2001 From: Shane Carr Date: Sat, 14 Apr 2018 05:54:53 +0000 Subject: [PATCH] ICU-13634 Refactoring new percentage parsing code. X-SVN-Rev: 41227 --- icu4c/source/i18n/numparse_impl.cpp | 11 +++----- icu4c/source/i18n/numparse_impl.h | 2 -- icu4c/source/i18n/numparse_parsednumber.cpp | 6 ---- icu4c/source/i18n/numparse_validators.cpp | 12 -------- icu4c/source/i18n/numparse_validators.h | 18 ------------ .../source/test/intltest/numbertest_parse.cpp | 12 ++++---- .../icu/impl/number/parse/FlagHandler.java | 28 ------------------- .../impl/number/parse/NumberParserImpl.java | 13 ++++----- .../icu/impl/number/parse/ParsedNumber.java | 6 ---- .../icu/dev/test/number/NumberParserTest.java | 12 ++++---- 10 files changed, 21 insertions(+), 99 deletions(-) delete mode 100644 icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/FlagHandler.java diff --git a/icu4c/source/i18n/numparse_impl.cpp b/icu4c/source/i18n/numparse_impl.cpp index acc68394a1c..25be60726d4 100644 --- a/icu4c/source/i18n/numparse_impl.cpp +++ b/icu4c/source/i18n/numparse_impl.cpp @@ -158,13 +158,9 @@ NumberParserImpl::createParserFromProperties(const number::impl::DecimalFormatPr // and to maintain regressive behavior, divide by 100 even if no percent sign is present. if (affixProvider->containsSymbolType(AffixPatternType::TYPE_PERCENT, status)) { parser->addMatcher(parser->fLocalMatchers.percent = {symbols}); - // causes number to be always scaled by 100: - parser->addMatcher(parser->fLocalValidators.percentFlags = {ResultFlags::FLAG_PERCENT}); } if (affixProvider->containsSymbolType(AffixPatternType::TYPE_PERMILLE, status)) { parser->addMatcher(parser->fLocalMatchers.permille = {symbols}); - // causes number to be always scaled by 1000: - parser->addMatcher(parser->fLocalValidators.permilleFlags = {ResultFlags::FLAG_PERMILLE}); } /////////////////////////////// @@ -206,9 +202,10 @@ NumberParserImpl::createParserFromProperties(const number::impl::DecimalFormatPr properties.decimalSeparatorAlwaysShown || properties.maximumFractionDigits != 0; parser->addMatcher(parser->fLocalValidators.decimalSeparator = {patternHasDecimalSeparator}); } - // NOTE: Don't look at magnitude multiplier here. That is performed when percent sign is seen. - if (properties.multiplier != 1) { - parser->addMatcher(parser->fLocalValidators.multiplier = {multiplierFromProperties(properties)}); + // The multiplier takes care of scaling percentages. + Multiplier multiplier = multiplierFromProperties(properties); + if (multiplier.isValid()) { + parser->addMatcher(parser->fLocalValidators.multiplier = {multiplier}); } parser->freeze(); diff --git a/icu4c/source/i18n/numparse_impl.h b/icu4c/source/i18n/numparse_impl.h index 4677ae14d88..748b9415ecb 100644 --- a/icu4c/source/i18n/numparse_impl.h +++ b/icu4c/source/i18n/numparse_impl.h @@ -80,8 +80,6 @@ class NumberParserImpl : public MutableMatcherCollection { RequireExponentValidator exponent; RequireNumberValidator number; MultiplierParseHandler multiplier; - FlagHandler percentFlags; - FlagHandler permilleFlags; } fLocalValidators; explicit NumberParserImpl(parse_flags_t parseFlags); diff --git a/icu4c/source/i18n/numparse_parsednumber.cpp b/icu4c/source/i18n/numparse_parsednumber.cpp index c658fc27d3e..f97219eed82 100644 --- a/icu4c/source/i18n/numparse_parsednumber.cpp +++ b/icu4c/source/i18n/numparse_parsednumber.cpp @@ -41,12 +41,6 @@ void ParsedNumber::postProcess() { if (!quantity.bogus && 0 != (flags & FLAG_NEGATIVE)) { quantity.negate(); } - if (!quantity.bogus && 0 != (flags & FLAG_PERCENT)) { - quantity.adjustMagnitude(-2); - } - if (!quantity.bogus && 0 != (flags & FLAG_PERMILLE)) { - quantity.adjustMagnitude(-3); - } } bool ParsedNumber::success() const { diff --git a/icu4c/source/i18n/numparse_validators.cpp b/icu4c/source/i18n/numparse_validators.cpp index a36a15f5120..724b0cf0313 100644 --- a/icu4c/source/i18n/numparse_validators.cpp +++ b/icu4c/source/i18n/numparse_validators.cpp @@ -80,16 +80,4 @@ UnicodeString RequireNumberValidator::toString() const { } -FlagHandler::FlagHandler(result_flags_t flags) - : fFlags(flags) {} - -void FlagHandler::postProcess(ParsedNumber& result) const { - result.flags |= fFlags; -} - -UnicodeString FlagHandler::toString() const { - return u""; -} - - #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/icu4c/source/i18n/numparse_validators.h b/icu4c/source/i18n/numparse_validators.h index c27890ae11d..d3bc63aceb3 100644 --- a/icu4c/source/i18n/numparse_validators.h +++ b/icu4c/source/i18n/numparse_validators.h @@ -97,24 +97,6 @@ class MultiplierParseHandler : public ValidationMatcher, public UMemory { }; -/** - * Unconditionally applies a given set of flags to the ParsedNumber in the post-processing step. - */ -class FlagHandler : public ValidationMatcher, public UMemory { - public: - FlagHandler() = default; - - FlagHandler(result_flags_t flags); - - void postProcess(ParsedNumber& result) const U_OVERRIDE; - - UnicodeString toString() const U_OVERRIDE; - - private: - result_flags_t fFlags; -}; - - } // namespace impl } // namespace numparse U_NAMESPACE_END diff --git a/icu4c/source/test/intltest/numbertest_parse.cpp b/icu4c/source/test/intltest/numbertest_parse.cpp index ec8fee01b83..e5a10c2c3fb 100644 --- a/icu4c/source/test/intltest/numbertest_parse.cpp +++ b/icu4c/source/test/intltest/numbertest_parse.cpp @@ -59,12 +59,12 @@ void NumberParserTest::testBasic() { {3, u"51423-", u"0", 5, 51423.}, // plus and minus sign by default do NOT match after {3, u"+51423", u"0", 6, 51423.}, {3, u"51423+", u"0", 5, 51423.}, // plus and minus sign by default do NOT match after - {3, u"%51423", u"0", 6, 514.23}, - {3, u"51423%", u"0", 6, 514.23}, - {3, u"51423%%", u"0", 6, 514.23}, - {3, u"‰51423", u"0", 6, 51.423}, - {3, u"51423‰", u"0", 6, 51.423}, - {3, u"51423‰‰", u"0", 6, 51.423}, + {3, u"%51423", u"0", 6, 51423.}, + {3, u"51423%", u"0", 6, 51423.}, + {3, u"51423%%", u"0", 6, 51423.}, + {3, u"‰51423", u"0", 6, 51423.}, + {3, u"51423‰", u"0", 6, 51423.}, + {3, u"51423‰‰", u"0", 6, 51423.}, {3, u"∞", u"0", 1, INFINITY}, {3, u"-∞", u"0", 2, -INFINITY}, {3, u"@@@123 @@", u"0", 6, 123.}, // TODO: Should padding be strong instead of weak? diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/FlagHandler.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/FlagHandler.java deleted file mode 100644 index 37d39113ad7..00000000000 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/FlagHandler.java +++ /dev/null @@ -1,28 +0,0 @@ -// © 2018 and later: Unicode, Inc. and others. -// License & terms of use: http://www.unicode.org/copyright.html#License -package com.ibm.icu.impl.number.parse; - -/** - * Unconditionally applies a given set of flags to the ParsedNumber in the post-processing step. - */ -public class FlagHandler extends ValidationMatcher { - - public static final FlagHandler PERCENT = new FlagHandler(ParsedNumber.FLAG_PERCENT); - public static final FlagHandler PERMILLE = new FlagHandler(ParsedNumber.FLAG_PERMILLE); - - private final int flags; - - private FlagHandler(int flags) { - this.flags = flags; - } - - @Override - public void postProcess(ParsedNumber result) { - result.flags |= flags; - } - - @Override - public String toString() { - return ""; - } -} diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java index 3d41c37ce78..0e964ef5762 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java @@ -19,6 +19,7 @@ import com.ibm.icu.impl.number.PatternStringParser; import com.ibm.icu.impl.number.PatternStringParser.ParsedPatternInfo; import com.ibm.icu.impl.number.PropertiesAffixPatternProvider; import com.ibm.icu.impl.number.RoundingUtils; +import com.ibm.icu.number.Multiplier; import com.ibm.icu.number.NumberFormatter.GroupingStrategy; import com.ibm.icu.text.DecimalFormatSymbols; import com.ibm.icu.util.Currency; @@ -204,13 +205,9 @@ public class NumberParserImpl { // and to maintain regressive behavior, divide by 100 even if no percent sign is present. if (affixProvider.containsSymbolType(AffixUtils.TYPE_PERCENT)) { parser.addMatcher(PercentMatcher.getInstance(symbols)); - // causes number to be always scaled by 100: - parser.addMatcher(FlagHandler.PERCENT); } if (affixProvider.containsSymbolType(AffixUtils.TYPE_PERMILLE)) { parser.addMatcher(PermilleMatcher.getInstance(symbols)); - // causes number to be always scaled by 1000: - parser.addMatcher(FlagHandler.PERMILLE); } /////////////////////////////// @@ -252,10 +249,10 @@ public class NumberParserImpl { || properties.getMaximumFractionDigits() != 0; parser.addMatcher(RequireDecimalSeparatorValidator.getInstance(patternHasDecimalSeparator)); } - // NOTE: Don't look at magnitude multiplier here. That is performed when percent sign is seen. - if (properties.getMultiplier() != null) { - parser.addMatcher( - new MultiplierParseHandler(RoundingUtils.multiplierFromProperties(properties))); + // The multiplier takes care of scaling percentages. + Multiplier multiplier = RoundingUtils.multiplierFromProperties(properties); + if (multiplier != null) { + parser.addMatcher(new MultiplierParseHandler(multiplier)); } parser.freeze(); diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/ParsedNumber.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/ParsedNumber.java index 40277d7700e..c6e686e64e2 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/ParsedNumber.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/ParsedNumber.java @@ -116,12 +116,6 @@ public class ParsedNumber { if (quantity != null && 0 != (flags & FLAG_NEGATIVE)) { quantity.negate(); } - if (quantity != null && 0 != (flags & FLAG_PERCENT)) { - quantity.adjustMagnitude(-2); - } - if (quantity != null && 0 != (flags & FLAG_PERMILLE)) { - quantity.adjustMagnitude(-3); - } } /** diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberParserTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberParserTest.java index 57aef1547ca..cf6ed3dc5b8 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberParserTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberParserTest.java @@ -65,12 +65,12 @@ public class NumberParserTest { { 3, "51423-", "0", 5, 51423. }, // plus and minus sign by default do NOT match after { 3, "+51423", "0", 6, 51423. }, { 3, "51423+", "0", 5, 51423. }, // plus and minus sign by default do NOT match after - { 3, "%51423", "0", 6, 514.23 }, - { 3, "51423%", "0", 6, 514.23 }, - { 3, "51423%%", "0", 6, 514.23 }, - { 3, "‰51423", "0", 6, 51.423 }, - { 3, "51423‰", "0", 6, 51.423 }, - { 3, "51423‰‰", "0", 6, 51.423 }, + { 3, "%51423", "0", 6, 51423. }, + { 3, "51423%", "0", 6, 51423. }, + { 3, "51423%%", "0", 6, 51423. }, + { 3, "‰51423", "0", 6, 51423. }, + { 3, "51423‰", "0", 6, 51423. }, + { 3, "51423‰‰", "0", 6, 51423. }, { 3, "∞", "0", 1, Double.POSITIVE_INFINITY }, { 3, "-∞", "0", 2, Double.NEGATIVE_INFINITY }, { 3, "@@@123 @@", "0", 6, 123. }, // TODO: Should padding be strong instead of weak? -- 2.40.0