private ParseResult fracLikeNumberParse()

in libraries/bot-dialogs/src/main/java/com/microsoft/recognizers/text/number/parsers/BaseNumberParser.java [169:296]


    private ParseResult fracLikeNumberParse(ExtractResult extractResult) {

        ParseResult result = new ParseResult(extractResult.getStart(), extractResult.getLength(), extractResult.getText(), extractResult.getType(), null, null, null);
        String resultText = extractResult.getText().toLowerCase();

        Matcher match = config.getFractionPrepositionRegex().matcher(resultText);
        if (match.find()) {

            String numerator = match.group("numerator");
            String denominator = match.group("denominator");

            double smallValue = Character.isDigit(numerator.charAt(0)) ?
                    getDigitalValue(numerator, 1) :
                    getIntValue(getMatches(numerator));

            double bigValue = Character.isDigit(denominator.charAt(0)) ?
                    getDigitalValue(denominator, 1) :
                    getIntValue(getMatches(denominator));

            result.setValue(smallValue / bigValue);
        } else {
            List<String> fracWords = config.normalizeTokenSet(Arrays.asList(resultText.split(" ")), result);

            // Split fraction with integer
            int splitIndex = fracWords.size() - 1;
            long currentValue = config.resolveCompositeNumber(fracWords.get(splitIndex));
            long roundValue = 1;

            // For case like "half"
            if (fracWords.size() == 1) {
                result.setValue(1 / getIntValue(fracWords));
                return result;
            }

            for (splitIndex = fracWords.size() - 2; splitIndex >= 0; splitIndex--) {

                String fracWord = fracWords.get(splitIndex);
                if (config.getWrittenFractionSeparatorTexts().contains(fracWord) ||
                    config.getWrittenIntegerSeparatorTexts().contains(fracWord)) {
                    continue;
                }

                long previousValue = currentValue;
                currentValue = config.resolveCompositeNumber(fracWord);

                int smHundreds = 100;

                // previous : hundred
                // current : one
                if ((previousValue >= smHundreds && previousValue > currentValue) ||
                        (previousValue < smHundreds && isComposable(currentValue, previousValue))) {
                    if (previousValue < smHundreds && currentValue >= roundValue) {
                        roundValue = currentValue;
                    } else if (previousValue < smHundreds && currentValue < roundValue) {
                        splitIndex++;
                        break;
                    }

                    // current is the first word
                    if (splitIndex == 0) {
                        // scan, skip the first word
                        splitIndex = 1;
                        while (splitIndex <= fracWords.size() - 2) {
                            // e.g. one hundred thousand
                            // frac[i+1] % 100 && frac[i] % 100 = 0
                            if (config.resolveCompositeNumber(fracWords.get(splitIndex)) >= smHundreds &&
                                    !config.getWrittenFractionSeparatorTexts().contains(fracWords.get(splitIndex + 1)) &&
                                    config.resolveCompositeNumber(fracWords.get(splitIndex + 1)) < smHundreds) {
                                splitIndex++;
                                break;
                            }
                            splitIndex++;
                        }
                        break;
                    }
                    continue;
                }
                splitIndex++;
                break;
            }

            if (splitIndex < 0) {
                splitIndex = 0;
            }

            List<String> fracPart = new ArrayList<String>();
            for (int i = splitIndex; i < fracWords.size(); i++) {
                if (fracWords.get(i).contains("-")) {
                    String[] split = fracWords.get(i).split(Pattern.quote("-"));
                    fracPart.add(split[0]);
                    fracPart.add("-");
                    fracPart.add(split[1]);
                } else {
                    fracPart.add(fracWords.get(i));
                }
            }

            fracWords.subList(splitIndex, fracWords.size()).clear();

            // denomi = denominator
            double denomiValue = getIntValue(fracPart);
            // Split mixed number with fraction
            double numerValue = 0;
            double intValue = 0;

            int mixedIndex = fracWords.size();
            for (int i = fracWords.size() - 1; i >= 0; i--) {
                if (i < fracWords.size() - 1 && config.getWrittenFractionSeparatorTexts().contains(fracWords.get(i))) {
                    String numerStr = String.join(" ", fracWords.subList(i + 1, fracWords.size()));
                    numerValue = getIntValue(getMatches(numerStr));
                    mixedIndex = i + 1;
                    break;
                }
            }

            String intStr = String.join(" ", fracWords.subList(0, mixedIndex));
            intValue = getIntValue(getMatches(intStr));

            // Find mixed number
            if (mixedIndex != fracWords.size() && numerValue < denomiValue) {
                result.setValue(intValue + numerValue / denomiValue);
            } else {
                result.setValue((intValue + numerValue) / denomiValue);
            }
        }

        return result;
    }