ICU-13634 Refactoring new percentage parsing code.

X-SVN-Rev: 41227
This commit is contained in:
Shane Carr 2018-04-14 05:54:53 +00:00
parent 354afa4e79
commit 79f4944ecd
10 changed files with 21 additions and 99 deletions

View File

@ -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();

View File

@ -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);

View File

@ -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 {

View File

@ -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"<Flags>";
}
#endif /* #if !UCONFIG_NO_FORMATTING */

View File

@ -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

View File

@ -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?

View File

@ -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 "<FlagsHandler " + Integer.toHexString(flags) + ">";
}
}

View File

@ -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();

View File

@ -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);
}
}
/**

View File

@ -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?