README

GoDoc Go Report Card

pars - Simple parser combinators for Go

For documentation please read the godoc.

Expand ▾ Collapse ▴

Documentation

Overview

    Package pars is a simple framework for parser combinators. It is designed to be easy to use, yet powerful enough to allow solving real world problems.

    Parsers can be arranged into flexible stacks of more elemental parsers. Parser results can be transformed via transformers to easily convert their results into a more fitting format or to implement additional conditions that must be fulfilled for a successful parse.

    Complex parsers can be debugged by wrapping them with a logger.

    pars parsers can read from a string or from an io.Reader, so streaming parsing is possible if you need it.

    Index

    Examples

    Constants

    This section is empty.

    Variables

    This section is empty.

    Functions

    func AssignInto

    func AssignInto(dest interface{}) func(interface{})

      AssignInto returns a setter for Into parsers. The setter will set a given field to the parsers result value on success and to the zero value on failure.

      This function or the generated setter might panic if the types do not fit.

      Example
      Output:
      
      Hello, Ark!
      

      func AssignIntoSlice

      func AssignIntoSlice(dest interface{}) func(interface{})

        AssignIntoSlice returns a setter for Into parsers. The setter will set a given slice pointer to the parsers result value on success and to nil on failure.

        This function or the generated setter might panic if the types do not fit.

        Example
        Output:
        
        Type safe numbers from parsing:
        []int{123, 456, 789}
        Sum: 1368
        

        func ParseFromReader

        func ParseFromReader(ior io.Reader, p Parser) (interface{}, error)

          ParseFromReader parses from an io.Reader.

          func ParseString

          func ParseString(s string, p Parser) (interface{}, error)

            ParseString is a helper function to directly use a parser on a string.

            Types

            type Clause

            type Clause []Parser

              Clause is the most simple DispatchClause. It is just a slice of parsers without any transformations.

              func (Clause) Parsers

              func (c Clause) Parsers() []Parser

                Parsers returns the parser slice for this clause.

                func (Clause) TransformError

                func (c Clause) TransformError(err error) error

                  TransformError returns the given error unchanged.

                  func (Clause) TransformResult

                  func (c Clause) TransformResult(val []interface{}) interface{}

                    TransformResult returns the only value if the slice of values has only one element. Otherwise it returns the slice of values unchanged.

                    type ClonableDispatchClause

                    type ClonableDispatchClause interface {
                    	DispatchClause
                    	//Clone creates a functionally equivalent clause with unique state.
                    	Clone() ClonableDispatchClause
                    }

                      ClonableDispatchClause is the interface of stateful DispatchClause types that need clones with unique state.

                      type DescribeClause

                      type DescribeClause struct {
                      	DispatchClause
                      	Description string
                      }

                        DescribeClause extends the error message of a clause so that a custom description is part of the message.

                        func (DescribeClause) Clone

                        func (d DescribeClause) Clone() DispatchClause

                          Clone calls clone of the inner clause if implemented.

                          func (DescribeClause) TransformError

                          func (d DescribeClause) TransformError(err error) error

                            TransformError extends the error message of a clause so that a custom description is part of the message.

                            type DispatchClause

                            type DispatchClause interface {
                            	//Parsers returns the parsers of the clause.
                            	Parsers() []Parser
                            	//TransformResult allows the DispatchClause to combine the results of its parsers to a single result.
                            	TransformResult([]interface{}) interface{}
                            	//TransformError allows the DispatchClause to replace or extend the error returned on a failed match.
                            	TransformError(error) error
                            }

                              DispatchClause is the interface of a clause used by Dispatch.

                              type InsteadOfClause

                              type InsteadOfClause struct {
                              	DispatchClause
                              	Result interface{}
                              }

                                InsteadOfClause extends a clause so that it returns a fixed value as if it was wrapped in an InsteadOf.

                                func (InsteadOfClause) Clone

                                func (i InsteadOfClause) Clone() DispatchClause

                                  Clone calls clone of the inner clause if implemented.

                                  func (InsteadOfClause) TransformResult

                                  func (i InsteadOfClause) TransformResult(_ []interface{}) interface{}

                                    TransformResult returns the Result as if the clause was wrapped in an InsteadOf.

                                    type InsteadOfDerefClause

                                    type InsteadOfDerefClause struct {
                                    	DispatchClause
                                    	Result interface{}
                                    }

                                      InsteadOfDerefClause extends a clause so that it returns a value that will be dereferenced as if the clause was wrapped in an InsteadOfDeref.

                                      func (InsteadOfDerefClause) Clone

                                        Clone calls clone of the inner clause if implemented.

                                        func (InsteadOfDerefClause) TransformResult

                                        func (i InsteadOfDerefClause) TransformResult(_ []interface{}) interface{}

                                          TransformResult returns the dereferenced Result as if the clause was wrapped in an InsteadOfDeref.

                                          type Logger

                                          type Logger interface {
                                          	Println(...interface{})
                                          }

                                            Logger is anything that lines can be printed to.

                                            type Parser

                                            type Parser interface {
                                            	//Parse is used for the actual parsing. It reads from the reader and returns the result or an error value.
                                            	//
                                            	//Each parser must remember enough from the call to this method to undo the reading in case of a parsing error that occurs later.
                                            	//
                                            	//When Parse returns with an error, Parse must make sure that all read bytes are unread so that another parser could try to parse them.
                                            	Parse(*Reader) (interface{}, error)
                                            	//Unread puts read bytes back to the reader so that they can be read again by other parsers.
                                            	Unread(*Reader)
                                            	//Clone creates a parser that works the same as the receiver. This allows to create a single parser as a blueprint for other parsers.
                                            	//
                                            	//Internal state from reading operations should not be cloned.
                                            	Clone() Parser
                                            }

                                              Parser contains the methods that each parser in this framework has to provide.

                                              var EOF Parser = eof{}

                                                EOF is a parser that never yields a value but that succeeds if and only if the source reached EOF

                                                func AnyByte

                                                func AnyByte() Parser

                                                  AnyByte returns a parser that reads exactly one byte from the source.

                                                  func AnyRune

                                                  func AnyRune() Parser

                                                    AnyRune returns a parser that parses a single valid rune. If no such rune can be read, ErrRuneExpected is returned.

                                                    func BigInt

                                                    func BigInt() Parser

                                                      BigInt returns a parser that parses an integer. The parsed integer is returned as a math/big.Int.

                                                      func Byte

                                                      func Byte(b byte) Parser

                                                        Byte returns a parser used to read a single known byte. A different byte is treated as a parsing error.

                                                        func Char

                                                        func Char(r rune) Parser

                                                          Char returns a parser used to read a single known rune. A different rune is treated as a parsing error.

                                                          func CharPred

                                                          func CharPred(pred func(rune) bool) Parser

                                                            CharPred returns a parser that parses a single rune as long as it fulfills the given predicate.

                                                            func DelimitedString

                                                            func DelimitedString(beginDelimiter, endDelimiter string) Parser

                                                              DelimitedString returns a parser that parses a string between two given delimiter strings and returns the value between.

                                                              func DiscardLeft

                                                              func DiscardLeft(left, right Parser) Parser

                                                                DiscardLeft returns a parser that calls two other parsers but only returns the result of the second parser. Both parsers must succeed.

                                                                Example
                                                                Output:
                                                                
                                                                123: int
                                                                

                                                                func DiscardRight

                                                                func DiscardRight(left, right Parser) Parser

                                                                  DiscardRight returns a parser that calls two other parsers but only returns the result of the first parser. Both parsers must succeed.

                                                                  func Dispatch

                                                                  func Dispatch(clauses ...DispatchClause) Parser

                                                                    Dispatch returns a parser that is like a combination of Seq and Or with limited backtracking.

                                                                    A Dispatch contains multiple clauses consisting of parsers. Dispatch parses by trying the clauses one by one. The first matching clause is used, later clauses are not tried. Each clause can contain multiple parsers. Clauses are special because they limit the backtracking: If the first parser of a clause matches, that clause is selected even if a later parser of that clause fails. If no clause matches, the error from the last clause is returned.

                                                                    The motivation for limited backtracking is in better error reporting. When an Or parser fails, all you know is that not a single parser succeeded. When a Dispatch parser fails after a clause was selected, you know which subclause was supposed to be parsed and can return a fitting error message.

                                                                    func DispatchSome

                                                                    func DispatchSome(clauses ...DispatchClause) Parser

                                                                      DispatchSome is a parser that combines Dispatch and Some. Like Dispatch, it tries to find a clause where the first parser succeeds and then commits to that clause. If the whole clause succeeds, the TransformResult method is called as usual. If a committed clause fails, the whole parser fails and returns the corresponding error (transformed by the TransformError method).

                                                                      Unlike Dispatch, after a successful parse another round starts with the first clause again. DispatchSome parses until either an error occurs or no single clause matched. Different from Dispatch, if no clause matches, it is not an error but marks the end of the loop.

                                                                      A successful DispatchSome returns a slice of all single results from each Dispatch round. This slice may be empty.

                                                                      func Error

                                                                      func Error(err error) Parser

                                                                        Error returns a parser that always fails with the given error

                                                                        func ErrorTransformer

                                                                        func ErrorTransformer(parser Parser, transformer func(error) (interface{}, error)) Parser

                                                                          ErrorTransformer wraps a parser so that an error result is transformed according to the given function. If the wrapped parser was successful, the result is not changed.

                                                                          func Except

                                                                          func Except(parser, except Parser) Parser

                                                                            Except returns a parser that wraps another parser so that it fails if a third, excepted parser would succeed.

                                                                            func Float

                                                                            func Float() Parser

                                                                              Float returns a parser that parses a floating point number. The supported format is an optional minus sign followed by digits optionally followed by a decimal point and more digits.

                                                                              func InsteadOf

                                                                              func InsteadOf(parser Parser, value interface{}) Parser

                                                                                InsteadOf wraps a parser so that a different given value is used as a result on success.

                                                                                func InsteadOfDeref

                                                                                func InsteadOfDeref(parser Parser, value interface{}) Parser

                                                                                  InsteadOfDeref wraps a parser so that a different given value is used as a result on success. The given value has to be a pointer to something (not nil) and will be dereferenced.

                                                                                  func Int

                                                                                  func Int() Parser

                                                                                    Int returns a parser that parses an integer. The parsed integer is converted via strconv.Atoi.

                                                                                    func Into

                                                                                    func Into(parser Parser, setter func(interface{})) Parser

                                                                                      Into wraps a parser so that a successful parse calls the given setter. If the wrapped parser fails, the setter is not called. If the returned parser succeeds at first, but is unread later, the setter will be called again with nil as the value.

                                                                                      It is recommended that the variable the setter writes into is not read from other parsers (e.g. via Into or Transformer) as it might become confusing to understand which parser has seen which setter result at which time.

                                                                                      Also, Into should be used as outmost as possible. A parser like 'Some(Into(AnyRune(), setter))' will have its setter called many times, so each value will be overwritten by the next one. On the other hand, you can use this for a setter that appends all values into a slice instead of just setting a single variable. Just have a clear idea of what your setter will do.

                                                                                      func JoinString

                                                                                      func JoinString(parser Parser) Parser

                                                                                        JoinString wraps a parser that returns a slice of runes or strings so that it returns a single string instead. Runes and strings can be mixed in the same slice. The slice also can contain other slices of runes and strings, recursively.

                                                                                        The returned parser WILL PANIC if the wrapped parser returns something that is not a slice of runes or strings!

                                                                                        func Many

                                                                                        func Many(parser Parser) Parser

                                                                                          Many returns a parser that matches a given parser one or more times. Not matching at all is an error.

                                                                                          func Optional

                                                                                          func Optional(parser Parser) Parser

                                                                                            Optional returns a parser that reads exactly one result according to a given other parser. If it fails, the error is discarded and nil is returned.

                                                                                            func Or

                                                                                            func Or(parsers ...Parser) Parser

                                                                                              Or returns a parser that matches the first of a given set of parsers. A later parser will not be tried if an earlier match was found. The returned parser uses the error message of the last parser verbatim.

                                                                                              Example
                                                                                              Output:
                                                                                              
                                                                                              124: string
                                                                                              

                                                                                              func Recursive

                                                                                              func Recursive(factory func() Parser) Parser

                                                                                                Recursive allows to recursively define a parser in terms of itself.

                                                                                                func RuneDelimitedString

                                                                                                func RuneDelimitedString(beginDelimiter, endDelimiter rune) Parser

                                                                                                  RuneDelimitedString returns a parser that parses a string between two given delimiter runes and returns the value between.

                                                                                                  func RunesUntil

                                                                                                  func RunesUntil(endCondition Parser) Parser

                                                                                                    RunesUntil returns a parser that parses runes as long as the given endCondition parser does not match.

                                                                                                    func Sep

                                                                                                    func Sep(item, separator Parser) Parser

                                                                                                      Sep returns a parser that parses a sequence of items according to a first parser that are separated by matches of a second parser.

                                                                                                      func Seq

                                                                                                      func Seq(parsers ...Parser) Parser

                                                                                                        Seq returns a parser that matches all of its given parsers in order or none of them.

                                                                                                        Example
                                                                                                        Output:
                                                                                                        
                                                                                                        $: int32
                                                                                                        123: int
                                                                                                        

                                                                                                        func Some

                                                                                                        func Some(parser Parser) Parser

                                                                                                          Some returns a parser that matches a given parser zero or more times. Not matching at all is not an error.

                                                                                                          func SplicingSeq

                                                                                                          func SplicingSeq(parsers ...Parser) Parser

                                                                                                            SplicingSeq returns a parser that works like a Seq but joins slices returned by its subparsers into a single slice.

                                                                                                            func String

                                                                                                            func String(expected string) Parser

                                                                                                              String returns a parser for a single known string. Different strings are treated as a parsing error.

                                                                                                              func StringCI

                                                                                                              func StringCI(expected string) Parser

                                                                                                                StringCI returns a case-insensitive parser for a single known string. Different strings are treated as a parsing error.

                                                                                                                func SwallowLeadingWhitespace

                                                                                                                func SwallowLeadingWhitespace(parser Parser) Parser

                                                                                                                  SwallowLeadingWhitespace wraps a parser so that it removes leading whitespace.

                                                                                                                  func SwallowTrailingWhitespace

                                                                                                                  func SwallowTrailingWhitespace(parser Parser) Parser

                                                                                                                    SwallowTrailingWhitespace wraps a parser so that it removes trailing whitespace.

                                                                                                                    func SwallowWhitespace

                                                                                                                    func SwallowWhitespace(parser Parser) Parser

                                                                                                                      SwallowWhitespace wraps a parser so that it removes leading and trailing whitespace.

                                                                                                                      func Transformer

                                                                                                                      func Transformer(parser Parser, transformer func(interface{}) (interface{}, error)) Parser

                                                                                                                        Transformer wraps a parser so that the result is transformed according to the given function. If the transformer returns an error, the parsing is handled as failed.

                                                                                                                        Example
                                                                                                                        Output:
                                                                                                                        
                                                                                                                        Sample1: 32°C
                                                                                                                        Sample2: 40°C
                                                                                                                        Sample3: 0°C
                                                                                                                        Sample3 error: Could not find expected sequence item 1: Could not parse expected string "°F": EOF
                                                                                                                        

                                                                                                                        func WithLogging

                                                                                                                        func WithLogging(parser Parser, logger Logger) Parser

                                                                                                                          WithLogging wraps a parser so that calls to it are logged to a given logger.

                                                                                                                          func WithStdLogging

                                                                                                                          func WithStdLogging(parser Parser, prefix string) Parser

                                                                                                                            WithStdLogging wraps a parser so that calls to it are logged to a logger logging to StdErr with a given prefix.

                                                                                                                            type Reader

                                                                                                                            type Reader struct {
                                                                                                                            	// contains filtered or unexported fields
                                                                                                                            }

                                                                                                                              Reader is an io.Reader that can Unread as many bytes as necessary.

                                                                                                                              func NewReader

                                                                                                                              func NewReader(r io.Reader) *Reader

                                                                                                                                NewReader creates a new Reader from an io.Reader.

                                                                                                                                func (*Reader) Read

                                                                                                                                func (br *Reader) Read(p []byte) (n int, err error)

                                                                                                                                  Read reads a slice of bytes.

                                                                                                                                  func (*Reader) Unread

                                                                                                                                  func (br *Reader) Unread(p []byte)

                                                                                                                                    Unread unreads a slice of bytes so that they will be read again by Read.

                                                                                                                                    type Scanner

                                                                                                                                    type Scanner struct {
                                                                                                                                    	// contains filtered or unexported fields
                                                                                                                                    }

                                                                                                                                      Scanner provides a convenient interface to use a single parser multiple times on the same reader.

                                                                                                                                      Successive calls to Scan will parse the input and allow the results to be accessed one at a time.

                                                                                                                                      Scanner stops at the first error.

                                                                                                                                      Example
                                                                                                                                      Output:
                                                                                                                                      
                                                                                                                                      this
                                                                                                                                      is
                                                                                                                                      a
                                                                                                                                      text
                                                                                                                                      of
                                                                                                                                      words
                                                                                                                                      <nil>
                                                                                                                                      

                                                                                                                                      func NewScanner

                                                                                                                                      func NewScanner(r *Reader, p Parser) Scanner

                                                                                                                                        NewScanner returns a new scanner using a given Reader and Parser.

                                                                                                                                        func (Scanner) Err

                                                                                                                                        func (s Scanner) Err() error

                                                                                                                                          Err returns the last encountered error that is not io.EOF. It returns nil otherwise.

                                                                                                                                          func (Scanner) Result

                                                                                                                                          func (s Scanner) Result() interface{}

                                                                                                                                            Result returns the most recently parsed value from a call to Scan.

                                                                                                                                            func (Scanner) ResultString

                                                                                                                                            func (s Scanner) ResultString() string

                                                                                                                                              ResultString returns the most recently parsed value from a call to Scan, cast to a String.

                                                                                                                                              This will panic if the last result is not a string!

                                                                                                                                              func (*Scanner) Scan

                                                                                                                                              func (s *Scanner) Scan() bool

                                                                                                                                                Scan invokes the parser on the reader and makes the results available via Result and Err.

                                                                                                                                                Scan returns true if the parsing succeeded and returns false otherwise.

                                                                                                                                                type StringJoiningClause

                                                                                                                                                type StringJoiningClause struct {
                                                                                                                                                	DispatchClause
                                                                                                                                                }

                                                                                                                                                  StringJoiningClause extends a clause that consists of parsers that return runes or strings so that it returnes a single string instead. Slices are handled recursively.

                                                                                                                                                  StringJoiningClause WILL PANIC if any of the parsers return something other than a rune or a string or a slice of these types.

                                                                                                                                                  func (StringJoiningClause) Clone

                                                                                                                                                    Clone calls clone of the inner clause if implemented.

                                                                                                                                                    func (StringJoiningClause) TransformResult

                                                                                                                                                    func (s StringJoiningClause) TransformResult(vals []interface{}) interface{}

                                                                                                                                                      TransformResult joins runes and strings together like JoinString.

                                                                                                                                                      Directories

                                                                                                                                                      Path Synopsis
                                                                                                                                                      examples
                                                                                                                                                      pars-calc
                                                                                                                                                      pars-calc is a small cli calculator that takes floats or calculations of floats consisting of additions, substractions, multiplications or divisions on StdIn, parses them via the parser implemented in parser.go into something easily evaluable, and prints the result of the calculation.
                                                                                                                                                      pars-calc is a small cli calculator that takes floats or calculations of floats consisting of additions, substractions, multiplications or divisions on StdIn, parses them via the parser implemented in parser.go into something easily evaluable, and prints the result of the calculation.