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 ¶
- func ParseFromReader(ior io.Reader, p Parser) (interface{}, error)
- func ParseString(s string, p Parser) (interface{}, error)
- type Logger
- type Parser
- func AnyByte() Parser
- func AnyRune() Parser
- func BigInt() Parser
- func Byte(b byte) Parser
- func Char(r rune) Parser
- func CharPred(pred func(rune) bool) Parser
- func DelimitedString(beginDelimiter, endDelimiter string) Parser
- func DiscardLeft(left, right Parser) Parser
- func DiscardRight(left, right Parser) Parser
- func Error(err error) Parser
- func ErrorTransformer(parser Parser, transformer func(error) (interface{}, error)) Parser
- func Except(parser, except Parser) Parser
- func Float() Parser
- func Int() Parser
- func Many(parser Parser) Parser
- func NewAnyByte() Parserdeprecated
- func NewAnyRune() Parserdeprecated
- func NewBigInt() Parserdeprecated
- func NewByte(b byte) Parserdeprecated
- func NewChar(r rune) Parserdeprecated
- func NewCharPred(pred func(rune) bool) Parserdeprecated
- func NewDelimitedString(beginDelimiter, endDelimiter string) Parserdeprecated
- func NewDiscardLeft(left, right Parser) Parserdeprecated
- func NewDiscardRight(left, right Parser) Parserdeprecated
- func NewError(err error) Parserdeprecated
- func NewExcept(parser, except Parser) Parserdeprecated
- func NewFloat() Parserdeprecated
- func NewInt() Parserdeprecated
- func NewLogger(parser Parser, logger *log.Logger) Parserdeprecated
- func NewMany(parser Parser) Parserdeprecated
- func NewOptional(parser Parser) Parserdeprecated
- func NewOr(parsers ...Parser) Parserdeprecated
- func NewRecursive(factory func() Parser) Parserdeprecated
- func NewRunesToString(parser Parser) Parserdeprecated
- func NewRunesUntil(endCondition Parser) Parserdeprecated
- func NewSep(item, separator Parser) Parserdeprecated
- func NewSeq(parsers ...Parser) Parserdeprecated
- func NewSome(parser Parser) Parserdeprecated
- func NewSplicingSeq(parsers ...Parser) Parserdeprecated
- func NewStdLogger(parser Parser, prefix string) Parserdeprecated
- func NewString(expected string) Parserdeprecated
- func NewStringCI(expected string) Parserdeprecated
- func NewSwallowLeadingWhitespace(parser Parser) Parserdeprecated
- func NewSwallowTrailingWhitespace(parser Parser) Parserdeprecated
- func NewSwallowWhitespace(parser Parser) Parserdeprecated
- func NewTransformer(parser Parser, transformer func(interface{}) (interface{}, error)) Parserdeprecated
- func Optional(parser Parser) Parser
- func Or(parsers ...Parser) Parser
- func Recursive(factory func() Parser) Parser
- func RunesToString(parser Parser) Parser
- func RunesUntil(endCondition Parser) Parser
- func Sep(item, separator Parser) Parser
- func Seq(parsers ...Parser) Parser
- func Some(parser Parser) Parser
- func SplicingSeq(parsers ...Parser) Parser
- func String(expected string) Parser
- func StringCI(expected string) Parser
- func SwallowLeadingWhitespace(parser Parser) Parser
- func SwallowTrailingWhitespace(parser Parser) Parser
- func SwallowWhitespace(parser Parser) Parser
- func Transformer(parser Parser, transformer func(interface{}) (interface{}, error)) Parser
- func WithLogging(parser Parser, logger Logger) Parser
- func WithStdLogging(parser Parser, prefix string) Parser
- type Reader
- type Scanner
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ParseFromReader ¶
ParseFromReader parses from an io.Reader.
func ParseString ¶
ParseString is a helper function to directly use a parser on a string.
Types ¶
type Logger ¶ added in v1.1.0
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 ¶ added in v1.1.0
func AnyByte() Parser
AnyByte returns a parser that reads exactly one byte from the source.
func AnyRune ¶ added in v1.1.0
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 ¶ added in v1.1.0
func BigInt() Parser
BigInt returns a parser that parses an integer. The parsed integer is returned as a math/big.Int.
func Byte ¶ added in v1.1.0
Byte returns a parser used to read a single known byte. A different byte is treated as a parsing error.
func Char ¶ added in v1.1.0
Char returns a parser used to read a single known rune. A different rune is treated as a parsing error.
func CharPred ¶ added in v1.1.0
CharPred returns a parser that parses a single rune as long as it fulfills the given predicate.
func DelimitedString ¶ added in v1.1.0
DelimitedString returns a parser that parses a string between two given delimiter strings and returns the value between.
func DiscardLeft ¶ added in v1.1.0
DiscardLeft returns a parser that calls two other parsers but only returns the result of the second parser. Both parsers must succeed.
Example ¶
data := "$123" dollarParser := DiscardLeft(Char('$'), Int()) result, err := ParseString(data, dollarParser) if err != nil { fmt.Println("Error while parsing:", err) return } fmt.Printf("%v: %T\n", result, result)
Output: 123: int
func DiscardRight ¶ added in v1.1.0
DiscardRight returns a parser that calls two other parsers but only returns the result of the first parser. Both parsers must succeed.
func ErrorTransformer ¶ added in v1.2.0
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 ¶ added in v1.1.0
Except returns a parser that wraps another parser so that it fails if a third, excepted parser would succeed.
func Float ¶ added in v1.1.0
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 Int ¶ added in v1.1.0
func Int() Parser
Int returns a parser that parses an integer. The parsed integer is converted via strconv.Atoi.
func Many ¶ added in v1.1.0
Many returns a parser that matches a given parser one or more times. Not matching at all is an error.
func NewAnyByte
deprecated
func NewAnyByte() Parser
NewAnyByte returns a parser that reads exactly one byte from the source.
Deprecated: Use AnyByte instead.
func NewAnyRune
deprecated
func NewAnyRune() Parser
NewAnyRune returns a parser that parses a single valid rune. If no such rune can be read, ErrRuneExpected is returned.
Deprecated: Use AnyRune instead.
func NewCharPred
deprecated
func NewDelimitedString
deprecated
func NewDiscardLeft
deprecated
func NewDiscardRight
deprecated
func NewOptional
deprecated
func NewRecursive
deprecated
func NewRunesToString
deprecated
func NewRunesUntil
deprecated
func NewSplicingSeq
deprecated
func NewStdLogger
deprecated
func NewStringCI
deprecated
func NewSwallowLeadingWhitespace
deprecated
func NewSwallowTrailingWhitespace
deprecated
func NewSwallowWhitespace
deprecated
func NewTransformer
deprecated
func Optional ¶ added in v1.1.0
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 ¶ added in v1.1.0
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 ¶
data := "124" parser := Or(String("123"), String("124")) result, err := ParseString(data, parser) if err != nil { fmt.Println("Error while parsing:", err) return } fmt.Printf("%v: %T\n", result, result)
Output: 124: string
func Recursive ¶ added in v1.1.0
Recursive allows to recursively define a parser in terms of itself.
func RunesToString ¶ added in v1.1.0
RunesToString wraps a parser that returns a slice of runes so that it returns a string instead. The returned parser WILL PANIC if the wrapped parser returns something that is not a slice of runes!
func RunesUntil ¶ added in v1.1.0
RunesUntil returns a parser that parses runes as long as the given endCondition parser does not match.
func Sep ¶ added in v1.1.0
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 ¶ added in v1.1.0
Seq returns a parser that matches all of its given parsers in order or none of them.
Example ¶
data := "$123" dollarParser := Seq(Char('$'), Int()) result, err := ParseString(data, dollarParser) if err != nil { fmt.Println("Error while parsing:", err) return } values := result.([]interface{}) fmt.Printf("%c: %T\n", values[0], values[0]) fmt.Printf("%v: %T\n", values[1], values[1])
Output: $: int32 123: int
func Some ¶ added in v1.1.0
Some returns a parser that matches a given parser zero or more times. Not matching at all is not an error.
func SplicingSeq ¶ added in v1.1.0
SplicingSeq returns a parser that works like a Seq but joins slices returned by its subparsers into a single slice.
func String ¶ added in v1.1.0
String returns a parser for a single known string. Different strings are treated as a parsing error.
func StringCI ¶ added in v1.1.0
StringCI returns a case-insensitive parser for a single known string. Different strings are treated as a parsing error.
func SwallowLeadingWhitespace ¶ added in v1.1.0
SwallowLeadingWhitespace wraps a parser so that it removes leading whitespace.
func SwallowTrailingWhitespace ¶ added in v1.1.0
SwallowTrailingWhitespace wraps a parser so that it removes trailing whitespace.
func SwallowWhitespace ¶ added in v1.1.0
SwallowWhitespace wraps a parser so that it removes leading and trailing whitespace.
func Transformer ¶ added in v1.1.0
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 ¶
package main import ( "bitbucket.org/ragnara/pars" "fmt" ) // Celsius contains a temperature in degree celsius. type Celsius int func (c Celsius) String() string { return fmt.Sprintf("%v°C", int(c)) } // TemperatureParser is a parser for temperature strings returning Celsius instances. type TemperatureParser struct { pars.Parser } // NewTemperatureParser creates a new TemperatureParser instance. func NewTemperatureParser() TemperatureParser { //Define the format simpleParser := pars.Seq(pars.Int(), pars.Or(pars.String("°C"), pars.String("°F"))) //Add an conversion transformedParser := pars.Transformer(simpleParser, transformParsedTemperatureToCelsius) return TemperatureParser{Parser: transformedParser} } // Parse returns the Celsius instance for a temperature string containing an integer followed by either "°C" or "°F". Fahrenheit strings are converted to celsius. // For other strings, an error is returned. func (t TemperatureParser) Parse(s string) (Celsius, error) { val, err := pars.ParseString(s, t.Parser) if err != nil { return Celsius(0), err } return val.(Celsius), nil } // MustParse parses exactly like Parse but panics if an invalid string was found. It should not be used on user input! func (t TemperatureParser) MustParse(s string) Celsius { val, err := t.Parse(s) if err != nil { panic(err) } return val } func transformParsedTemperatureToCelsius(parserResult interface{}) (interface{}, error) { values := parserResult.([]interface{}) degrees := values[0].(int) unit := values[1].(string) switch unit { case "°C": return Celsius(degrees), nil case "°F": return Celsius((degrees - 32) * 5 / 9), nil default: panic("Impossible unit: " + unit) } } func main() { sample1 := "32°C" sample2 := "104°F" sample3 := "128K" fmt.Println("Sample1:", NewTemperatureParser().MustParse(sample1)) fmt.Println("Sample2:", NewTemperatureParser().MustParse(sample2)) val, err := NewTemperatureParser().Parse(sample3) fmt.Println("Sample3:", val) fmt.Println("Sample3 error:", err.Error()) }
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 ¶ added in v1.1.0
WithLogging wraps a parser so that calls to it are logged to a given logger.
func WithStdLogging ¶ added in v1.1.0
WithStdLogging wraps a parser so that calls to it are logged to a logger logging to StdErr with a given prefix.
type Reader ¶ added in v1.2.0
type Reader struct {
// contains filtered or unexported fields
}
Reader is an io.Reader that can Unread as many bytes as necessary.
type Scanner ¶ added in v1.2.0
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 ¶
data := "this is a text of words" reader := NewReader(strings.NewReader(data)) wordParser := SwallowTrailingWhitespace(RunesToString(RunesUntil(CharPred(unicode.IsSpace)))) scanner := NewScanner(reader, wordParser) for scanner.Scan() { fmt.Println(scanner.ResultString()) } fmt.Println(scanner.Err())
Output: this is a text of words <nil>
func NewScanner ¶ added in v1.2.0
NewScanner returns a new scanner using a given Reader and Parser.
func (Scanner) Err ¶ added in v1.2.0
Err returns the last encountered error that is not io.EOF. It returns nil otherwise.
func (Scanner) Result ¶ added in v1.2.0
func (s Scanner) Result() interface{}
Result returns the most recently parsed value from a call to Scan.
func (Scanner) ResultString ¶ added in v1.2.0
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!
Source Files ¶
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. |