Created
April 22, 2025 21:57
-
-
Save VladD2/cecd8f4c6919183455b7aeab87b7771d to your computer and use it in GitHub Desktop.
AST грамматики динамически расширяемого парсера
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public abstract record Rule(string Kind) | |
{ | |
public abstract override string ToString(); | |
public virtual Rule InlineReferences(Dictionary<string, Rule> inlineableRules) => this; | |
} | |
public abstract record Terminal(string Kind) : Rule(Kind) | |
{ | |
public override Rule InlineReferences(Dictionary<string, Rule> inlineableRules) => this; | |
public abstract int TryMatch(string input, int position); | |
} | |
public sealed record Literal(string Value, string? Kind = null) : Terminal(Kind ?? Value) | |
{ | |
public override Rule InlineReferences(Dictionary<string, Rule> inlineableRules) => this; | |
public override int TryMatch(string input, int position) => | |
input.AsSpan(position).StartsWith(Value, StringComparison.Ordinal) ? Value.Length : 0; | |
} | |
public record Seq(Rule[] Elements, string Kind) : Rule(Kind) | |
{ | |
public override string ToString() => string.Join(" ", Elements.Select(e => e is Choice ? $"({e})" : e.ToString())); | |
public override Rule InlineReferences(Dictionary<string, Rule> inlineableRules) => | |
new Seq(Elements.Select(e => e.InlineReferences(inlineableRules)).ToArray(), Kind); | |
} | |
public record Choice(Rule[] Alternatives, string? Kind = null) : Rule(Kind ?? nameof(Choice)) | |
{ | |
public override string ToString() => string.Join<Rule>(" | ", Alternatives); | |
public override Rule InlineReferences(Dictionary<string, Rule> inlineableRules) => | |
new Choice(Alternatives.Select(a => a.InlineReferences(inlineableRules)).ToArray(), Kind); | |
} | |
public record OneOrMany(Rule Element, string? Kind = null) : Rule(Kind ?? nameof(OneOrMany)) | |
{ | |
public override string ToString() => $"{Element}+"; | |
public override Rule InlineReferences(Dictionary<string, Rule> inlineableRules) => | |
new OneOrMany(Element.InlineReferences(inlineableRules), Kind); | |
} | |
public record ZeroOrMany(Rule Element, string? Kind = null) : Rule(Kind ?? nameof(ZeroOrMany)) | |
{ | |
public override string ToString() => $"{Element}*"; | |
public override Rule InlineReferences(Dictionary<string, Rule> inlineableRules) => | |
new ZeroOrMany(Element.InlineReferences(inlineableRules), Kind); | |
} | |
public record Optional(Rule Element, string? Kind = null) : Rule(Kind ?? nameof(Optional)) | |
{ | |
public override string ToString() => $"{Element}?"; | |
public override Rule InlineReferences(Dictionary<string, Rule> inlineableRules) => | |
new Optional(Element.InlineReferences(inlineableRules), Kind); | |
} | |
public record Ref(string RuleName, string? Kind = null) : Rule(Kind ?? nameof(RuleName)) | |
{ | |
public override string ToString() => RuleName; | |
public override Rule InlineReferences(Dictionary<string, Rule> inlineableRules) => | |
inlineableRules.TryGetValue(RuleName, out var rule) ? rule.InlineReferences(inlineableRules) : this; | |
} | |
public record ReqRef(string RuleName, int Precedence = 0, bool Right = false, string? Kind = null) : Rule(Kind ?? nameof(RuleName)) | |
{ | |
public override string ToString() => $"{RuleName} {{{Precedence}, {(Right ? "left" : "right")}}}"; | |
public override Rule InlineReferences(Dictionary<string, Rule> inlineableRules) => this; | |
} | |
public record RuleWithPrecedence(string Kind, Seq Seq, int Precedence, bool Right); | |
public record TdoppRule( | |
Ref Name, | |
string Kind, | |
Rule[] Prefix, | |
RuleWithPrecedence[] Postfix | |
) : Rule(Kind) | |
{ | |
public override string ToString() => | |
$"{Name} = Prefix: {string.Join<Rule>(" | ", Prefix)}" + | |
$" Postfix: {string.Join("", Postfix.Select(x => $" {{{x.Precedence}{(x.Right ? "" : " right")}}} {x.Seq}"))}"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment