Pigeon
Command pigeon generates parsers in Go from a PEG grammar.
Install / Use
/learn @mna/PigeonREADME
pigeon - a PEG parser generator for Go
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.
Release policy
Starting of June 2023, the backwards compatibility support for pigeon is changed to follow the official Go Security Policy.
Over time, the Go ecosystem is evolving.
On one hand side, packages like golang.org/x/tools, which are critical dependencies of pigeon, do follow the official Security Policy and with pigeon not following the same guidelines, it was no longer possible to include recent versions of these dependencies and with this it was no longer possible to include critical bugfixes.
On the other hand there are changes to what is considered good practice by the greater community (e.g. change from interface{} to any). For users following (or even enforcing) these good practices, the code generated by pigeon does no longer meet the bar of expectations.
Last but not least, following the Go Security Policy over the last years has been a smooth experience and therefore updating Go on a regular basis feels like duty that is reasonable to be put on users of pigeon.
These observations lead to the decision to follow the same Security Policy as Go.
Installation
go install github.com/mna/pigeon@latest
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 toAnySlice(v any) []any {
if v == nil {
return nil
}
return v.([]any)
}
func eval(first, rest any) int {
l := first.(int)
restSl := toAnySlice(rest)
for _, v := range restSl {
restExpr := toAnySlice(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 package documentation for detailed usage.
Contributing
See the CONTRIBUTING.md file.
License
The BSD 3-Clause license. See the LICENSE file.
Related Skills
node-connect
339.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.9kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
339.3kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
83.9kCommit, push, and open a PR
