All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.qudtlib.support.parse.UnitTransition Maven / Gradle / Ivy

package io.github.qudtlib.support.parse;

import io.github.qudtlib.Qudt;
import io.github.qudtlib.model.FactorUnit;
import io.github.qudtlib.model.Unit;
import java.util.*;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

class UnitTransition extends AbstractStateTransition {
    private static final Pattern P_UNIT = Pattern.compile(".*");

    public UnitTransition() {
        super("Unit", P_UNIT);
    }

    @Override
    public boolean mayMatchLater(String string) {
        return isRelaxedMatchStartForUnit(string);
    }

    @Override
    protected List parse(
            State state,
            String matchedToken,
            List nextTransitions,
            List requiredClosingTransitions) {
        Set units = getMatchingUnits(matchedToken);
        int exponent = state.isDividerSeen() ? -1 : 1;
        List parsedUnitsBase = state.getParsedUnits();
        List> variants =
                units.stream()
                        .map(
                                u -> {
                                    List variant = new ArrayList<>(parsedUnitsBase);

                                    variant.add(
                                            new ParsedUnit(
                                                    makeFactorUnit(u, exponent), matchedToken));
                                    return variant;
                                })
                        .collect(Collectors.toList());
        Deque> transitionStack =
                new ArrayDeque<>(state.getStateTransitionStack());
        if (!state.isAtEnd() && !state.isDividerSeen() && !state.isNegativeExponentSeen()) {
            nextTransitions.add(StateTransition.DIVIDER);
        }
        pushTransitions(transitionStack, requiredClosingTransitions);
        pushTransitions(transitionStack, nextTransitions);
        if (variants.isEmpty()) {
            return List.of();
        }
        return variants.stream()
                .map(
                        variant ->
                                new State(
                                        state.remainingInputForNextState(),
                                        null,
                                        variant,
                                        state.isDividerSeen(),
                                        state.isNegativeExponentSeen(),
                                        transitionStack))
                .toList();
    }

    private FactorUnit makeFactorUnit(Unit u, int exponent) {
        List factorUnitList = u.getFactorUnits().getFactorUnits();
        /*if (factorUnitList.size() == 1 && factorUnitList.get(0).getExponent() != 1) {
            FactorUnit fu = factorUnitList.get(0);
            return new FactorUnit(fu.getUnit(), fu.getExponent() * exponent);
        }*/
        return new FactorUnit(u, exponent);
    }

    static Set getMatchingUnits(String effectiveToken) {
        return Stream.of(
                        Qudt.unitsBySymbol(effectiveToken, false, false).stream(),
                        Qudt.unitsByIriLocalname(effectiveToken, false, true).stream(),
                        Qudt.unitsByLabel(effectiveToken, false, true).stream(),
                        Qudt.unitsByUcumCode(effectiveToken, false, false).stream())
                .flatMap(Function.identity())
                .collect(Collectors.toSet());
    }

    static boolean isRelaxedMatchStartForUnit(String effectiveToken) {
        effectiveToken = effectiveToken.replaceFirst("^1/", "/");
        return !(Qudt.unitsBySymbol(effectiveToken, true, false).isEmpty()
                && Qudt.unitsByIriLocalname(effectiveToken, true, true).isEmpty()
                && Qudt.unitsByLabel(effectiveToken, true, true).isEmpty()
                && Qudt.unitsByUcumCode(effectiveToken, true, false).isEmpty());
    }

    static boolean isRelaxedMatchForUnit(String effectiveToken, Unit u) {
        final String cmp = effectiveToken.replaceFirst("^1/", "/");
        return cmp.equals(u.getSymbol().orElse(null))
                || cmp.equalsIgnoreCase(u.getUcumCode().orElse(null))
                || cmp.equalsIgnoreCase(u.getIriLocalname())
                || u.getLabels().stream().anyMatch(label -> label.getString().equalsIgnoreCase(cmp))
                || cmp.equals(u.getUcumCode().orElse(null));
    }

    @Override
    protected List getRequiredClosingTransitions() {
        return List.of();
    }

    @Override
    protected List getAllowedNextTransitions() {
        return List.of(
                StateTransition.UNIT,
                StateTransition.EXPONENT,
                StateTransition.DOT,
                StateTransition.WHITESPACE,
                StateTransition.OPENING_BRACKET);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy