pigeon

命令 pigeon 从 PEG 语法中生成 Go 中的解析器。(Command pigeon generates parsers in Go from a PEG grammar.)

Github星跟踪图

pigeon -- Go 的 PEG 解析器生成器

pigeon 命令基于 解析表达式语法(PEG) 生成解析器。它的语法和语法受到 PEG.js 项目 的启发,而实现则松散地基于 C# 3.0 的解析表达式语法 文章。它解析以 UTF-8 编码的 Unicode 文本。

有关详细用法,请参阅 godoc 页面。另外,请查看 Pigeon Wiki,了解有关 Pigeon 和 PEG 的更多信息。

发布

  • v1.0.0 是原始实现的标记版本。
  • 已经开始在 v2.0.0 上进行一些计划中的重大更改。

Github 用户 @mna 于2015年4月创建了该软件包,@breml 是该软件包的维护者,截至2017年5月。

自 v1.0.0 以来的重大变化

由于 golang.org/x/tools/imports 的要求,删除了对 Go < v1.9 的支持,该更新是为了反映最近版本 go 的变化。这分别符合 Go Release MaintenanceGo Release Policy ,后者声明支持每个主要版本,直到有两个较新的主要版本。

安装

如果正确安装了 $GOPATH 和 $GOBIN 环境变量集,那么运行

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

这将安装或更新包,并且 pigeon 命令将安装在 $GOBIN 目录中。这个包和这个命令生成的解析器都不需要任何第三方依赖项,除非在语法的代码块中使用这种依赖项。

基本用法

$ pigeon [选项] [PEG_GRAMMAR_FILE]

默认情况下,从stdin读取输入语法,并将生成的代码打印到stdout。 您可以使用-o标志将其保存在文件中。

示例

给定以下语法:

{
// 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 <- !.

生成的解析器可以解析简单的算术运算,例如:

18 + 3 - 27 * (-18 / -3)
=> -141

可以在 examples/ 子目录中找到更多示例。

有关详细用法,请参阅 godoc 页面

贡献

请参阅CONTRIBUTING.md文件。

许可

BSD 3-Clause license 许可。 请参阅 LICENSE 文件。

(First edition: vz edited at 2019.08.25)

主要指标

概览
名称与所有者mna/pigeon
主编程语言Go
编程语言Go (语言数: 3)
平台Linux, Mac, Windows
许可证BSD 3-Clause "New" or "Revised" License
所有者活动
创建于2015-04-05 14:55:20
推送于2025-07-15 19:39:41
最后一次提交2025-07-15 21:39:34
发布数5
最新版本名称v1.3.0 (发布于 )
第一版名称v1.0.0 (发布于 )
用户参与
星数878
关注者数14
派生数68
提交数304
已启用问题?
问题数71
打开的问题数19
拉请求数89
打开的拉请求数4
关闭的拉请求数11
项目设置
已启用Wiki?
已存档?
是复刻?
已锁定?
是镜像?
是私有?

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.11 to support go modules for dependency tracking.

  • Removed support for Go < v1.9 due to the requirement golang.org/x/tools/imports, which was updated to reflect changes in recent versions of Go. 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.