Search in sources :

Example 31 with ParsingSeparator

use of pcgen.base.text.ParsingSeparator in project pcgen by PCGen.

the class ModifyLst method parseToken.

@Override
public ParseResult parseToken(LoadContext context, CDOMObject obj, String value) {
    if (obj instanceof Campaign) {
        return new ParseResult.Fail(getTokenName() + " may not be used in Campaign Files.  " + "Please use the Global Modifier file", context);
    }
    ParsingSeparator sep = new ParsingSeparator(value, '|');
    sep.addGroupingPair('[', ']');
    sep.addGroupingPair('(', ')');
    if (!sep.hasNext()) {
        return new ParseResult.Fail(getTokenName() + " may not be empty", context);
    }
    String varName = sep.next();
    if (!sep.hasNext()) {
        return new ParseResult.Fail(getTokenName() + " needed 2nd argument: " + value, context);
    }
    String modIdentification = sep.next();
    if (!sep.hasNext()) {
        return new ParseResult.Fail(getTokenName() + " needed third argument: " + value, context);
    }
    String modInstructions = sep.next();
    //Defaults to zero
    int priorityNumber = 0;
    if (sep.hasNext()) {
        String priority = sep.next();
        if (priority.length() < 10) {
            return new ParseResult.Fail(getTokenName() + " was expecting PRIORITY= but got " + priority + " in " + value, context);
        }
        if ("PRIORITY=".equalsIgnoreCase(priority.substring(0, 9))) {
            try {
                priorityNumber = Integer.parseInt(priority.substring(9));
            } catch (NumberFormatException e) {
                return new ParseResult.Fail(getTokenName() + " requires Priority to be an integer: " + priority.substring(9) + " was not an integer");
            }
            if (priorityNumber < 0) {
                return new ParseResult.Fail(getTokenName() + " Priority requires an integer >= 0. " + priorityNumber + " was not positive");
            }
        } else {
            return new ParseResult.Fail(getTokenName() + " was expecting PRIORITY=x but got " + priority + " in " + value, context);
        }
        if (sep.hasNext()) {
            return new ParseResult.Fail(getTokenName() + " had too many arguments: " + value, context);
        }
    }
    ScopeInstance scopeInst = context.getActiveScope();
    LegalScope scope = scopeInst.getLegalScope();
    if (!context.getVariableContext().isLegalVariableID(scope, varName)) {
        return new ParseResult.Fail(getTokenName() + " found invalid var name: " + varName + "(scope: " + scope.getName() + ") Modified on " + obj.getClass().getSimpleName() + ' ' + obj.getKeyName(), context);
    }
    FormatManager<?> format = context.getVariableContext().getVariableFormat(scope, varName);
    return finishProcessing(context, obj, format, varName, modIdentification, modInstructions, priorityNumber);
}
Also used : ScopeInstance(pcgen.base.formula.base.ScopeInstance) Campaign(pcgen.core.Campaign) ParsingSeparator(pcgen.base.text.ParsingSeparator) ParseResult(pcgen.rules.persistence.token.ParseResult) LegalScope(pcgen.base.formula.base.LegalScope)

Example 32 with ParsingSeparator

use of pcgen.base.text.ParsingSeparator in project pcgen by PCGen.

the class RemoveFeatToken method parseNonEmptyToken.

@Override
protected ParseResult parseNonEmptyToken(LoadContext context, CDOMObject obj, String value) {
    AbilityCategory category = AbilityCategory.FEAT;
    Nature nature = Nature.NORMAL;
    ParsingSeparator sep = new ParsingSeparator(value, '|');
    sep.addGroupingPair('[', ']');
    sep.addGroupingPair('(', ')');
    String activeValue = sep.next();
    Formula count;
    if (!sep.hasNext()) {
        count = FormulaFactory.ONE;
    } else {
        count = FormulaFactory.getFormulaFor(activeValue);
        if (!count.isValid()) {
            return new ParseResult.Fail("Count in " + getTokenName() + " was not valid: " + count.toString(), context);
        }
        if (!count.isValid()) {
            return new ParseResult.Fail("Count in " + getTokenName() + " was not valid: " + count.toString(), context);
        }
        if (count.isStatic() && count.resolveStatic().doubleValue() <= 0) {
            return new ParseResult.Fail("Count in " + getFullName() + " must be > 0", context);
        }
        activeValue = sep.next();
    }
    if (sep.hasNext()) {
        return new ParseResult.Fail(getFullName() + " had too many pipe separated items: " + value, context);
    }
    if (isEmpty(activeValue) || hasIllegalSeparator(',', activeValue)) {
        return ParseResult.INTERNAL_ERROR;
    }
    List<CDOMReference<Ability>> refs = new ArrayList<>();
    List<PrimitiveChoiceSet<CNAbilitySelection>> pcs = new ArrayList<>();
    ParsingSeparator tok = new ParsingSeparator(activeValue, ',');
    tok.addGroupingPair('[', ']');
    tok.addGroupingPair('(', ')');
    boolean foundAny = false;
    boolean foundOther = false;
    ReferenceManufacturer<Ability> rm = context.getReferenceContext().getManufacturer(ABILITY_CLASS, AbilityCategory.FEAT);
    while (tok.hasNext()) {
        CDOMReference<Ability> ab = null;
        String token = tok.next();
        if ("CHOICE".equals(token) || Constants.LST_ANY.equals(token)) {
            foundAny = true;
            ab = rm.getAllReference();
        } else if (token.startsWith(Constants.LST_CLASS_DOT) || token.startsWith(Constants.LST_CLASS_EQUAL)) {
            String className = token.substring(6);
            if (className.isEmpty()) {
                return new ParseResult.Fail(getTokenName() + " must have Class name after " + token, context);
            }
            CDOMSingleRef<PCClass> pcc = context.getReferenceContext().getCDOMReference(PCCLASS_CLASS, className);
            AbilityFromClassChoiceSet acs = new AbilityFromClassChoiceSet(pcc);
            pcs.add(acs);
        } else {
            foundOther = true;
            ab = TokenUtilities.getTypeOrPrimitive(rm, token);
            if (ab == null) {
                return new ParseResult.Fail("  Error was encountered while parsing " + getTokenName() + ": " + value + " had an invalid reference: " + token, context);
            }
        }
        if (ab != null) {
            refs.add(ab);
        }
    }
    if (foundAny && foundOther) {
        return new ParseResult.Fail("Non-sensical " + getFullName() + ": Contains ANY and a specific reference: " + value, context);
    }
    if (!refs.isEmpty()) {
        AbilityRefChoiceSet rcs = new AbilityRefChoiceSet(CDOMDirectSingleRef.getRef(category), refs, nature);
        pcs.add(rcs);
    }
    if (pcs.isEmpty()) {
        return new ParseResult.Fail("Internal Error: " + getFullName() + " did not have any references: " + value, context);
    }
    PrimitiveChoiceSet<CNAbilitySelection> ascs;
    if (pcs.size() == 1) {
        ascs = pcs.get(0);
    } else {
        ascs = new CompoundOrChoiceSet<>(pcs, Constants.COMMA);
    }
    ChoiceSet<CNAbilitySelection> cs = new ChoiceSet<>(getTokenName(), ascs, true);
    cs.setTitle("Select for removal");
    PersistentTransitionChoice<CNAbilitySelection> tc = new ConcretePersistentTransitionChoice<>(cs, count);
    context.getObjectContext().addToList(obj, ListKey.REMOVE, tc);
    tc.allowStack(true);
    tc.setChoiceActor(this);
    return ParseResult.SUCCESS;
}
Also used : ArrayList(java.util.ArrayList) ConcretePersistentTransitionChoice(pcgen.cdom.base.ConcretePersistentTransitionChoice) Formula(pcgen.base.formula.Formula) AbilityFromClassChoiceSet(pcgen.cdom.choiceset.AbilityFromClassChoiceSet) CNAbilitySelection(pcgen.cdom.helper.CNAbilitySelection) Nature(pcgen.cdom.enumeration.Nature) Ability(pcgen.core.Ability) CNAbility(pcgen.cdom.content.CNAbility) PrimitiveChoiceSet(pcgen.cdom.base.PrimitiveChoiceSet) ParseResult(pcgen.rules.persistence.token.ParseResult) AbilityRefChoiceSet(pcgen.cdom.choiceset.AbilityRefChoiceSet) AbilityFromClassChoiceSet(pcgen.cdom.choiceset.AbilityFromClassChoiceSet) CompoundOrChoiceSet(pcgen.cdom.choiceset.CompoundOrChoiceSet) ChoiceSet(pcgen.cdom.base.ChoiceSet) PrimitiveChoiceSet(pcgen.cdom.base.PrimitiveChoiceSet) CDOMSingleRef(pcgen.cdom.reference.CDOMSingleRef) ParsingSeparator(pcgen.base.text.ParsingSeparator) AbilityCategory(pcgen.core.AbilityCategory) CDOMReference(pcgen.cdom.base.CDOMReference) AbilityRefChoiceSet(pcgen.cdom.choiceset.AbilityRefChoiceSet)

Example 33 with ParsingSeparator

use of pcgen.base.text.ParsingSeparator in project pcgen by PCGen.

the class Bonus method newBonus.

/**
	 * Create a new Bonus
	 * @param context TODO
	 * @param bonusString
	 * @return BonusObj
	 * 
	 * TODO - This is doing all manner of string parsing.  It really belongs in
	 * the persistence layer.
	 */
public static BonusObj newBonus(LoadContext context, final String bonusString) {
    ParsingSeparator sep = new ParsingSeparator(bonusString, '|');
    sep.addGroupingPair('[', ']');
    sep.addGroupingPair('(', ')');
    if ((bonusString.indexOf(Constants.PIPE) == bonusString.lastIndexOf(Constants.PIPE)) && bonusString.indexOf('%') < 0) {
        Logging.errorPrint("Illegal bonus format: " + bonusString);
        return null;
    }
    String bonusName = sep.next();
    try {
        //Throw away old level value if present
        Integer.parseInt(bonusName);
        bonusName = sep.next().toUpperCase();
    } catch (NumberFormatException exc) {
        bonusName = bonusName.toUpperCase();
    }
    int equalOffset = -1;
    Class<? extends BonusObj> bEntry = TokenLibrary.getBonus(bonusName);
    String typeOfBonus = bonusName;
    if (bEntry == null) {
        equalOffset = bonusName.indexOf('=');
        if (equalOffset >= 0) {
            typeOfBonus = bonusName.substring(0, equalOffset + 1);
            bEntry = TokenLibrary.getBonus(typeOfBonus);
        }
        if (bEntry == null) {
            typeOfBonus = Bonus.BONUS_UNDEFINED;
            Logging.errorPrint("Unrecognized bonus: " + bonusString);
            return null;
        }
    }
    String bonusInfo = sep.next();
    String bValue = "0";
    if (sep.hasNext()) {
        bValue = sep.next();
    }
    if (bValue.startsWith("PRE") || bValue.startsWith("!PRE")) {
        Logging.errorPrint("Invalid BONUS has no value: " + bonusString);
        return null;
    }
    bValue = bValue.toUpperCase();
    BonusObj aBonus = null;
    try {
        aBonus = bEntry.newInstance();
    } catch (Exception exc) {
        Logging.errorPrint("Could not create bonusObj for:" + bonusString);
        return null;
    }
    aBonus.putOriginalString(bonusString.intern());
    aBonus.setBonusName(bonusName.intern());
    aBonus.setTypeOfBonus(typeOfBonus.intern());
    Formula val = aBonus.setValue(bValue.intern());
    if (!val.isValid()) {
        Logging.errorPrint("Could not create bonusObj for:" + bonusString + " since Formula " + bValue + " is not valid: " + val.toString());
        return null;
    }
    while (sep.hasNext()) {
        final String aString = sep.next().toUpperCase();
        if (PreParserFactory.isPreReqString(aString)) {
            try {
                final PreParserFactory factory = PreParserFactory.getInstance();
                aBonus.addPrerequisite(factory.parse(aString));
            } catch (PersistenceLayerException ple) {
                Logging.errorPrint(ple.getMessage(), ple);
                Logging.reportSource(Logging.ERROR, context);
                return null;
            }
        } else if (aString.startsWith("TYPE=") || aString.startsWith("TYPE.")) {
            String bonusType = aString.substring(5);
            int dotLoc = bonusType.indexOf('.');
            if (dotLoc != -1) {
                final String stackingFlag = bonusType.substring(dotLoc + 1);
                // built into the code.
                if (//$NON-NLS-1$
                stackingFlag.startsWith("REPLACE")) {
                    aBonus.setStackingFlag(StackType.REPLACE);
                } else if (//$NON-NLS-1$
                stackingFlag.startsWith("STACK")) {
                    aBonus.setStackingFlag(StackType.STACK);
                }
            }
            final boolean result = aBonus.addType(bonusType.intern());
            if (!result) {
                Logging.log(Logging.LST_ERROR, new StringBuilder().append("Could not add type ").append(aString.substring(5)).append(" to bonusType ").append(typeOfBonus).append(" in Bonus.newBonus").toString());
                Logging.reportSource(Logging.LST_ERROR, context);
                return null;
            }
        }
    }
    if (equalOffset >= 0) {
        aBonus.setVariable(bonusName.substring(equalOffset + 1).intern());
    }
    if (!aBonus.requiresRealCaseTarget()) {
        bonusInfo = bonusInfo.toUpperCase();
    }
    StringTokenizer aTok = new StringTokenizer(bonusInfo, ",");
    if (!aTok.hasMoreTokens()) {
        Logging.log(Logging.LST_ERROR, new StringBuilder().append("Could not parse empty target ").append(" from BONUS:").append(bonusString).toString());
        Logging.reportSource(Logging.LST_ERROR, context);
        return null;
    }
    LstUtils.deprecationCheck(aBonus, bonusName, bonusString);
    while (aTok.hasMoreTokens()) {
        final String token = aTok.nextToken();
        final boolean result = aBonus.parseToken(context, token);
        if (!result) {
            Logging.log(Logging.LST_ERROR, new StringBuilder().append("Could not parse token ").append(token).append(" from BONUS:").append(bonusString).toString());
            Logging.reportSource(Logging.LST_ERROR, context);
            return null;
        }
    }
    return aBonus;
}
Also used : PreParserFactory(pcgen.persistence.lst.prereq.PreParserFactory) PersistenceLayerException(pcgen.persistence.PersistenceLayerException) PersistenceLayerException(pcgen.persistence.PersistenceLayerException) Formula(pcgen.base.formula.Formula) StringTokenizer(java.util.StringTokenizer) ParsingSeparator(pcgen.base.text.ParsingSeparator)

Example 34 with ParsingSeparator

use of pcgen.base.text.ParsingSeparator in project pcgen by PCGen.

the class LookupToken method parseToken.

@Override
public ParseResult parseToken(LoadContext context, KitGear kitGear, String value) {
    ParsingSeparator sep = new ParsingSeparator(value, ',');
    sep.addGroupingPair('[', ']');
    sep.addGroupingPair('(', ')');
    String first = sep.next();
    if (!sep.hasNext()) {
        return new ParseResult.Fail("Token must contain separator ','", context);
    }
    String second = sep.next();
    if (sep.hasNext()) {
        return new ParseResult.Fail("Token cannot have more than one separator ','", context);
    }
    Formula formula = FormulaFactory.getFormulaFor(second);
    if (!formula.isValid()) {
        return new ParseResult.Fail("Formula in " + getTokenName() + " was not valid: " + formula.toString(), context);
    }
    kitGear.loadLookup(first, formula);
    return ParseResult.SUCCESS;
}
Also used : NamedFormula(pcgen.base.util.NamedFormula) Formula(pcgen.base.formula.Formula) ParsingSeparator(pcgen.base.text.ParsingSeparator)

Example 35 with ParsingSeparator

use of pcgen.base.text.ParsingSeparator in project pcgen by PCGen.

the class OptionToken method parseNonEmptyToken.

@Override
protected ParseResult parseNonEmptyToken(LoadContext context, BaseKit kit, String value) {
    ParsingSeparator pipeSep = new ParsingSeparator(value, '|');
    pipeSep.addGroupingPair('[', ']');
    pipeSep.addGroupingPair('(', ')');
    while (pipeSep.hasNext()) {
        String subTok = pipeSep.next();
        if (subTok.isEmpty()) {
            return new ParseResult.Fail(getTokenName() + " arguments has invalid pipe separator: " + value, context);
        }
        ParseResult pr = checkForIllegalSeparator(',', subTok);
        if (!pr.passed()) {
            return pr;
        }
        ParsingSeparator commaSep = new ParsingSeparator(subTok, ',');
        commaSep.addGroupingPair('[', ']');
        commaSep.addGroupingPair('(', ')');
        String minString = commaSep.next();
        String maxString;
        if (commaSep.hasNext()) {
            maxString = commaSep.next();
        } else {
            maxString = subTok;
        }
        if (commaSep.hasNext()) {
            return new ParseResult.Fail("Token cannot have more than one separator ','", context);
        }
        Formula min = FormulaFactory.getFormulaFor(minString);
        if (!min.isValid()) {
            return new ParseResult.Fail("Min Formula in " + getTokenName() + " was not valid: " + min.toString(), context);
        }
        Formula max = FormulaFactory.getFormulaFor(maxString);
        if (!max.isValid()) {
            return new ParseResult.Fail("Max Formula in " + getTokenName() + " was not valid: " + max.toString(), context);
        }
        kit.setOptionBounds(min, max);
    }
    return ParseResult.SUCCESS;
}
Also used : Formula(pcgen.base.formula.Formula) ParsingSeparator(pcgen.base.text.ParsingSeparator) ParseResult(pcgen.rules.persistence.token.ParseResult)

Aggregations

ParsingSeparator (pcgen.base.text.ParsingSeparator)35 Formula (pcgen.base.formula.Formula)26 ParseResult (pcgen.rules.persistence.token.ParseResult)18 ArrayList (java.util.ArrayList)15 CDOMReference (pcgen.cdom.base.CDOMReference)10 ConcretePersistentTransitionChoice (pcgen.cdom.base.ConcretePersistentTransitionChoice)9 StringTokenizer (java.util.StringTokenizer)8 ChoiceSet (pcgen.cdom.base.ChoiceSet)7 ReferenceChoiceSet (pcgen.cdom.choiceset.ReferenceChoiceSet)6 PCClass (pcgen.core.PCClass)5 PersistenceLayerException (pcgen.persistence.PersistenceLayerException)5 Ungranted (pcgen.cdom.base.Ungranted)4 Prerequisite (pcgen.core.prereq.Prerequisite)4 Skill (pcgen.core.Skill)3 LegalScope (pcgen.base.formula.base.LegalScope)2 PrimitiveCollection (pcgen.cdom.base.PrimitiveCollection)2 AbilityRefChoiceSet (pcgen.cdom.choiceset.AbilityRefChoiceSet)2 CNAbility (pcgen.cdom.content.CNAbility)2 LevelCommandFactory (pcgen.cdom.content.LevelCommandFactory)2 Nature (pcgen.cdom.enumeration.Nature)2