Command pigeon generates parsers in Go from a PEG grammar.
Go Makefile Shell
Switch branches/tags
Nothing to show
Clone or download
breml Add -nolint flag (#67)
If the -nolint flag is provided to pigeon, special comments in
the format '// nolint: ...' are added to the source code of the
generated parser. Those comments are understood by [gometalinter].
The respective linter warnings are then ignored.

[gometalinter]: https://github.com/alecthomas/gometalinter
Latest commit 15c8782 Jun 2, 2018
Permalink
Failed to load latest commit information.
ast fix panic when state code block used with the -optimize-grammar option ( Oct 22, 2017
bootstrap Add -nolint flag (#67) Jun 2, 2018
builder Add -nolint flag (#67) Jun 2, 2018
examples Add -nolint flag (#67) Jun 2, 2018
grammar Add state change expression (#{}) Oct 14, 2017
misc Fix redundant newline error with Go 1.10.x Apr 14, 2018
test Add -nolint flag (#67) Jun 2, 2018
.editorconfig Formatting .editorconfig Apr 14, 2018
.gitattributes cleanup global state, fix .gitattributes Oct 14, 2017
.gitignore Reorganize .gitignore, added *.out May 23, 2017
.travis.yml Remove support for Go < 1.7 May 6, 2018
CONTRIBUTING.md test on all supported versions, rename imports to new github path Mar 24, 2017
LICENSE initial commit in pigeon repo Apr 5, 2015
Makefile Add -nolint flag (#67) Jun 2, 2018
README.md Remove support for Go < 1.7 May 6, 2018
TODO todo: update item Apr 16, 2015
benchparse_test.go builder: rename Parse to ParseReader, make Parse accept a slice of bytes Apr 6, 2015
cmpast_test.go test on all supported versions, rename imports to new github path Mar 24, 2017
doc.go Add -nolint flag (#67) Jun 2, 2018
main.go Add -nolint flag (#67) Jun 2, 2018
main_test.go test: AndCodeExpr and NotCodeExpr Apr 12, 2015
parse_test.go Reformat with `gofmt -s` Oct 21, 2017
pigeon.go Add -nolint flag (#67) Jun 2, 2018
reserved_words.go initial commit in pigeon repo Apr 5, 2015
targeted_test.go Add AllowInvalidUTF8 option Oct 18, 2017
unicode_classes.go initial commit in pigeon repo Apr 5, 2015

README.md

pigeon - a PEG parser generator for Go

GoDoc build status GoReportCard Software License

The pigeon command generates parsers based on a parsing expression grammar (PEG). Its grammar and syntax is inspired by the PEG.js project, while the implementation is loosely based on the parsing expression grammar for C# 3.0 article. It parses Unicode text encoded in UTF-8.

See the godoc page for detailed usage. Also have a look at the Pigeon Wiki for additional information about Pigeon and PEG in general.

Releases

  • v1.0.0 is the tagged release of the original implementation.
  • Work has started on v2.0.0 with some planned breaking changes.

Github user @mna created the package in April 2015, and @breml is the package's maintainer as of May 2017.

Breaking Changes since v1.0.0

  • Removed support for Go < v1.7 due to the requirement of the package context in golang.org/x/tools/imports, which was added to the Go stdlib in Go v1.7. This is in compliance with the Go Release Policy respectively the Go Release Maintenance, which states support for each major release until there are two newer major releases.

Installation

Provided you have Go correctly installed with the $GOPATH and $GOBIN environment variables set, run:

$ go get -u github.com/mna/pigeon

This will install or update the package, and the pigeon command will be installed in your $GOBIN directory. Neither this package nor the parsers generated by this command require any third-party dependency, unless such a dependency is used in the code blocks of the grammar.

Basic usage

$ pigeon [options] [PEG_GRAMMAR_FILE]

By default, the input grammar is read from stdin and the generated code is printed to stdout. You may save it in a file using the -o flag.

Example

Given the following grammar:

{
// part of the initializer code block omitted for brevity

var ops = map[string]func(int, int) int {
    "+": func(l, r int) int {
        return l + r
    },
    "-": func(l, r int) int {
        return l - r
    },
    "*": func(l, r int) int {
        return l * r
    },
    "/": func(l, r int) int {
        return l / r
    },
}

func toIfaceSlice(v interface{}) []interface{} {
    if v == nil {
        return nil
    }
    return v.([]interface{})
}

func eval(first, rest interface{}) int {
    l := first.(int)
    restSl := toIfaceSlice(rest)
    for _, v := range restSl {
        restExpr := toIfaceSlice(v)
        r := restExpr[3].(int)
        op := restExpr[1].(string)
        l = ops[op](l, r)
    }
    return l
}
}


Input <- expr:Expr EOF {
    return expr, nil
}

Expr <- _ first:Term rest:( _ AddOp _ Term )* _ {
    return eval(first, rest), nil
}

Term <- first:Factor rest:( _ MulOp _ Factor )* {
    return eval(first, rest), nil
}

Factor <- '(' expr:Expr ')' {
    return expr, nil
} / integer:Integer {
    return integer, nil
}

AddOp <- ( '+' / '-' ) {
    return string(c.text), nil
}

MulOp <- ( '*' / '/' ) {
    return string(c.text), nil
}

Integer <- '-'? [0-9]+ {
    return strconv.Atoi(string(c.text))
}

_ "whitespace" <- [ \n\t\r]*

EOF <- !.

The generated parser can parse simple arithmetic operations, e.g.:

18 + 3 - 27 * (-18 / -3)

=> -141

More examples can be found in the examples/ subdirectory.

See the godoc page for detailed usage.

Contributing

See the CONTRIBUTING.md file.

License

The BSD 3-Clause license. See the LICENSE file.