parc

package module
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 7, 2024 License: MIT Imports: 6 Imported by: 0

README

parc

parc is a Parser Combinator written in Golang.

It mainly inspired by the Arcsecond library. Many ideas are also borrowed from the How Parser Combinators Work, Parser Combinators From Scratch youtube series of Low Byte Productions, the presentation of Jeremy Brown at GopherCon 2022: on Parsing w/o Code Generators: Parser Combinators in Go with Generics, and the nom Rust parser combinator library.

See the tutorial/ to get started with this package.

Read the parc package doc pages.

As every parser has its own unit tests, so find them in the source code, and study the ones you want to use, in order to better understanding how to use them.

References

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// Newline matches a space character ` `
	Space = Char(" ").As("Space")

	// Newline matches a newline character \n
	Newline = Char("\n").As("Newline")

	// Tab matches a tab character \t
	Tab = Char("\t").As("Tab")

	// Crlf recognizes the string \r\n
	Crlf = Str("\r\n").As("Crlf")

	// AnyChar matches any character
	AnyChar = Cond(IsAnyChar).As("AnyChar")

	// AnyStr matches any characters
	AnyStr = CondMin(IsAnyChar, 1).As("AnyStr")

	// Letter is a parser that matches a single letter character with the target string
	Letter = Cond(IsAsciiLetter).As("Letter")

	// Letters is a parser that matches one or more letter characters with the target string
	Letters = CondMin(IsAsciiLetter, 1).As("Letters")

	// Digit is a parser that matches a singl digit character with the target string
	Digit = Cond(IsDigit).As("Digit")

	// Digits is a parser that matches one or more digit characters with the target string
	Digits = CondMin(IsDigit, 1).As("Digits")

	// Integer is a parser that matches one or more digit characters with the target string and returns with an int value
	Integer = Digits.Map(func(in Result) Result {
		strValue := in.(string)
		intValue, _ := strconv.Atoi(strValue)
		return Result(intValue)
	})

	// RestOfLine returns with the content of the input string until the next newline (\n) character,
	// or until the end of the input string, if there is no newline found.
	RestOfLine = SequenceOf(
		CondMin(func(r rune) bool { return r != '\n' }, 1),
		Choice(Newline, EndOfInput()),
	).As("RestOfLine").Map(func(in Result) Result {
		sequence := in.([]Result)
		return sequence[0]
	})
)
View Source
var IsAlphabetic = IsAsciiLetter

IsAlphabetic is an alias of IsAsciiLetter

View Source
var IsDigit = IsDecimalDigit

IsDigit is an alias of IsDecimalDigit

View Source
var Optional = ZeroOrOne

Optional is an alias of ZeroOrOne

View Source
var Times = Count

Times is an alias of the Count parser

View Source
var TimesMin = CountMin

TimesMin is an alias of the CountMin parser

View Source
var TimesMinMax = CountMinMax

TimesMinMax is an alias of the CountMinMax parser

Functions

func Between

func Between(leftParser, rightParser *Parser) func(*Parser) *Parser

Between is a utility function that takes two parsers as arguments that defines a starting and ending pattern of a content, and returns a function that takes a content parser as argument. Using the resulted parser will provide a result that is the outcome of the content parser.

func Debug

func Debug(level int)

Debug switches debugging ON with the given level. Level=0 means, Debug is switched off.

func GetResultsItem added in v0.6.0

func GetResultsItem[T any](result Result, itemIdx int) *T

GetResultsItem takes the nth item from the results array, if there is any, otherwise it returns nil value

func IsAlphaNumeric added in v0.3.0

func IsAlphaNumeric(r rune) bool

IsAlphaNumeric tests if rune is ASCII alphanumeric: [A-Za-z0-9]

func IsAnyChar added in v0.3.0

func IsAnyChar(r rune) bool

IsAnyChar tests if rune is any char. Actually it always returns with true.

func IsAsciiLetter added in v0.3.0

func IsAsciiLetter(r rune) bool

IsAlphabetic tests if rune is ASCII alphabetic: [A-Za-z]

func IsBinaryDigit added in v0.3.0

func IsBinaryDigit(r rune) bool

IsBinaryDigit tests if rune is ASCII binary digit: [0-1]

func IsCarriageReturn added in v0.3.0

func IsCarriageReturn(r rune) bool

IsCarriageReturn tests if rune is ASCII newline: [\r]

func IsDecimalDigit added in v0.3.0

func IsDecimalDigit(r rune) bool

IsDecimalDigit tests if rune is ASCII digit: [0-9]

func IsHexadecimalDigit added in v0.3.0

func IsHexadecimalDigit(r rune) bool

IsHexadecimalDigit tests if rune is ASCII hex digit: [0-9A-Fa-f]

func IsNewline added in v0.3.0

func IsNewline(r rune) bool

IsNewline tests if rune is ASCII newline: [\n]

func IsOctalDigit added in v0.3.0

func IsOctalDigit(r rune) bool

IsOctDigit tests if rune is ASCII octal digit: [0-7]

func IsSpace added in v0.3.0

func IsSpace(r rune) bool

IsSpace tests if rune is ASCII space or tab

func IsTab added in v0.3.0

func IsTab(r rune) bool

IsTab Tests if rune is ASCII space or tab: [\t]

func IsWhitespace added in v0.3.0

func IsWhitespace(r rune) bool

IsWhitespace tests if rune is ASCII space, newline or tab

func Ref added in v0.6.0

func Ref[T any](value T) *T

Ref creates a reference to any value It is useful to define reference values of fixtures in test cases

Types

type Parser

type Parser struct {
	ParserFun ParserFun
	// contains filtered or unexported fields
}

Parser struct represent a parser

func Chain

func Chain(parser *Parser, parserMakerFn func(Result) *Parser) *Parser

Chain takes a function which receieves the last matched value and should return a parser. That parser is then used to parse the following input, forming a chain of parsers based on previous input. Chain is the fundamental way of creating contextual parsers.

func Char

func Char(s string) *Parser

Char is a parser that matches a fixed, single character value with the target string exactly one time

func Choice

func Choice(parsers ...*Parser) *Parser

Choice is a parser that executes a sequence of parsers against a parser state, and returns the first successful result if there is any

func Cond added in v0.3.0

func Cond(conditionFn func(rune) bool) *Parser

Cond returns a Parser which tests the next rune in the input with the condition function. If the condition is met, the rune is consumed from the input and the parser succeeds. Otherwise the parser fails.

func CondMin added in v0.3.0

func CondMin(conditionFn func(rune) bool, minOccurences int) *Parser

CondMin returns a Parser which tests the next rune in the input with the condition function. If the condition is met, the rune is consumed from the input and the parser succeeds as many times as possible, but at least `minOccurences` times. Otherwise the parser fails.

func CondMinMax added in v0.3.0

func CondMinMax(conditionFn func(rune) bool, minOccurences, maxOccurences int) *Parser

CondMinMax returns a Parser which tests the next rune in the input with the condition function. If the condition is met, the rune is consumed from the input and the parser succeeds at minimum of `minOccurences` times, but maximum of `maxOccurences` times. Otherwise the parser fails.

func Count added in v0.4.0

func Count(parser *Parser, count int) *Parser

Count tries to execute the parser given as a parameter exactly count times. Collects results into an array and returns with it at the end. It returns error if it could not run the parser exaclty count times. You can use Times parser, instead of Count since that is an alias of this parser.

func CountMin added in v0.4.0

func CountMin(parser *Parser, minOccurences int) *Parser

CountMin tries to execute the parser given as a parameter at least minOccurences times. Collects results into an array and returns with it at the end. It returns error if it could not run the parser at least minOccurences times. You can use TimesMin parser, instead of CountMin since that is an alias of this parser.

func CountMinMax added in v0.4.0

func CountMinMax(parser *Parser, minOccurences int, maxOccurences int) *Parser

CountMinMax tries to execute the parser given as a parameter at least minOccurences but maximum maxOccurences times. Collects results into an array and returns with it at the end. It returns error if it could not run the parser at least minOccurences times. You can use TimesMinMax parser, instead of CountMinMax since that is an alias of this parser.

func EndOfInput

func EndOfInput() *Parser

EndOfInput is a parser that only succeeds when there is no more input to be parsed.

func Map

func Map(parser *Parser, mapper func(Result) Result) *Parser

Map call the map function to the result and returns with the return value of this function

func NewParser

func NewParser(parserName string, parserFun ParserFun) *Parser

NewParser is the constructor of the Parser

func OneOrMore

func OneOrMore(parser *Parser) *Parser

OneOrMore is similar to the ZeroOrMore parser, but it must be able to run the parser successfuly at least once, otherwise it return with error. It executes the parser given as a parameter, until it succeeds, meanwhile it collects the results into an array then returns with it at the end.

func RegExp

func RegExp(regexpStr string) *Parser

RexExp is a parser that matches the regexpStr regular expression with the target string and returns with the first match.

func Rest added in v0.4.0

func Rest() *Parser

Rest is a parser that returns the remaining input

func SequenceOf

func SequenceOf(parsers ...*Parser) *Parser

SequenceOf is a parser that executes a sequence of parsers against a parser state

func StartOfInput

func StartOfInput() *Parser

StartOfInput is a parser that only succeeds when the parser is at the beginning of the input.

func Str

func Str(s string) *Parser

Str is a parser that matches a fixed string value with the target string exactly one time

func ZeroOrMore

func ZeroOrMore(parser *Parser) *Parser

ZeroOrMore tries to execute the parser given as a parameter, until it succeeds. Collects the results into an array and returns with it at the end. It never returns error either it could run the parser any times without errors or never.

func ZeroOrOne added in v0.4.0

func ZeroOrOne(parser *Parser) *Parser

ZeroOrOne tries to execute the parser given as a parameter once. It returns `nil` if it could not match, or a single result if match occured. It never returns error either it could run the parser only once or could not run it at all.

func (*Parser) As added in v0.5.0

func (p *Parser) As(name string) *Parser

As takes a name for the parser, that will be used in error messages and debugging instead of the original native name of the parser

func (*Parser) Chain

func (p *Parser) Chain(parserMakerFn func(Result) *Parser) *Parser

Chain takes a function which receieves the last matched value and should return a parser. That parser is then used to parse the following input, forming a chain of parsers based on previous input. Chain is the fundamental way of creating contextual parsers.

func (*Parser) ErrorMap

func (p *Parser) ErrorMap(mapperFn func(ParserState) error) *Parser

ErrorMap is like Map but it transforms the error value. The function passed to ErrorMap gets an object the current error message (error), the index (index) that parsing stopped at from this parsing session.

func (*Parser) Map

func (p *Parser) Map(mapper func(Result) Result) *Parser

Map call the map function to the result and returns with the return value of this function

func (*Parser) Name

func (p *Parser) Name() string

Name returns the name of the parser

func (*Parser) Parse

func (p *Parser) Parse(inputString *string) ParserState

Parse runs the parser with the target string

func (*Parser) SetParserFun added in v0.5.0

func (p *Parser) SetParserFun(parserFun ParserFun)

Name returns the name of the parser

type ParserFun

type ParserFun func(parserState ParserState) ParserState

ParserFun type represents the generic format of parsers, that receives a ParserState as input, and returns with a new ParserState as an output

type ParserState

type ParserState struct {
	Results Result
	Index   int
	Err     error
	IsError bool
	// contains filtered or unexported fields
}

ParserState represents an actual state of a parser

func NewParserState added in v0.3.0

func NewParserState(inputString *string, result Result, index int, err error) ParserState

NewParserState creates a new ParserState instance

func (ParserState) AtTheEnd added in v0.3.0

func (ps ParserState) AtTheEnd() bool

AtTheEnd returns true if index points to the end of the input string, otherwise returns false.

func (ParserState) Consume added in v0.3.0

func (ps ParserState) Consume(n int) ParserState

Consume returns a new state in which the index pointer is advanced by n bytes

func (ParserState) IndexPosStr added in v0.5.0

func (ps ParserState) IndexPosStr() string

IndexPos returns with the string format detailed position of the index of the input string including the absolute position, the row and column.

func (ParserState) IndexRowCol added in v0.5.0

func (ps ParserState) IndexRowCol() (row, col int)

IndexRowCol returns with the row and column position of the actual index of the input string

func (ParserState) InputLength added in v0.3.0

func (ps ParserState) InputLength() int

InputLength returns the total length of the input

func (ParserState) NextRune added in v0.3.0

func (ps ParserState) NextRune() (rune, ParserState)

NextRune returns the next rune in the input, as well as a new state in which the rune has been consumed.

func (ParserState) Remaining added in v0.3.0

func (ps ParserState) Remaining() string

Remaining returns the a string which is just the unconsumed input

func (ParserState) String

func (ps ParserState) String() string

String returns with the string fromat of the parser state

type Result

type Result any

Result represents the type of the result that is produced by calling the parser function of a parser. It is stored in the parser state the parser's parser function returns with.

func JoinStrResults added in v0.6.0

func JoinStrResults(in Result) Result

JoinStrResults merges the a string-array result into a single string. The items of the array must be string type. TODO: Handle non-string type items, e.g. skip nils, stringify other types, etc.

type TestCase added in v0.6.0

type TestCase struct {
	Input          string
	ExpectedResult Result
}

Generic TestCase struct to help writing test cases for sub-parsers

Directories

Path Synopsis
tutorial
Map
Str

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL