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