Exemple #1
0
 public void ParseResult_GetValueOrDefault()
 {
     ParseResult.Success(1, new TextPosition()).GetValueOrDefault().ShouldBe(1);
     ParseResult.Success(1, new TextPosition()).GetValueOrDefault(2).ShouldBe(1);
     ParseResult.Failure <int>(new TextPosition()).GetValueOrDefault().ShouldBe(0);
     ParseResult.Failure <int>(new TextPosition()).GetValueOrDefault(2).ShouldBe(2);
 }
        public void ParseReturnsCorrectResult()
        {
            var untranslatedStats = new[]
            {
                new UntranslatedStat("a", 1),
                new UntranslatedStat("b", 2),
                new UntranslatedStat("c", 3),
            };
            var modifierLines        = new[] { "a1", "b2" };
            var statTranslatorResult = new StatTranslatorResult(modifierLines, new UntranslatedStat[0]);
            var translator           = Mock.Of <IStatTranslator>(t => t.Translate(untranslatedStats) == statTranslatorResult);
            var localSource          = new ModifierSource.Local.Skill();
            var globalSource         = new ModifierSource.Global(localSource);
            var coreParserParameters = new[]
            {
                new CoreParserParameter(modifierLines[0], globalSource, Entity.Character),
                new CoreParserParameter(modifierLines[1], globalSource, Entity.Character),
            };
            var parseResults = new[]
            {
                ParseResult.Empty,
                ParseResult.Failure("b2", ""),
            };
            var coreParser = Mock.Of <ICoreParser>(p =>
                                                   p.Parse(coreParserParameters[0]) == parseResults[0] &&
                                                   p.Parse(coreParserParameters[1]) == parseResults[1]);

            var sut             = new UntranslatedStatParser(translator, coreParser);
            var parserParameter = new UntranslatedStatParserParameter(localSource, untranslatedStats);
            var expected        = ParseResult.Aggregate(parseResults);

            var actual = sut.Parse(parserParameter);

            Assert.AreEqual(expected, actual);
        }
Exemple #3
0
        public override ParseResult Parse(ParseContext ctx)
        {
            var oldPos = ctx.CurrentPosition;

            var         matchedParseMark    = 0;
            ParseResult matchedChoiceResult = null;
            var         matchedChoice       = Elements.FirstOrDefault(e =>
            {
                ctx.CurrentPosition = oldPos;
                ctx.StartMatch();
                var result = e.Element.Parse(ctx);

                var resultIsSuccess = result?.IsSuccess ?? false;
                if (resultIsSuccess)
                {
                    ctx.EndMatch(SaveChoice, this);
                }
                else
                {
                    ctx.UndoMatch();
                }

                matchedParseMark = !(result?.IsOptionallyMatched ?? false) ? result?.ParseMark ?? 0 : 0;

                if (!resultIsSuccess)
                {
                    ctx.CurrentPosition = oldPos;
                }

                if (resultIsSuccess)
                {
                    matchedChoiceResult = result;
                }
                return(resultIsSuccess);
            });

            if (matchedChoice == null)
            {
                return(ParseResult.Failure(ctx));
            }

            var success = ParseResult.Success(ctx);

            if (!(matchedChoiceResult?.IsOptionallyMatched ?? false))
            {
                success.ParseMark ^= matchedChoice.ParseMark ^ matchedParseMark;
            }

            return(success);
        }
Exemple #4
0
        public void AddThrowsIfStatLineIsNotSuccessfullyParsed()
        {
            var givenStats = new[]
            {
                Mock.Of <IGivenStats>(s =>
                                      s.AffectedEntities == new[] { Entity.Character } &&
                                      s.GivenStatLines == new[] { "s1" } &&
                                      s.GivenModifiers == new IIntermediateModifier[0])
            };
            var parseResult = ParseResult.Failure("", "");
            var parser      = Mock.Of <ICoreParser>(p =>
                                                    p.Parse(new CoreParserParameter("s1", GlobalSource, Entity.Character)) == parseResult);

            Assert.Throws <ParseException>(() => GivenStatsParser.Parse(parser, givenStats));
        }
        public override ParseResult Parse(ParseContext contextToUse)
        {
            var shouldSkipWhitespaces =
                (string.IsNullOrWhiteSpace(contextToUse.PeekPrevious(1)) || contextToUse.HasFinishedLine) &&
                string.IsNullOrWhiteSpace(Value);

            if (shouldSkipWhitespaces)
            {
                return(ParseResult.OptionalSuccess(contextToUse));
            }

            return(contextToUse.ReadNext(Value.Length).EqualsIgnoreCase(Value)
                ? ParseResult.Success(contextToUse)
                : ParseResult.Failure(contextToUse));
        }
Exemple #6
0
        public ParseResult NarrowedParse(ParseContext ctx, bool tryNarrowContext = false)
        {
            var contextToUse = ctx;

            if (tryNarrowContext && NarrowContextIfPossible(ref contextToUse, out var parseResult))
            {
                return(parseResult);
            }

            var skriptTypesManager = WorkspaceManager.CurrentWorkspace.TypesManager;

            //Split the types (if any)
            foreach (var typeRaw in Type.Split("/"))
            {
                var isObjectType = typeRaw.ToLower() == "object" || typeRaw.ToLower() == "objects";
                var skriptType   = skriptTypesManager.GetType(typeRaw);
                //Try to get a known type literal provider for that type
                var         type = WorkspaceManager.Instance.KnownTypesManager.GetTypeByName(typeRaw);
                ISkriptType skriptTypeDescriptor = null;

                /*if (!RuntimeHelpers.TryEnsureSufficientExecutionStack())
                 *  return ParseResult.Failure(ctx);*/

                //Check if this type requires more than one variable
                var isMultipleValues = typeRaw.EndsWith("s");
                if (isMultipleValues)
                {
                    //It does so we first have to get the singular type representation for this type
                    //Either get from the name we're given or just subtract the last letter ('s') from it
                    type = WorkspaceManager.Instance.KnownTypesManager.GetTypeByName(typeRaw) ??
                           WorkspaceManager.Instance.KnownTypesManager.GetTypeByName(
                        typeRaw.Substring(0, typeRaw.Length - 1)
                        );

                    //If we have a type, replace the type descriptor for the generic multi type matcher
                    if (type != null) // Hand over to GenericMultiValueType
                    {
                        skriptTypeDescriptor = new GenericMultiValueType(type, Constraint, CanMatchListConjunctions);
                    }
                }
                else
                {
                    //We got a single type so, use it.
                    skriptTypeDescriptor = type?.CreateNewInstance();
                }

                IExpression result = null;
                var         oldPos = contextToUse.CurrentPosition;

                //In case it isn't for an object, always try matching type
                //if (!isObjectType && (!ctx.Properties.WrappedObjectCount) && !contextToUse.ShouldJustCheckExpressionsThatMatchType)
                if (isObjectType && ctx.Properties.WrappedObjectCount < 2 ||
                    !isObjectType && !contextToUse.ShouldJustCheckExpressionsThatMatchType)
                {
                    result = skriptTypeDescriptor?.TryParseValue(contextToUse);
                }


                //This type has a flag to attempt to match conditionals. So, let's try do just that.
                if (result == null &&
                    Constraint.HasFlagFast(SyntaxValueAcceptanceConstraint.AllowConditionalExpressions))
                {
                    foreach (var condition in skriptTypesManager.KnownConditionsFromAddons)
                    {
                        var clone = contextToUse.Clone(false);

                        for (var index = 0; index < condition.PatternNodes.Length; index++)
                        {
                            var conditionPatternNode = condition.PatternNodes[index];
                            clone.CurrentPosition = contextToUse.CurrentPosition;
                            clone.StartRangeMeasure("Condition");
                            var conditionResult = conditionPatternNode.Parse(clone);

                            if (conditionResult.IsSuccess)
                            {
                                //Read on real context until our current position on cloned ctx
                                contextToUse.ReadUntilPosition(clone.CurrentPosition);
                                result = new ConditionalExpression(condition, clone.Matches, index,
                                                                   clone.EndRangeMeasure(), contextToUse);
                            }

                            clone.UndoRangeMeasure();
                        }
                    }
                }


                //This type doesn't have a flag to just match literals So, let's try first matching variables.
                if (result == null && !Constraint.HasFlagFast(SyntaxValueAcceptanceConstraint.LiteralsOnly))
                {
                    //Try parsing a variable
                    var reference = new SkriptVariableReferenceType();
                    var ctxClone  = contextToUse.Clone();
                    try
                    {
                        result = reference.TryParseValue(ctxClone);
                    }
                    catch (Exception)
                    {
                        // ignored
                    }

                    if (result != null)
                    {
                        contextToUse.ReadUntilPosition(ctxClone.CurrentPosition);
                    }
                }


                //We have not matched a result. Let's try matching with parentheses
                if (result == null && !SkipParenthesis)
                {
                    // Type descriptor wasn't able to parse the literal. Push back and try with parentheses.
                    contextToUse.CurrentPosition = oldPos;

                    //Try parsing with parentheses first
                    var parenthesesType = new GenericParenthesesType(typeRaw);
                    result = parenthesesType.TryParseValue(contextToUse);
                }

                //If we didn't match any literal for this type, try to match an expression for this type
                if (skriptType != null && result == null &&
                    !Constraint.HasFlagFast(SyntaxValueAcceptanceConstraint.LiteralsOnly))
                {
                    var clone = contextToUse.Clone(false);
                    clone.ShouldJustCheckExpressionsThatMatchType = true;
                    var currentPos = clone.CurrentPosition;

                    result = TryMatchExpressionOnFile(contextToUse, skriptTypesManager, clone, currentPos, skriptType);

                    //Temporarily disable
                    if (false && isObjectType)
                    {
                        //Try matching a Skript expression
                        // Time to check all expressions to make sure the user isn't just trying to mix types for whatever reason...
                        var exprFitType = contextToUse.ShouldJustCheckExpressionsThatMatchType
                            ? skriptTypesManager.GetExpressionsThatCanFitType(skriptType)
                            : skriptTypesManager.KnownExpressionsFromAddons;

                        if (exprFitType != null)
                        {
                            foreach (var expression in exprFitType)
                            {
                                clone.CurrentPosition = currentPos;

                                if (clone.HasVisitedExpression(skriptType, expression))
                                {
                                    continue;
                                }

                                clone.StartRangeMeasure("Expression");
                                clone.Matches.Clear();

                                clone.VisitExpression(skriptType, expression);

                                for (var index = 0; index < expression.PatternNodes.Length; index++)
                                {
                                    var pattern = expression.PatternNodes[index];

                                    var resultValue = pattern.Parse(clone);
                                    if (resultValue.IsSuccess && clone.CurrentPosition >= contextToUse.CurrentPosition)
                                    {
                                        var range = clone.EndRangeMeasure("Expression");
                                        contextToUse.ReadUntilPosition(clone.CurrentPosition);

                                        result = new SkriptExpression(expression, range, contextToUse);
                                    }
                                }

                                clone.UndoRangeMeasure();
                            }
                        }
                    }
                }

                //If we have matched something, let's add it to the matches.
                if (result != null)
                {
                    if (result.Type == null)
                    {
                        result.Type = skriptTypeDescriptor;
                    }
                    result.Context = contextToUse;
                    var match = new ExpressionParseMatch(result, this);

                    contextToUse.Matches.Add(match);
                }

                RestoreFromNarrowedContext(ctx, contextToUse);
                return(result != null?ParseResult.Success(ctx) : ParseResult.Failure(ctx));
            }

            return(ParseResult.Failure(contextToUse));
        }