diff --git a/AnyText/AnyText.Core/ParsePositionDelta.cs b/AnyText/AnyText.Core/ParsePositionDelta.cs index 8d8cc7c8..e8116447 100644 --- a/AnyText/AnyText.Core/ParsePositionDelta.cs +++ b/AnyText/AnyText.Core/ParsePositionDelta.cs @@ -1,11 +1,13 @@ -namespace NMF.AnyText +using System; + +namespace NMF.AnyText { /// /// Denotes a delta between parser positions /// /// the line delta /// the column delta - public record struct ParsePositionDelta(int Line, int Col) + public record struct ParsePositionDelta(int Line, int Col) : IComparable { /// /// Calculates the larger of two diffs @@ -35,6 +37,17 @@ public static ParsePositionDelta Smaller(ParsePositionDelta delta1, ParsePositio return delta1; } + /// + public int CompareTo(ParsePositionDelta other) + { + var ret = Line.CompareTo(other.Line); + if (ret != 0) + { + return ret; + } + return Col.CompareTo(other.Col); + } + /// /// Determines whether the first delta is larger than the second /// diff --git a/AnyText/AnyText.Core/Rules/FailedChoiceRuleApplication.cs b/AnyText/AnyText.Core/Rules/FailedChoiceRuleApplication.cs index afa662b7..240d0052 100644 --- a/AnyText/AnyText.Core/Rules/FailedChoiceRuleApplication.cs +++ b/AnyText/AnyText.Core/Rules/FailedChoiceRuleApplication.cs @@ -40,10 +40,8 @@ public override RuleApplication Recover(RuleApplication currentRoot, ParseContex { if (Rule is ChoiceRule choice) { - for (var i = 0; i < choice.Alternatives.Length; i++) + foreach (var fail in _innerFailures.OrderByDescending(f => f.ExaminedTo)) { - var fail = _innerFailures.FirstOrDefault(app => app.Rule == choice.Alternatives[i].Rule); - if (fail == null) continue; var recovery = fail.Recover(currentRoot, context, out position); if (recovery.IsPositive) { diff --git a/AnyText/AnyText.Core/Rules/FailedSequenceRuleApplication.cs b/AnyText/AnyText.Core/Rules/FailedSequenceRuleApplication.cs index 138b9043..8b04dcf9 100644 --- a/AnyText/AnyText.Core/Rules/FailedSequenceRuleApplication.cs +++ b/AnyText/AnyText.Core/Rules/FailedSequenceRuleApplication.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; namespace NMF.AnyText.Rules { @@ -94,6 +95,10 @@ internal override IEnumerable SuggestCompletions(ParsePosition public override void AddParseErrors(ParseContext context) { + if (_successfulApplications.Count > 0) + { + _successfulApplications.Last().AddParseErrors(context); + } if (_furtherFails != null) { foreach (var fail in _furtherFails) diff --git a/AnyText/AnyText.Core/Rules/StarRuleApplication.cs b/AnyText/AnyText.Core/Rules/StarRuleApplication.cs index d8b8a747..352917c0 100644 --- a/AnyText/AnyText.Core/Rules/StarRuleApplication.cs +++ b/AnyText/AnyText.Core/Rules/StarRuleApplication.cs @@ -29,7 +29,10 @@ internal override IEnumerable SuggestCompletions(ParsePosition public override void AddParseErrors(ParseContext context) { - Stopper?.AddParseErrors(context); + if (Stopper != null && Stopper.CurrentPosition.Line < context.Input.Length) + { + Stopper.AddParseErrors(context); + } base.AddParseErrors(context); } diff --git a/AnyText/AnyText.Generator/Transformation/AnytextCodeGenerator.cs b/AnyText/AnyText.Generator/Transformation/AnytextCodeGenerator.cs index 294e8228..8aa5d133 100644 --- a/AnyText/AnyText.Generator/Transformation/AnytextCodeGenerator.cs +++ b/AnyText/AnyText.Generator/Transformation/AnytextCodeGenerator.cs @@ -180,6 +180,8 @@ private static CodeExpression CreateParserExpression(IParserExpression parserExp return choiceExpression; case INegativeLookaheadExpression negative: return new CodeObjectCreateExpression(typeof(NegativeLookaheadRule).ToTypeReference(), CreateParserExpression(negative.Inner, negative.FormattingInstructions, ruleTransformation, assignTransformation, context)); + case IPositiveLookaheadExpression positive: + return new CodeObjectCreateExpression(typeof(PositiveLookaheadRule).ToTypeReference(), CreateParserExpression(positive.Inner, positive.FormattingInstructions, ruleTransformation, assignTransformation, context)); } throw new NotSupportedException(); } @@ -1077,6 +1079,7 @@ private static CodeMemberMethod CreateSetValue(CodeTypeReference semanticType, C private static CodeMemberMethod CreateGetValue(IAssignExpression input, CodeTypeReference semanticType, CodeTypeReference propertyType, CodeArgumentReferenceExpression semanticElementRef, CodePropertyReferenceExpression property) { + var feature = CodeGenerator._trace.LookupFeature(input); var getValue = new CodeMemberMethod { Name = "GetValue", @@ -1094,6 +1097,10 @@ private static CodeMemberMethod CreateGetValue(IAssignExpression input, CodeType ["context"] = "the parsing context" }); CodeExpression getValueReturn = property; + if (feature != null && feature.LowerBound == 0 && input.Assigned is RuleExpression ruleExpression && ruleExpression.Rule is EnumRule) + { + getValueReturn = new CodeMethodInvokeExpression(getValueReturn, nameof(Nullable.GetValueOrDefault)); + } getValue.Statements.Add(new CodeMethodReturnStatement(getValueReturn)); return getValue; } diff --git a/AnyText/AnyText.history b/AnyText/AnyText.history index 16469925..af6d8b29 100644 --- a/AnyText/AnyText.history +++ b/AnyText/AnyText.history @@ -47,4 +47,5 @@ patch: if a rule application is found, do not increase the deletion index patch: improve code lenses for synchronizations major: changed extension API for indentation-aware, create API to propagate context changes patch: do not check whether rule application is memoized if it is only interesting to see whether the line is obsolete -patch: adapt metamodel code to changed interface \ No newline at end of file +patch: adapt metamodel code to changed interface +patch: improve error reporting \ No newline at end of file