### Using Terms.Text() Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches a given string literally. This example demonstrates parsing the exact string 'hello' from the input. ```csharp var input = "hello world"; var parser = Terms.Text("hello"); ``` -------------------------------- ### Using Terms.Char() Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches a specific character. This example checks if the input starts with the character 'h'. ```csharp var input = "hello world"; var parser = Terms.Char('h'); ``` -------------------------------- ### Example SQL Parsing Source: https://github.com/sebastienros/parlot/blob/main/src/Samples/Sql/README.md Demonstrates how to parse a simple SQL SELECT statement and access its Abstract Syntax Tree (AST). This snippet is intended for use once the parser implementation is complete and free of compilation errors. ```csharp var result = SqlParser.Parse("SELECT * FROM users WHERE id > 10"); if (result != null) { // Work with the AST var statement = result.Statements[0].UnionStatements[0].Statement.SelectStatement; // ... } ``` -------------------------------- ### Using Terms.WhiteSpace() with Literals.Text() Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Combines matching literal text with whitespace parsing. This example demonstrates parsing 'hello' followed by whitespace, then 'world'. It requires whitespace between the words. ```csharp var parser = Literals.Text("hello").And(Terms.WhiteSpace()).And(Literals.Text("world")); parser.Parse("hello world"); // success parser.Parse("helloworld"); // failure ``` -------------------------------- ### Using Integer() Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches an integral numeric value, including an optional leading sign. This example parses a negative integer. ```csharp var input = "-1234"; ``` -------------------------------- ### Build a Mathematical Expression Parser with Fluent API Source: https://github.com/sebastienros/parlot/blob/main/README.md This example demonstrates building a complete parser for mathematical expressions, including handling numbers, negation, multiplication, division, addition, subtraction, and grouping with parentheses. It utilizes deferred parsers for recursive grammar definitions. ```csharp using Parlot.Fluent; using static Parlot.Fluent.Parsers; public static readonly Parser Expression; static FluentParser() { /* * Grammar: * The top declaration has a lower priority than the lower one. * * additive => multiplicative ( ( "-" | "+" ) multiplicative )* ; * multiplicative => unary ( ( "/" | "*" ) unary )* ; * unary => ( "-" ) unary * | primary ; * primary => NUMBER * | "(" expression ")" ; */ // The Deferred helper creates a parser that can be referenced by others before it is defined var expression = Deferred(); var number = Terms.Decimal() .Then(static d => new Number(d)) ; var divided = Terms.Char('/'); var times = Terms.Char('*'); var minus = Terms.Char('-'); var plus = Terms.Char('+'); var openParen = Terms.Char('('); var closeParen = Terms.Char(')'); // "(" expression ")" var groupExpression = Between(openParen, expression, closeParen); // primary => NUMBER | "(" expression ")"; var primary = number.Or(groupExpression); // ( "-" ) unary | primary; var unary = primary.Unary( (minus, x => new NegateExpression(x)) ); // multiplicative => unary ( ( "/" | "*" ) unary )* ; var multiplicative = unary.LeftAssociative( (divided, static (a, b) => new Division(a, b)), (times, static (a, b) => new Multiplication(a, b)) ); // additive => multiplicative(("-" | "+") multiplicative) * ; var additive = multiplicative.LeftAssociative( (plus, static (a, b) => new Addition(a, b)), (minus, static (a, b) => new Subtraction(a, b)) ); expression.Parser = additive; Expression = expression; } ``` -------------------------------- ### Parse Context and Input Variable Convention Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md This note explains the common convention for input text and parser variables in Parlot examples. It clarifies how parsing operations are typically performed. ```csharp // Note: when samples use a local `input` variable representing the input text to parse, and a `parser` variable, the result is usually the outcome of calling `var result = parser.Parse(input)` or `var success = parser.TryParse(input, out var result)`. ``` -------------------------------- ### Using Terms.NonWhiteSpace() Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches any non-blank spaces, optionally including new lines. This example captures the initial non-whitespace characters from the input. ```csharp var input = "hello world"; var parser = Terms.NonWhiteSpace(); ``` -------------------------------- ### Using Terms.Keyword() - Successful Match Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches a keyword string, ensuring it's followed by a non-letter character to prevent partial identifier matches. This example successfully parses the keyword 'if'. ```csharp var input = "if(x > 5)"; var parser = Terms.Keyword("if"); var result = parser.Parse(input); ``` -------------------------------- ### Using Literals.WhiteSpace() Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches blank spaces, optionally including new lines. Returns a TextSpan with the matched spaces. This example shows how to capture leading whitespace. ```csharp var input = " \thello world "; var parser = Literals.WhiteSpace(); ``` -------------------------------- ### Identifier Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches an identifier, optionally with extra allowed characters. Default start characters are [$a-zA-Z]. Other characters can include digits. ```csharp Parser Identifier(Func extraStart = null, Func extraPart = null) ``` ```csharp var input = "slice_text();"; var parser = Terms.Identifier(); ``` -------------------------------- ### Using Select with Custom Context Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Dynamically selects a parser based on a condition in a custom parse context. This example uses a 'PreferYes' flag in 'CustomContext' to choose between parsing 'yes' or 'no'. ```csharp var parser = Select(context => { return context.PreferYes ? Literals.Text("yes") : Literals.Text("no"); }); var result = parser.Parse(new CustomContext(new Scanner("yes")) { PreferYes = true }); ``` -------------------------------- ### Identifier Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches an identifier, optionally with extra allowed characters. Default start characters are `[$_a-zA-Z]`. Other characters also include digits. ```APIDOC ## Identifier Parser ### Description Matches an identifier, optionally with extra allowed characters. Default start chars are `[$_a-zA-Z]`. Other chars also include digits. ### Method Signature ```csharp Parser Identifier(Func extraStart = null, Func extraPart = null) ``` ### Usage Example ```csharp var input = "slice_text();"; var parser = Terms.Identifier(); ``` ### Result Example ``` slice_text ``` ``` -------------------------------- ### Terms.Keyword() Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches a keyword string, ensuring the following character is not a letter. This prevents partial matches of identifiers that start with the keyword text. ```APIDOC ## Terms.Keyword() ### Description Matches a keyword string, ensuring the following character is not a letter. This prevents partial matches of identifiers that start with the keyword text. ### Method Signature ```csharp Parser Keyword(string text, bool caseInsensitive = false) ``` ### Usage Example ```csharp var input = "if(x > 5)"; var parser = Terms.Keyword("if"); var result = parser.Parse(input); // Result: "if" ``` Parsing `"ifoo"` would fail: ```csharp var input = "ifoo"; var parser = Terms.Keyword("if"); var result = parser.Parse(input); // Returns null - failure ``` Any non-letter is considered valid after a keyword (non-letters): `(`, `)`, `;`, `,`, whitespace, digits, `_`, `$`, etc. ``` -------------------------------- ### Accessing Parse Positions with Then Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md The `Then` overload `Func` provides access to the start and end offsets of the parsed result. These offsets are integer positions in the input buffer. ```csharp var parser = Literals.Identifier().Then((context, start, end, value) => { var length = end - start; return $"Parsed '{value}' at offset {start}, length {length}"; }); parser.Parse("hello"); ``` -------------------------------- ### Creating an Integer or Hello Parser with Optimization Source: https://github.com/sebastienros/parlot/blob/main/docs/writing.md Shows how to combine parsers using `Or` to create a parser that can match either an integer or the text 'Hello'. This enables optimization via lookup tables. ```csharp var integer = Terms.Integer(); var hello = Terms.Text("Hello", caseInsensitive: true); var intOrHello = integer.Or(Hello); ``` -------------------------------- ### Select Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Selects the parser to execute at runtime. Use it when the next parser depends on mutable state or a custom ParseContext implementation. ```APIDOC ## Select ### Description Selects the parser to execute at runtime. Use it when the next parser depends on mutable state or a custom `ParseContext` implementation. ### Method Signatures ```csharp Parser Select(Func> selector) Parser Select(Func> selector) where C : ParseContext ``` ### Usage Example ```csharp var parser = Select(context => { return context.PreferYes ? Literals.Text("yes") : Literals.Text("no"); }); var result = parser.Parse(new CustomContext(new Scanner("yes")) { PreferYes = true }); ``` `CustomContext` is an application-defined type that derives from `ParseContext` and exposes additional configuration. If the selector returns `null`, the `Select` parser fails without consuming any input. Capture additional state through closures or custom `ParseContext` properties when needed. ``` -------------------------------- ### Avoiding Dynamic Parser Creation in Select Factory Source: https://github.com/sebastienros/parlot/blob/main/docs/writing.md Demonstrates a correct usage of the `Select` parser factory, where pre-defined parsers are returned. This avoids expensive parser creation on each invocation. ```csharp var a = Terms.Text("a"); var b = Terms.Text("b"); var p = Select(c => c.OptionA ? a : b); ``` -------------------------------- ### Import Parlot Fluent API Parsers Source: https://github.com/sebastienros/parlot/blob/main/README.md Import the static Parsers class to access combinators like Terms, Literals, and others for building grammars. ```csharp using Parlot.Fluent; using static Parlot.Fluent.Parsers; ``` -------------------------------- ### Parser Composition With Covariance Source: https://github.com/sebastienros/parlot/blob/main/docs/covariance-example.md With covariance, IParser can be directly used where IParser is expected, simplifying composition with methods like OneOf and avoiding wrapper objects. ```csharp class Animal { public string Name { get; set; } } class Dog : Animal { public string Breed { get; set; } } class Cat : Animal { public string Color { get; set; } } var dogParser = Terms.Text("dog").Then(_ => new Dog { Name = "Buddy", Breed = "Golden Retriever" }); var catParser = Terms.Text("cat").Then(_ => new Cat { Name = "Whiskers", Color = "Orange" }); // Can use OneOf directly with IParser - no wrapper objects needed! var animalParser = OneOf(dogParser, catParser); ``` -------------------------------- ### Operator Syntax for Parser Composition Source: https://github.com/sebastienros/parlot/blob/main/README.md Demonstrates the use of '+' for sequential parser combination and '|' for choice between parsers in Parlot. These operators offer a more concise syntax compared to the And() and Or() methods. ```csharp // Using operators var parser = Literals.Char('a') + Literals.Char('b') + Literals.Char('c'); var choice = Literals.Char('x') | Literals.Char('y') | Literals.Char('z'); // Equivalent to var parser = Literals.Char('a').And(Literals.Char('b')).And(Literals.Char('c')); var choice = Literals.Char('x').Or(Literals.Char('y')).Or(Literals.Char('z')); ``` -------------------------------- ### Lookup Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Builds a parser that lists all possible matches to improve performance. Useful for ISeekable parsers to provide OneOf with a lookup table. ```csharp Parser Lookup(params ReadOnlySpan expectedChars) ``` ```csharp Parser Lookup(params ISeekable[] parsers) ``` -------------------------------- ### Literals.WhiteSpace() Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches blank spaces, optionally including new lines. Returns a TextSpan with the matched spaces. ```APIDOC ## Literals.WhiteSpace() ### Description Matches blank spaces, optionally including new lines. Returns a `TextSpan` with the matched spaces. ### Method Signature ```csharp Parser WhiteSpace(bool includeNewLines = false) ``` ### Usage Example ```csharp var input = " \thello world "; var parser = Literals.WhiteSpace(); // Result: " \t" ``` ``` -------------------------------- ### WithComments Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md A helper based on `WithWhiteSpaceParser` that simplifies defining custom comment syntax within parsers. ```APIDOC ## WithComments ### Description Based on `WithWhiteSpaceParser`, this helper makes it easier to define custom comments syntax. ### Usage Example ```csharp var hello = Terms.Text("hello"); var world = Terms.Text("world"); var parser = hello.And(world) .WithComments(builder => { builder.WithSingleLine("--"); builder.WithSingleLine("#"); builder.WithMultiLine("/*", "*/"); }); parser.Parse("hello -- comment\n world"); parser.Parse("hello -- comment\r\n world"); parser.Parse("hello # comment\n world"); parser.Parse("hello /* multiline\n comment\n */ world"); ``` ``` -------------------------------- ### Expression Benchmark Results Source: https://github.com/sebastienros/parlot/blob/main/README.md Benchmark results for parsing small and big mathematical expressions using Parlot (raw, compiled, fluent) and Pidgin. Shows mean execution time, error, standard deviation, and memory allocations. ```text BenchmarkDotNet v0.15.0, Windows 11 (10.0.26100.4770/24H2/2024Update/HudsonValley) 12th Gen Intel Core i7-1260P 2.10GHz, 1 CPU, 16 logical and 12 physical cores .NET SDK 10.0.100-preview.6.25358.103 [Host] : .NET 9.0.7 (9.0.725.31616), X64 RyuJIT AVX2 ShortRun : .NET 9.0.7 (9.0.725.31616), X64 RyuJIT AVX2 Job=ShortRun IterationCount=3 LaunchCount=1 WarmupCount=3 | Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio | |-------------------- |------------:|------------:|----------:|------:|--------:|-------:|----------:|------------:| | ParlotRawSmall | 234.0 ns | 133.27 ns | 7.31 ns | 0.49 | 0.01 | 0.0322 | 304 B | 0.43 | | ParlotCompiledSmall | 481.6 ns | 89.48 ns | 4.90 ns | 1.00 | 0.01 | 0.0753 | 712 B | 1.00 | | ParlotFluentSmall | 486.7 ns | 219.33 ns | 12.02 ns | 1.01 | 0.02 | 0.0753 | 712 B | 1.00 | | PidginSmall | 5,301.9 ns | 1,864.01 ns | 102.17 ns | 11.01 | 0.21 | 0.0839 | 832 B | 1.17 | | | | | | | | | | | | ParlotRawBig | 1,074.4 ns | 115.56 ns | 6.33 ns | 0.45 | 0.01 | 0.1259 | 1200 B | 0.39 | | ParlotCompiledBig | 2,403.9 ns | 777.57 ns | 42.62 ns | 1.00 | 0.02 | 0.3281 | 3104 B | 1.00 | | ParlotFluentBig | 2,443.7 ns | 204.37 ns | 11.20 ns | 1.02 | 0.02 | 0.3281 | 3104 B | 1.00 | | PidginBig | 26,210.1 ns | 3,920.26 ns | 214.88 ns | 10.91 | 0.19 | 0.4272 | 4152 B | 1.34 | ``` -------------------------------- ### Using Terms.Keyword() - Failed Match Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Demonstrates a failed match with Terms.Keyword() when the keyword is part of a larger identifier. Parsing 'ifoo' with the 'if' keyword parser results in failure. ```csharp var input = "ifoo"; var parser = Terms.Keyword("if"); var result = parser.Parse(input); // Returns null - failure ``` -------------------------------- ### Terms.Char() Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches a given character. ```APIDOC ## Terms.Char() ### Description Matches a given character. ### Method Signature ```csharp Parser Char(char c) ``` ### Usage Example ```csharp var input = "hello world"; var parser = Terms.Char('h'); // Result: 'h' ``` ``` -------------------------------- ### Or Parser Combination Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches any of two parsers. An overload exists to return a common base class from two different parser types. ```csharp Parser Or(this Parser parser, Parser or) ``` ```csharp Parser Or(this Parser parser, Parser or) ``` ```csharp var parser = Terms.Text("one").Or(Terms.Text("1")); parser.Parse("1"); parser.Parse("one"); parser.Parse("hello") ``` -------------------------------- ### Else - Integer and Text Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Uses Else to provide a default value (0) if the Integer parser fails, then combines it with a Text parser. This parser always succeeds. ```csharp var parser = Terms.Integer().Else(0).And(Terms.Text("years")); capture.Parse("years"); capture.Parse("123 years"); ``` -------------------------------- ### Handling Multiple Parsers in OneOf Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/writing.md Illustrates the `OneOf` parser's logic, where it attempts each provided parser sequentially until one succeeds. No cursor reset is needed if a parser succeeds. ```csharp public override bool Parse(ParseContext context, ref ParseResult result) { context.EnterParser(this); foreach (var parser in _parsers) { if (parser.Parse(context, ref result)) { context.ExitParser(this); return true; } } context.ExitParser(this); return false; } ``` -------------------------------- ### Pattern Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches consecutive characters based on a predicate, with optional minimum and maximum size constraints. ```csharp Parser Pattern(Func predicate, int minSize = 1, int maxSize = 0) ``` ```csharp var input = "ababcad"; var parser = Terms.Pattern(c => c == 'a' || c == 'b'); ``` -------------------------------- ### Terms.NonWhiteSpace() Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches any non-blank spaces, optionally including new lines. Returns a TextSpan with the matched characters. ```APIDOC ## Terms.NonWhiteSpace() ### Description Matches any non-blank spaces, optionally including new lines. Returns a `TextSpan` with the matched characters. ### Method Signature ```csharp Parser NonWhiteSpace(bool includeNewLines = false) ``` ### Usage Example ```csharp var input = "hello world"; var parser = Terms.NonWhiteSpace(); // Result: "hello" ``` ``` -------------------------------- ### Deferred Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Creates a parser that can be referenced before it is defined, useful for handling cyclic dependencies between parsers. ```APIDOC ## Deferred ### Description Creates a parser that can be referenced before it is actually defined. This is used when there is a cyclic dependency between parsers. ### Method Signature ```csharp Deferred Deferred() ``` ### Usage Example ```csharp var parser = Deferred(); var group = Between(Terms.Char('('), parser, Terms.Char(')')); parser.Parser = Terms.Integer().Or(group); parser.Parse("((1))"); parser.Parse("1"); ``` ### Result Example ``` 1 1 ``` ``` -------------------------------- ### Custom Comment Syntax Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Easily define custom comments syntax using single-line and multi-line comment delimiters. This is based on WithWhiteSpaceParser. ```csharp var hello = Terms.Text("hello"); var world = Terms.Text("world"); var parser = hello.And(world) .WithComments(builder => { builder.WithSingleLine("--"); builder.WithSingleLine("#"); builder.WithMultiLine("/*", "*/"); }); parser.Parse("hello -- comment\n world"); parser.Parse("hello -- comment\r\n world"); parser.Parse("hello # comment\n world"); parser.Parse("hello /* multiline\n comment\n */ world"); ``` -------------------------------- ### WhenFollowedBy - Positive Lookahead Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Parses an integer only if it is immediately followed by a colon, without consuming the colon. ```csharp // Parse a number only if it's followed by a colon var parser = Literals.Integer().WhenFollowedBy(Literals.Char(':')); parser.Parse("42:"); // success, returns 42 parser.Parse("42"); // failure, lookahead doesn't match ``` -------------------------------- ### Switch - Dynamic Parser Selection Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Selects a subsequent parser based on the result of a preceding integer parser, determining whether to expect 'is odd' or 'is even'. ```csharp var parser = Terms.Integer().Switch((context, i) => { // Valid entries: "1 is odd", "2 is even" // Invalid: "7 is even" return i % 2 == 0 ? Terms.Text("is odd") : Terms.Text("is even"); }); ``` -------------------------------- ### And Parser Combination Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches two consecutive parsers, returning a strongly-typed tuple of their results. Multiple And() calls can chain to match sequences. ```csharp Parser> And(this Parser parser, Parser and) ``` ```csharp var parser = Terms.Text("hello").And(Terms.Text("world")); parser.Parse("hello world").Item1; parser.Parse("hello world").Item2; parser.Parse("hello"); ``` ```csharp var input = "age = 12"; var parser = Terms.Identifier().And(Terms.Char('=')).And(Terms.Integer()); var result = parser.Parse(input); Assert.Equal("age", result.Item1); Assert.Equal('=', result.Item2); Assert.Equal(12, result.Item3); ``` -------------------------------- ### AnyOf Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches any characters from a specified list. Overloads are available for .NET 8+ using vectorized parsing for better performance. ```csharp Parser AnyOf(string values, int minSize = 1, int maxSize = 0) ``` ```csharp Parser AnyOf(ReadOnlySpan values, int minSize = 1, int maxSize = 0) ``` ```csharp Parser AnyOf(SearchValue searchValues, int minSize = 1, int maxSize = 0) ``` ```csharp var input = "ababcad"; var parser = Terms.AnyOf("ab"); ``` -------------------------------- ### Terms.WhiteSpace() Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches the WhiteSpaceParser configured in the current context. When used from Terms it parses whitespace (or comments) as defined in the ParseContext or from WithWhiteSpaceParser(parser). ```APIDOC ## Terms.WhiteSpace() ### Description Matches the `WhiteSpaceParser` configured in the current context. When used from `Terms` it parses whitespace (or comments) as defined in the `ParseContext` or from `WithWhiteSpaceParser(parser)`. ### Method Signature ```csharp Parser WhiteSpace() ``` ### Usage Example ```csharp var parser = Literals.Text("hello").And(Terms.WhiteSpace()).And(Literals.Text("world")); parser.Parse("hello world"); // success parser.Parse("helloworld"); // failure ``` ``` -------------------------------- ### Or Combinator Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Combines two parsers, matching if either the first or the second parser succeeds. Supports parsers returning a common base class. ```APIDOC ## Or Combinator ### Description Matches any of two parsers. ### Method Signature ```csharp Parser Or(this Parser parser, Parser or) ``` ### Overload for Common Base Class ```csharp Parser Or(this Parser parser, Parser or) ``` ### Usage Example ```csharp var parser = Terms.Text("one").Or(Terms.Text("1")); parser.Parse("1"); parser.Parse("one"); parser.Parse("hello") ``` ### Result Example ``` "1" "one" null ``` ### Chaining Multiple `Or()` calls can be used in a row, e.g., `a.Or(b).Or(c).Or(d)` ``` -------------------------------- ### Resetting Cursor Position in Sequence Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/writing.md Demonstrates how to reset the cursor position when a sub-parser fails within a sequence. This is crucial for maintaining correct parsing state. ```csharp public override bool Parse(ParseContext context, ref ParseResult> result) { context.EnterParser(this); var parseResult1 = new ParseResult(); var start = context.Scanner.Cursor.Position; if (_parser1.Parse(context, ref parseResult1)) { var parseResult2 = new ParseResult(); if (_parser2.Parse(context, ref parseResult2)) { result.Set(parseResult1.Start, parseResult2.End, new ValueTuple(parseResult1.Value, parseResult2.Value)); context.ExitParser(this); return true; } context.Scanner.Cursor.ResetPosition(start); } context.ExitParser(this); return false; } ``` -------------------------------- ### AnyOf Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches any character from a provided list of characters. Supports vectorized parsing for .NET 8+. ```APIDOC ## AnyOf Parser ### Description Matches any chars from a list of chars. ### Method Signature ```csharp Parser AnyOf(string values, int minSize = 1, int maxSize = 0) ``` ### Overloads for .NET 8+ ```csharp Parser AnyOf(ReadOnlySpan values, int minSize = 1, int maxSize = 0) Parser AnyOf(SearchValue searchValues, int minSize = 1, int maxSize = 0) ``` ### Usage Example ```csharp var input = "ababcad"; var parser = Terms.AnyOf("ab"); ``` ### Result Example ``` abab ``` ``` -------------------------------- ### Terms.Text() Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches a given string, optionally in a case insensitive way. ```APIDOC ## Terms.Text() ### Description Matches a given string, optionally in a case insensitive way. ### Method Signature ```csharp Parser Text(string text, bool caseInsensitive = false) ``` ### Usage Example ```csharp var input = "hello world"; var parser = Terms.Text("hello"); // Result: "hello" ``` ``` -------------------------------- ### OneOf Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Similar to the Or parser, but accepts an unlimited list of parsers. It tries each parser in sequence until one succeeds. ```csharp Parser OneOf(params Parser[] parsers) ``` -------------------------------- ### Terms.Integer() Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches an integral numeric value and an optional leading sign. ```APIDOC ## Terms.Integer() ### Description Matches an integral numeric value and an optional leading sign. ### Method Signature ```csharp Parser Integer() ``` ### Usage Example ```csharp var input = "-1234"; // Result: -1234 ``` ``` -------------------------------- ### Always Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Always returns successfully, optionally with a specific return type or value. Useful for creating parsers that should always succeed. ```csharp Parser Always() ``` ```csharp Parser Always() ``` ```csharp Parser Always(T value) ``` -------------------------------- ### Then Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Converts the result of a parser, typically used to create custom data structures or convert types upon successful parsing. ```APIDOC ## Then ### Description Convert the result of a parser. This is usually used to create custom data structures when a parser succeeds, or to convert it to another type. ### Method Overloads ```csharp Parser Then(Func conversion) Parser Then(Func conversion) Parser Then(Func conversion) Parser Then(U value) Parser Then() // Converts the result to `U` ``` ### Usage Example 1 (Custom Data Structure) ```csharp var parser = Terms.Integer() .AndSkip(Terms.Char(',')) .And(Terms.Integer()) .Then(x => new Point(x.Item1, y.Item2)); parser.Parse("1,2"); ``` ### Result Example 1 ``` Point { x: 1, y: 2} ``` ### Usage Example 2 (Simple Conversion) ```csharp var parser = OneOf( Terms.Text("not").Then(UnaryOperator.Not), Terms.Text("-").Then(UnaryOperator.Negate) ); ``` ### Accessing Start and End Positions #### Usage Example The `Func` overload provides access to the start and end offsets of the parsed result: ```csharp var parser = Literals.Identifier().Then((context, start, end, value) => { var length = end - start; return $"Parsed '{value}' at offset {start}, length {length}"; }); parser.Parse("hello"); ``` #### Result Example ``` "Parsed 'hello' at offset 0, length 5" ``` > **Note:** The start and end parameters are integer offsets (positions in the input buffer), not `TextPosition` objects. For `Literals` parsers, these offsets correspond exactly to where the parser matched. For `Terms` parsers (which skip whitespace), the behavior differs slightly between compiled and non-compiled modes due to how whitespace skipping is handled in the compilation process. ``` -------------------------------- ### Pattern Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches a consecutive sequence of characters based on a specific predicate, with optional minimum and maximum size constraints. ```APIDOC ## Pattern Parser ### Description Matches a consecutive characters with a specific predicate, optionally defining a minimum and maximum size. ### Method Signature ```csharp Parser Pattern(Func predicate, int minSize = 1, int maxSize = 0) ``` ### Usage Example ```csharp var input = "ababcad"; var parser = Terms.Pattern(c => c == 'a' || c == 'b'); ``` ### Result Example ``` abab ``` ``` -------------------------------- ### Decimal Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches a numeric value with optional digits and a leading sign. The exponent is supported. This parser is equivalent to Number() for backward compatibility. ```csharp Parser Decimal() ``` ```csharp var input = "-1234.56"; var parser = Terms.Decimal(NumberOptions.AllowSign); ``` -------------------------------- ### And Combinator Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Combines two parsers, matching if both parsers succeed consecutively. The result is a strongly typed tuple containing the results of both parsers. ```APIDOC ## And Combinator ### Description Matches two consecutive parsers. The result is a strongly typed tuple containing the two individual results. ### Method Signature ```csharp Parser> And(this Parser parser, Parser and) ``` ### Usage Example ```csharp var parser = Terms.Text("hello").And(Terms.Text("world")); parser.Parse("hello world").Item1; parser.Parse("hello world").Item2; parser.Parse("hello"); ``` ### Result Example ``` "hello" "world" null ``` ### Chaining for Multiple Matches Multiple `And()` calls can be used in a row, e.g., to match a variable assignment like `age = 12` ```csharp var input = "age = 12"; var parser = Terms.Identifier().And(Terms.Char('=')).And(Terms.Integer()); var result = parser.Parse(input); Assert.Equal("age", result.Item1); Assert.Equal('=', result.Item2); Assert.Equal(12, result.Item3); ``` ``` -------------------------------- ### AndSkip Parser Combination Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Behaves like And but skips the result of the second parser. This is useful for expecting successive terms while ignoring some to keep the result lean. ```csharp Parser AndSkip(this Parser parser, Parser and) ``` ```csharp var parser = Terms.Text("hello").AndSkip(Terms.Text("world")); parser.Parse("hello world"); parser.Parse("hello"); ``` ```csharp var input = "age = 12"; var parser = Terms.Identifier().AndSkip(Terms.Char('=')).And(Terms.Integer()); var result = parser.Parse(input); Assert.Equal("age", result.Item1); Assert.Equal(12, result.Item2); ``` -------------------------------- ### Decimal Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches a numeric value with optional digits and leading sign. The exponent is supported. This parser is equivalent to `Number()` and exists for backward compatibility. ```APIDOC ## Decimal Parser ### Description Matches a numeric value with optional digits and leading sign. The exponent is supported. ### Method Signature ```csharp Parser Decimal() ``` ### Notes This is equivalent to `Number()` and only exists for backward compatibility purposes. ### Usage Example ```csharp var input = "-1234.56"; var parser = Terms.Decimal(NumberOptions.AllowSign); ``` ### Result Example ``` -1234.56 ``` ``` -------------------------------- ### Fail Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md A parser that always returns a failed attempt. Use this when a parser is required but should explicitly represent a failure. ```csharp Parser Fail() ``` ```csharp Parser Fail() ``` -------------------------------- ### Parser Composition Without Covariance Source: https://github.com/sebastienros/parlot/blob/main/docs/covariance-example.md Before covariance, explicit type conversions using .Then(x => x) were required to combine parsers of derived types into a common base type, leading to wrapper objects. ```csharp class Animal { public string Name { get; set; } } class Dog : Animal { public string Breed { get; set; } } class Cat : Animal { public string Color { get; set; } } var dogParser = Terms.Text("dog").Then(_ => new Dog { Name = "Buddy", Breed = "Golden Retriever" }); var catParser = Terms.Text("cat").Then(_ => new Cat { Name = "Whiskers", Color = "Orange" }); // Had to use .Then(x => x) to convert each parser - creates wrapper objects var animalParser = dogParser.Then(x => x).Or(catParser.Then(x => x)); ``` -------------------------------- ### Recursive Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Creates a parser that can reference itself, typically used for recursive grammar structures. ```APIDOC ## Recursive ### Description Creates a parser that can reference itself. ### Method Signature ```csharp Deferred Recursive(Func, Parser> parser) ``` ### Usage Example ```csharp var number = Terms.Decimal(); var minus = Terms.Char('-'); var parser = Recursive((u) => minus.And(u) .Then(static x => 0 - x.Item2) .Or(number) ); parser.Parse("--1"); ``` ### Result Example ``` 1 ``` ``` -------------------------------- ### AndSkip Combinator Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Combines two parsers, matching if both succeed consecutively, but skips the result of the second parser. Useful for expecting successive terms while ignoring some. ```APIDOC ## AndSkip Combinator ### Description Behaves like [And](#And) but skips the later one's result. ### Method Signature ```csharp Parser AndSkip(this Parser parser, Parser and) ``` ### Usage Example ```csharp var parser = Terms.Text("hello").AndSkip(Terms.Text("world")); parser.Parse("hello world"); parser.Parse("hello"); ``` ### Result Example ``` "hello" null ``` ### Use Case Example This is useful to expect successive terms but to ignore some of them and make the result as lean as possible. ```csharp var input = "age = 12"; var parser = Terms.Identifier().AndSkip(Terms.Char('=')).And(Terms.Integer()); var result = parser.Parse(input); Assert.Equal("age", result.Item1); Assert.Equal(12, result.Item2); ``` ``` -------------------------------- ### Deferred Parser Definition Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Creates a parser that can be referenced before it is defined, useful for handling cyclic dependencies between parsers. The parser definition can be assigned later. ```csharp Deferred Deferred() ``` ```csharp var parser = Deferred(); var group = Between(Terms.Char('('), parser, Terms.Char(')')); parser.Parser = Terms.Integer().Or(group); parser.Parse("((1))"); parser.Parse("1"); ``` -------------------------------- ### WhenNotFollowedBy - Negative Lookahead Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Parses an integer only if it is NOT immediately followed by a colon, without consuming the colon. ```csharp // Parse a number only if it's NOT followed by a colon var parser = Literals.Integer().WhenNotFollowedBy(Literals.Char(':')); parser.Parse("42"); // success, returns 42 parser.Parse("42:"); // failure, lookahead matches ``` -------------------------------- ### AnyCharBefore Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Returns any characters until the specified parser is matched. Use with combined parsers like `AnyCharBefore(a.Or(b))` for better performance than chaining `AnyCharBefore` calls. ```csharp Parser AnyCharBefore(Parser parser, bool canBeEmpty = false, bool failOnEof = false, bool consumeDelimiter = false) ``` -------------------------------- ### SkipAnd Parser Combinator Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Combines two parsers, executing the first but skipping its result, and then executing the second. Useful for expecting successive terms while ignoring some. ```csharp Parser SkipAnd(this Parser parser, Parser and) ``` ```csharp var parser = Terms.Text("hello").SkipAnd(Terms.Text("world")); parser.Parse("hello world"); parser.Parse("hello"); ``` ```csharp var input = "age = 12"; var parser = Terms.Identifier().And(Terms.Char('=')).SkipAnd(Terms.Integer()); var result = parser.Parse(input); Assert.Equal("age", result.Item1); Assert.Equal(12, result.Item2); ``` -------------------------------- ### ZeroOrOne Parser Combinator Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Makes a parser optional, allowing it to match zero or one time. The result is the matched value or null if not matched. ```csharp Parser ZeroOrOne(Parser parser) ``` ```csharp var parser = ZeroOrOne(Terms.Text("hello")); // or Terms.Text("hello").ZeroOrOne() parser.Parse("hello"); parser.Parse(""); // returns null but with a successful state ``` -------------------------------- ### Number Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches a numeric value of any .NET type. The `NumberOptions` enumeration enables customization of how the number is parsed. The return type can be any numeric .NET type compatible with the selected options. ```APIDOC ## Number Parser ### Description Matches a numeric value of any .NET type. The `NumberOptions` enumeration enables to customize how the number is parsed. The return type can be any numeric .NET type that is compatible with the selected options. ### Method Signature ```csharp Parser Number() where T : INumber ``` ### Usage Example ```csharp var input = "-1,234.56e1"; var parser = Terms.Number(NumberOptions.Float | NumberOptions.AllowGroupSeparators); ``` ### Result Example ``` -12345.6 ``` ``` -------------------------------- ### Number Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches a numeric value of any .NET type. The NumberOptions enumeration customizes parsing, and the return type can be any compatible numeric .NET type. ```csharp Parser Number() where T : INumber ``` ```csharp var input = "-1,234.56e1"; var parser = Terms.Number(NumberOptions.Float | NumberOptions.AllowGroupSeparators); ``` -------------------------------- ### SkipWhiteSpace Parser Combinator Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches a parser after skipping any leading whitespace characters. This respects the configured WhiteSpaceParser. ```csharp Parser SkipWhiteSpace(Parser parser) ``` ```csharp var parser = SkipWhiteSpace(Literals.Text("abc")); parser.Parse("abc"); parser.Parse(" abc"); ``` -------------------------------- ### ZeroOrMany Parser Combinator Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Executes a parser as long as it's successful, collecting all individual results into a list. Can be used as a postfix operator. ```csharp Parser> ZeroOrMany(Parser parser) ``` ```csharp var parser = ZeroOrMany(Terms.Text("hello")); // or Terms.Text("hello").ZeroOrMany() parser.Parse("hello hello"); parser.Parse(""); ``` -------------------------------- ### Between Parser Combinator Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches a parser that is enclosed by two other parsers (before and after). Useful for parsing delimited content. ```csharp Parser Between(Parser before, Parser parser, Parser after) ``` ```csharp var parser = Between(Terms.Char('['), Terms.Integer(), Terms.Char(']')); parser.Parse("[ 1 ]"); parser.Parse("[ 1"); ``` -------------------------------- ### NoneOf Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches any characters except those specified in the given list. Overloads are available for .NET 8+ using vectorized parsing for better performance. ```csharp Parser NoneOf(string values, int minSize = 1, int maxSize = 0) ``` ```csharp Parser NoneOf(ReadOnlySpan values, int minSize = 1, int maxSize = 0) ``` ```csharp Parser NoneOf(SearchValue searchValues, int minSize = 1, int maxSize = 0) ``` ```csharp var input = "ababcad"; var parser = Terms.NoneOf("cd"); ``` -------------------------------- ### Discard - Obsolete Result Replacement Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Replaces the result of a previous parser with a default value or a specified custom value. This method is now obsolete and 'Then' should be used instead. ```csharp Parser Discard() Parser Discard(U value) ``` -------------------------------- ### Recursive Parser Definition Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Creates a parser that can reference itself, enabling the definition of recursive grammar structures. The parser function receives a reference to the deferred parser it represents. ```csharp Deferred Recursive(Func, Parser> parser) ``` ```csharp var number = Terms.Decimal(); var minus = Terms.Char('-'); var parser = Recursive((u) => minus.And(u) .Then(static x => 0 - x.Item2) .Or(number) ); parser.Parse("--1"); ``` -------------------------------- ### Not Parser Combinator Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Succeeds only if the given parser does not match the input. Useful for negative lookaheads. ```csharp Parser Not(Parser parser) ``` ```csharp var parser = Not(Terms.Text("hello")); parser.Parse("hello"); parser.Parse("world"); ``` -------------------------------- ### NoneOf Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches any character that is NOT in the specified list of characters. Supports vectorized parsing for .NET 8+. ```APIDOC ## NoneOf Parser ### Description Matches any other chars than the ones specified. ### Method Signature ```csharp Parser NoneOf(string values, int minSize = 1, int maxSize = 0) ``` ### Overloads for .NET 8+ ```csharp Parser NoneOf(ReadOnlySpan values, int minSize = 1, int maxSize = 0) Parser NoneOf(SearchValue searchValues, int minSize = 1, int maxSize = 0) ``` ### Usage Example ```csharp var input = "ababcad"; var parser = Terms.NoneOf("cd"); ``` ### Result Example ``` abab ``` ``` -------------------------------- ### String Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches a quoted string literal with escape sequences. Use this parser to parse strings from a programming language. ```APIDOC ## String Parser ### Description Matches a quoted string literal with escape sequences. Use this parser to parse strings from a programming language. ### Method Signature ```csharp Parser String(StringLiteralQuotes quotes = StringLiteralQuotes.SingleOrDouble) ``` ### Usage Example ```csharp var input = "'hello\\nworld'"; var parser = Terms.String(); ``` ### Result Example ``` 'hello\\nworld' ``` ``` -------------------------------- ### String Parser Source: https://github.com/sebastienros/parlot/blob/main/docs/parsers.md Matches a quoted string literal with escape sequences, suitable for parsing strings from programming languages. Supports single or double quotes by default. ```csharp Parser String(StringLiteralQuotes quotes = StringLiteralQuotes.SingleOrDouble) ``` ```csharp var input = "'hello\nworld'"; var parser = Terms.String(); ```