/chomp

A parser combinator library for chomping strings (a rune at a time) in Go

Primary LanguageGoMIT LicenseMIT

Chomp

A parser combinator library for chomping strings (a rune at a time) in Go. A more intuitive way to parse text without having to write a single regex. Happy to chomp both ASCII and Unicode (it all tastes the same).

Inspired by nom 💜.

Design

At the heart of chomp is a combinator. A higher-order function capable of parsing text under a defined condition and returning a tuple (1,2,3):

  • 1: the remaining unparsed (or unchomped) text.
  • 2: the parsed (or chomped) text.
  • 3: an error if the combinator failed to parse.

Here's a sneak peek at its definition:

type Result interface {
	string | []string
}

type Combinator[T Result] func(string) (string, T, error)

A combinator in its simplest form would look like this:

func Tag(str string) chomp.Combinator[string] {
	return func(s string) (string, string, error) {
		if strings.HasPrefix(s, str) {
			// Return a tuple containing:
			// 1. the remaining string after the prefix
			// 2. the matched prefix
			// 3. no error
			return s[len(str):], str, nil
		}

		return s, "", chomp.CombinatorParseError{
			Input: str,
			Text: s,
			Type: "tag",
		}
	}
}

The true power of chomp comes from the ability to build parsers by chaining (or combining) combinators together.

Writing a Parser Combinator

Take a look at one of the examples of how to write a parser combinator.

  1. GPG Private Key parser

Why use Chomp?

  • Combinators are very easy to write and combine into more complex parsers.
  • Code written with chomp looks like natural grammar and is easy to understand, maintain and extend.
  • It is incredibly easy to unit test.

Badges

Build status License MIT Go Report Card Go Version DeepSource