PEGO

Ready-made parsers

Parsers for common languages, written in PEGO and generated into Go with pego gen. Each is a Go module of its own that depends only on the standard library: import it and parse, with nothing to generate or compile at run time.

Language Module Specification Checked against
CEL github.com/ornew/pego/parsers/cel The CEL language definition, as cel-go parses it All 2,527 conformance tests of cel-spec; cel-go v0.32.0 (trees, offsets and literal values on 32,794 vendored expressions; fuzz tests)
CSV github.com/ornew/pego/parsers/csv RFC 4180, with the leniencies of encoding/csv 73 edge cases, encoding/csv (differential and fuzz tests)
CUE github.com/ornew/pego/parsers/cue The CUE Language Specification, as cue/parser v0.17.1 parses it cue/parser: 4,061 sources of the CUE repository, 32,488 mutants, 15,000 generated inputs and 4,126 literals (trees, offsets and comments; no difference); fuzz tests
DuckDB SQL github.com/ornew/pego/parsers/duckdb DuckDB 1.5.6's SQL dialect DuckDB 1.5.6 on 158,605 texts (acceptance, statement splitting and the AST of SELECT statements; 13 known deviations)
Go github.com/ornew/pego/parsers/golang The Go Programming Language Specification (go1.27), as go/parser parses it; ParseFile returns go/ast go/parser: every file of GOROOT/src (whole trees, positions included), the programs embedded in its tests, mutations and fuzz tests (no difference)
JSON github.com/ornew/pego/parsers/json RFC 8259 JSONTestSuite (every y_ and n_ case), encoding/json (differential and fuzz tests)
Python github.com/ornew/pego/parsers/python Python 3.14, as CPython 3.14.0 parses it CPython's ast.dump, positions included, on the standard library, Lib/test and its 61,540 code snippets (no difference); mutation and fuzz tests
TypeScript github.com/ornew/pego/parsers/typescript TypeScript 5.9 and TSX, as the TypeScript 5.9.3 compiler parses them The compiler's trees on its own test cases (14,799 of 14,804 files agree), its lib declaration files and mutated sources
XML github.com/ornew/pego/parsers/xml XML 1.0 (Fifth Edition), non-validating, with Namespaces in XML 1.0 W3C XML Conformance Test Suite (no failure among the XML 1.0 tests that need no external entity), encoding/xml (differential and fuzz tests)
YAML github.com/ornew/pego/parsers/yaml YAML 1.2.2, with the core schema for Go values yaml-test-suite (all 402 tests: events and JSON values)
go get github.com/ornew/pego/parsers/json
import "github.com/ornew/pego/parsers/json"

v, err := json.Decode(`{"name": "pego", "tags": ["peg", "pratt"]}`) // map[string]any{...}
ast, err := json.ParseAST(src)                                      // typed values with positions

Every parser has the API of a parser generated with pego gen -types -recognize (see code generation), plus functions written for its language:

ParseAST(input, unit...) The document as the Go types the grammar declares, each with its Span in the input
Parse(input, unit...) The document as a tree of *Node, as the engine returns it
Recognize(input, unit...) Only checks the input, without building anything
*SyntaxError The position (Line, Col, Pos) and the expected tokens of a syntax error

Positions are in code points by default; pass Bytes for byte offsets.

Layout

Each directory holds:

File Contents
<language>.pego The grammar. It can be used with the engine too (pego.CompileSource), for streaming, incremental parsing or the pego tools.
parser.go The parser generated from the grammar. Do not edit it.
other .go files Code written for the language: documentation, conversions to Go values, helpers
*_test.go Tests against the language's specification, conformance suites and reference implementations; examples; benchmarks
testdata/*.txt, *.golden Inputs and the expected trees and errors, checked on the generated parser here and on every backend of the engine by parsers_test.go
go.mod, LICENCE The module

Development

go generate ./parsers                 # regenerate every parser.go (after changing a grammar or the generator)
go test ./parsers                     # parser.go up to date; golden files on every backend of the engine
go test ./parsers -update             # rewrite the golden files from the engine
parsers/test.sh                       # both, and the tests of every module
cd parsers/json && go test ./...      # the tests of one module

The generated parser.go declares unexported names of its runtime (such as parse, parser and rule) in the package, so hand-written code must avoid them.

The generation commands are the go:generate lines of generate.go; the up-to-date test reads them, so a new parser needs only a new line there. The modules are not part of the main module's go test ./...: run parsers/test.sh after changing the engine or the generator.