Skip to content

Parsers

kevin-montrose edited this page Apr 10, 2021 · 5 revisions

Parsers

Introduction

The Parser class provides a way to map a sequence of characters to an instance of some type as part of deserializing a cell. Parser is used as part of both static and dynamic deserialization.

Supported Backers

Parser instances can be backed by constructors, methods, and delegates.

Delegates and methods return a bool value where true indicates success and false indicates failure. If a delegate or method fails and a fallback has been configured with Else(Parser) the fallback will be tried.

Constructors

Two kinds of ConstructorInfo can back a Parser.

Constructors are assumed to never fail, and therefore will never fallback to another Parser. If a constructor is fallible, it should be wrapped in a method or delegate that detects failures and returns false.

Delegates

Any delegate of the form bool Name(ReadOnlySpan<char>, in ReadContext, out DesiredValue) can back a Parser.

Cesil provides ParserDelegate<TOutput> and Parser.ForDelegate<TOutput>(ParserDelegate<TOutput>) which conform to this form. You can also explicitly cast any delegate to Parser, provided it is logically equivalent to ParserDelegate<TOutput>.

If a delegate backed Parser returns false, the Parser configured by Else(Parser) (if any) will be tried next.

Methods

Any static MethodInfo that exposes the same interface as ParserDelegate<TOutput> can back a Parser.

Concretely, the method must:

  • be static
  • return a bool
  • have 3 parameters

You can also explicitly cast any MethodInfo to Parser, provided it is logically equivalent to ParserDelegate<TOutput>.

If a method backed Parser returns false, the Parser configured by Else(Parser) (if any) will be tried next.

Defaults

Cesil provides a number of Default Parsers, obtainable with Parser.GetDefault(TypeInfo).

These Parsers all correctly report failure, and thus support chaining.

Chaining With Else(Parser)

Delegate and method backed Parsers can fail, and indicate that by returning false. If Cesil cannot parse a character sequence, an exception is raised.

To try another Parser after one fails, you chain them with the Else(Parser) method. Else(Parser) specifies which Parser to try if the current one fails.

Else(Parser) returns a new Parser, the original is not modified.

If a Parser already has a fallback Parser specified, the one passed to Else(Parser) will be tried after all the others have failed. Conceptually, Else(Parser) adds a Parser to the end of a list of fallbacks to try.

Explicit Casts

Cesil provides explicit casts of MethodInfo, ConstructorInfo and Delegate to Parser. These are roughly equivalent to calling the static ForXXX(...) methods on Parser, but differ by allowing null values.

Clone this wiki locally