struct Parsem::Parser(Token, Output)

Overview

Parsem's composable parser type.

Generic type parameters:

Defined in:

parser.cr

Class Method Summary

Instance Method Summary

Class Method Detail

def self.fail(expected = nil, actual = ParseError::FailParser.new) #

Returns a parser that fails unconditionally.


[View source]
def self.pure(constant : Output) #

Returns a parser that consumes no input and produces constant.


[View source]

Instance Method Detail

def <<(other : Parser(Token, OtherOutput)) : self forall OtherOutput #

Sequencing left-yield operator.

Returns a parser that applies the left parser, and if that succeeds, then the right parser.

On success, keeps the output of the left parser, but discards that of the right parser.


[View source]
def <=>(other : Parser(Token, OtherOutput)) forall OtherOutput #

Sequencing proc-apply operator.

Returns a parser that applies the left parser, and if that succeeds, then the right parser.

On success, calls the output of the left parser, which must be a proc (function), with the output of the right parser as its sole argument. Produces as output the result of that call.

To create a valid left-hand-side parser for this operation, use Proc#^(Parser).


[View source]
def >>(other : Parser(Token, OtherOutput)) : Parser(Token, OtherOutput) forall OtherOutput #

Sequencing right-yield operator.

Returns a parser that applies the left parser, and if that succeeds, then the right parser.

On success, discards the output of the left parser, but keeps that of the right parser.


[View source]
def |(other : Parser(Token, OtherOutput)) : Parser(Token, Output | OtherOutput) forall OtherOutput #

Choice operator.

Returns a parser that applies the left parser. If it fails without consuming any input, then applies the right parser instead.

To allow backtracking when the left parser consumes input, tag it with #allow_backtrack.


[View source]
def ahead #

Returns a new parser that applies this parser, but without consuming any input.


[View source]
def allow_backtrack #

Makes the choice operator (#|) always backtrack when this parser fails.

Normally, backtracking only occurs if the failed parser didn't consume any input. This bypasses that restriction.

NOTE This must be applied directly to the parser that is composed with #|, not any of its descendants.

NOTE This makes #| swallow all of this parser's error messages, too.

WARNING If you aren't careful, this can cause extremely bad performance on invalid input.

BUG Backtracking may result in confusing and unintuitive error messages.


[View source]
def concat #

Maps Parsem.concat over this parser, which must output an array. Used to concatenate arrays produced by this and the next parser.


[View source]
def extend #

Maps Parsem.extend over this parser, which must output an array. Used to append the result of the next parser to this parser's output array.


[View source]
def flatten #

Shortcut for self.map &.flatten. Used to flatten arrays-of-arrays produced by this parser.


[View source]
def join #

Shortcut for self.map &.join. Useful when this parser produces arrays of characters, but you want strings instead.


[View source]
def map(&block : Output -> NewOutput) forall NewOutput #

Returns a parser that that applies this parser, then pipes the output through block.

If this parser succeeds, produces the result of calling block with the output value as the argument. Otherwise, fails without calling block.

This is a block-based convenience wrapper for Proc#^(Parser), with the restriction that the provided block cannot take more than one parameter.


[View source]
def name(name : String) #

Ascribes the next token a user-friendly name for display in error messages.


[View source]
def name?(name : String) #

Ascribes the next token a user-friendly name for display in error messages, if it doesn't already have one.


[View source]
def not_ahead #

Returns a new parser that applies this parser, without consuming any input, and succeeds only when this parser fails.

This parser must output Token or Array(Token).


[View source]
def optional #

Returns a parser that applies this parser, and succeeds regardless of the result.

If this parser succeeds, produces an array containing its output value. Otherwise, produces an empty array.


[View source]
def parse(tokens : Slice(Token)) : ParseError(Token) | Output #

Applies the parser to tokens. If it matches, returns the produced output; otherwise, returns a ParseError.


[View source]
def parse(tokens : Array(Token)) : ParseError(Token) | Output #

Applies the parser to tokens. If it matches, returns the produced output; otherwise, returns a ParseError.

WARNING You must not resize tokens for the duration of this method. Parsing is done on its internal array buffer for efficiency, and resizing can invalidate the buffer.


[View source]
def parse(string : String) #

Applies the parser to string. If it matches, returns the produced output; otherwise, returns a ParseError.

Type restriction: Token = Char

TODO Unicode support


[View source]
def parse_to_string(string : String) #

Applies the parser to string and tries to convert the result to a string.

If Output = Array(Char) and the parser matches, returns the produced output #joind into a string. Otherwise, acts like #parse(String).

Type restriction: Token = Char

TODO Unicode support


[View source]
def repeat(range : Range(B, E)) forall B, E #

Returns a parser that applies this parser some number of times within range.

If this parser succeeds at least range.begin || 0 times, produces an array of the output values from all the successful applications. Otherwise, fails with the first ParseError encountered.


[View source]
def repeat(count : Int32) #

Returns a parser that applies this parser count times.

If this parser succeeds all count times, produces an array of its output values. Otherwise, fails with the first ParseError encountered.


[View source]