PEGO

Package pego/grammar

import "github.com/ornew/pego/grammar"

Overview

Package grammar defines the abstract syntax tree (AST) of PEGO grammars.

A grammar file (File) is a package clause and a list of declarations (Decl): type definitions (TypeDef), type aliases (TypeAlias), variable definitions (VarDef) and rule definitions (RuleDef). A rule body is a parser expression (Expr), and actions and predicates are value expressions (Term).

Index

Constants

const (
	Prefix  = "prefix"
	Postfix = "postfix"
	Infix   = "infix"
)

Kinds of operators.

const (
	AssocLeft  = "left"
	AssocRight = "right"
	AssocNone  = "none"
)

Associativities.

Functions

func Format source

func Format(g *Grammar) string

Format converts g to PEGO source code.

Comments and line breaks recorded in the AST (see LineBreak) are kept, so formatting parsed source preserves its comments. Struct field types and trailing comments on consecutive lines are aligned. A grammar without such layout information (for example, one decoded from JSON) is printed with a blank line between definitions and one item per line in blocks.

func FormatContext source

func FormatContext(ctx context.Context, g *Grammar) (result string, err error)

FormatContext is Format with cooperative cancellation during AST traversal, layout processing and output construction. Cancellation returns an empty string and ctx.Err(), never partial formatted source. The caller must not mutate g during formatting. Individual allocations, concatenations and comparisons may finish before cancellation is observed.

func FormatExpr source

func FormatExpr(e Expr) string

FormatExpr returns the parser expression e in PEGO syntax.

func FormatExprContext source

func FormatExprContext(ctx context.Context, e Expr) (result string, err error)

FormatExprContext is FormatExpr with the same cancellation contract as FormatContext. The caller must not mutate e during formatting.

func FormatSyntax source

func FormatSyntax(g *Grammar) string

FormatSyntax renders the parsing syntax of g without modifying it. It omits type declarations, result annotations, Value Actions (including inline and Operators Rule actions), captures, metadata attributes and recovery wrappers. Redundant groups are removed; precedence and source layout retain necessary parentheses. Predicate Actions, matching operators and other pragmas remain.

This is a documentation view, not an equivalent replacement parser: a predicate may depend on an omitted capture, action or type. Recovery diagnostics and returned values are intentionally not preserved. Comments on retained source forms follow Format's layout rules; comments attached only to removed forms may be omitted.

func FormatTerm source

func FormatTerm(t Term) string

FormatTerm returns the value expression t in PEGO syntax.

func FormatTermContext source

func FormatTermContext(ctx context.Context, t Term) (result string, err error)

FormatTermContext is FormatTerm with the same cancellation contract as FormatContext. The caller must not mutate t during formatting.

func FormatType source

func FormatType(t TypeExpr) string

FormatType returns t in PEGO syntax.

func FormatTypeContext source

func FormatTypeContext(ctx context.Context, t TypeExpr) (result string, err error)

FormatTypeContext is FormatType with the same cancellation contract as FormatContext. The caller must not mutate t during formatting.

func MarshalJSON source

func MarshalJSON(g *Grammar) ([]byte, error)

MarshalJSON converts g to JSON.

func RuleOperators source

func RuleOperators(e Expr) (*OperatorsRule, *Attributed)

RuleOperators returns the Operators Rule that e is, or that e holds when the pragma #ignorecase follows its block. It returns nil for any other expression. The Attributed that carries the pragma is returned beside it, or nil.

func Validate source

func Validate(g *Grammar) error

Validate checks required children, nonnegative positional references, repetition and character-range bounds, and pointer cycles without mutating g. It returns the first *ValidationError in deterministic depth-first order, checking a node's bounds before its children, or nil.

Optional children may be nil, but an interface containing a nil pointer is invalid. Shared subtrees are allowed. Empty collections and any negative Repeat.Max retain their existing meanings. Source layout is not checked. Name resolution, types, attributes and OperatorsRule semantics are checked by the compiler. Validation does not impose a size or depth limit.

func ValidateContext source

func ValidateContext(ctx context.Context, g *Grammar) (err error)

ValidateContext checks the same grammar invariants as Validate, but stops without returning partial diagnostics when ctx is cancelled. It polls while traversing the AST; individual string checks and sorting are not interruptible.

Types

type And source

type And struct {
	SourceInfo `json:"source,omitempty"`
	Expr       Expr `json:"expr"`
}

And is a positive lookahead &a.

type Any source

type Any struct {
	SourceInfo `json:"source,omitempty"`
}

Any matches any single character (.).

type Atomic source

type Atomic struct {
	SourceInfo `json:"source,omitempty"`
	Expr       Expr       `json:"expr"`
	Break      *LineBreak `json:"-"`
}

Atomic is an atomic expression a #atomic.

type Attribute source

type Attribute struct {
	SourceInfo `json:"source,omitempty"`
	Name       string `json:"name"`
	// Pragma distinguishes behavioral # directives from @ attributes.
	Pragma bool           `json:"pragma,omitempty"`
	Args   []any          `json:"args,omitempty"`
	KwArgs map[string]any `json:"kwArgs,omitempty"`
	// KeywordOrder preserves source order; JSON grammars format keys sorted.
	KeywordOrder []string `json:"-"`
	// TrailingComma records a comma after the last argument. Format puts the
	// arguments on separate lines when it is set.
	TrailingComma bool `json:"-"`
	// ArgsLayout keeps the comments around the arguments in source order,
	// positional ones first. Its Elems match Args and then KeywordOrder by
	// index. They go stale if Args or KwArgs are edited without it: Format
	// writes all the comments after the opening parenthesis when the number of
	// arguments differs, and otherwise keeps each comment with the argument at
	// its index.
	ArgsLayout *ListLayout `json:"-"`
}

Attribute is a postfix attribute @name(positional, keyword=value, ...). Argument values are int, string, bool, nil, or parser expressions. An empty argument is written nil.

func (*Attribute) Arg source

func (a *Attribute) Arg(name string) (Expr, bool)

Arg returns the argument named name.

func (*Attribute) ExpressionArgs source

func (a *Attribute) ExpressionArgs() []Expr

ExpressionArgs returns the parser-expression arguments. Scalar and omitted positional arguments are not parser expressions.

func (*Attribute) ExpressionArgsContext source

func (a *Attribute) ExpressionArgsContext(ctx context.Context) (result []Expr, err error)

ExpressionArgsContext is ExpressionArgs with cooperative cancellation during argument collection and keyword sorting. It returns no partial slice on cancellation. The caller must not mutate a during collection.

type Attributed source

type Attributed struct {
	SourceInfo `json:"source,omitempty"`
	Expr       Expr         `json:"expr"`
	Attrs      []*Attribute `json:"attrs"`

	// Breaks[i], when not nil, puts Attrs[i] on a new line. Format honors
	// it only in the items of the top-level sequences of a rule body.
	Breaks []*LineBreak `json:"-"`
}

Attributed is an expression with postfix @ attributes and # pragmas.

type BeginInput source

type BeginInput struct {
	SourceInfo `json:"source,omitempty"`
}

BeginInput matches the beginning of the input (^^).

type BeginLine source

type BeginLine struct {
	SourceInfo `json:"source,omitempty"`
}

BeginLine matches the beginning of a line (^).

type Binary source

type Binary struct {
	SourceInfo `json:"source,omitempty"`
	Op         string     `json:"op"`
	L          Term       `json:"l"`
	R          Term       `json:"r"`
	OpenBreak  *LineBreak `json:"-"`
	BodyBreak  *LineBreak `json:"-"`
	CloseBreak *LineBreak `json:"-"`
}

Binary is a binary operation l op r. The operator "[]" is indexing, l[r], which keeps the layout of its brackets like a TermGroup keeps that of its parentheses.

type Bind source

type Bind struct {
	SourceInfo `json:"source,omitempty"`
	Name       string `json:"name"`
	Value      Term   `json:"value"`
}

Bind binds a variable in a predicate action: name := value.

type Block source

type Block struct {
	SourceInfo `json:"source,omitempty"`
	Statements []Term       `json:"statements"`
	OpenBreak  *LineBreak   `json:"-"`
	Breaks     []*LineBreak `json:"-"`
	CloseBreak *LineBreak   `json:"-"`
	OneLine    bool         `json:"-"`
}

Block is a braced action statement list. Nonempty predicate blocks lower to adjacent predicate actions. Value-action and empty predicate blocks remain unsupported by compilation. Single-statement predicate actions use Predicate.Term directly.

type BoolLit source

type BoolLit struct {
	SourceInfo `json:"source,omitempty"`
	Value      bool `json:"value"`
}

BoolLit is a boolean literal, true or false.

type Bottom source

type Bottom struct {
	SourceInfo `json:"source,omitempty"`
}

Bottom is the bottom expression _|_.

type Call source

type Call struct {
	SourceInfo `json:"source,omitempty"`
	Func       string `json:"func"`
	Args       []Term `json:"args"`

	// The parentheses keep their comments like a TupleLit's.
	OpenBreak  *LineBreak `json:"-"`
	BodyBreak  *LineBreak `json:"-"`
	CloseBreak *LineBreak `json:"-"`
	// TrailingComma records a comma after the last argument. Format puts the
	// arguments on separate lines when it is set.
	TrailingComma bool `json:"-"`
}

Call is a call of a built-in function f(args...).

type Capture source

type Capture struct {
	SourceInfo `json:"source,omitempty"`
	Name       string `json:"name"`
	Expr       Expr   `json:"expr"`
}

Capture is a capture name:a.

type CaptureRef source

type CaptureRef struct {
	SourceInfo `json:"source,omitempty"`
	Name       string `json:"name"`
	// Param marks a reference to a lambda parameter, which is written without $.
	Param bool `json:"param,omitempty"`
	// Pragma distinguishes behavioral # directives from @ attributes.
	Pragma bool `json:"pragma,omitempty"`
}

CaptureRef is a reference $name to a capture, or name to a lambda parameter.

type Cast source

type Cast struct {
	SourceInfo `json:"source,omitempty"`
	X          Term     `json:"x"`
	Type       TypeExpr `json:"type"`
}

Cast is a type assertion x.(Type): its value is x, which must be a Type.

type CharClass source

type CharClass struct {
	SourceInfo `json:"source,omitempty"`
	Ranges     []CharRange `json:"ranges"`
	Negated    bool        `json:"negated,omitempty"`
}

CharClass is a character class [...], or [^...] if Negated is set.

type CharRange source

type CharRange struct {
	Lo rune `json:"lo"`
	Hi rune `json:"hi"`
}

CharRange is a character range [Lo, Hi]. Both endpoints must be Unicode scalar values and Lo must not exceed Hi.

type Choice source

type Choice struct {
	SourceInfo `json:"source,omitempty"`
	Alts       []Expr `json:"alts"`

	// Breaks[i], when not nil, puts Alts[i] (with its "/") on a new line.
	// Format honors it only in the top-level choice of a rule body.
	Breaks []*LineBreak `json:"-"`
}

Choice is an ordered choice a / b.

type Comment source

type Comment struct {
	// Header identifies a statement header that illegally contains this comment.
	Header Pos
	Pos    Pos
	// End is the source position just after the comment.
	End Pos
	// Text includes delimiters. Line comments exclude their final line
	// break and trailing white space; block comments preserve their contents.
	Text string
	// Content is marker-free documentation text, including original line
	// endings and whitespace. It is independent of formatter spelling.
	Content string
	// Blank reports whether a blank line precedes the comment.
	Blank bool
	// Run lists the comments that this one stands for when several comments end
	// the same line, with Text and Content holding all of them: the formatter
	// writes them together, as they were. AllComments returns them separately.
	Run []*Comment
}

Comment is a line comment (// ...) or nested block comment (/* ... */).

type Cut source

type Cut struct {
	SourceInfo `json:"source,omitempty"`
}

Cut is a cut --.

type Decl source

type Decl interface {
	// DeclName returns the declared name.
	DeclName() string
	// Diagnostic returns the position of the declaration for diagnostics.
	Diagnostic() Pos
	// contains filtered or unexported methods
}

Decl is a declaration of a file: a type, variable or rule declaration.

type Discard source

type Discard struct {
	SourceInfo `json:"source,omitempty"`
	Expr       Expr `json:"expr"`
}

Discard is a discarded expression -a.

type EndInput source

type EndInput struct {
	SourceInfo `json:"source,omitempty"`
}

EndInput matches the end of the input ($$).

type EndLine source

type EndLine struct {
	SourceInfo `json:"source,omitempty"`
}

EndLine matches the end of a line ($).

type Expr source

type Expr interface {
	// contains filtered or unexported methods
}

Expr is a parser expression.

type Field source

type Field struct {
	SourceInfo `json:"source,omitempty"`
	Name       string `json:"name"`
	// HeaderComments are the normalized contents of the comments between the
	// name and the type, one string per comment as for TypeDef.HeaderComments.
	HeaderComments []string `json:"headerComments,omitempty"`
	Type           TypeExpr `json:"type"`

	Break *LineBreak `json:"-"`
}

Field is a field of a struct type.

type FieldInit source

type FieldInit struct {
	SourceInfo `json:"source,omitempty"`
	Name       string `json:"name"`
	Value      Term   `json:"value"`
}

FieldInit initializes a field of a struct value.

type File source

type File struct {
	SourceInfo `json:"source,omitempty"`
	Pkg        Pkg    `json:"pkg,omitempty"`
	Decls      []Decl `json:"decls"`

	// EndBreak holds the comments at the end of the file (see LineBreak).
	EndBreak *LineBreak `json:"-"`
	// HeaderComments records source comments inside declaration headers.
	// Parsing accepts them as trivia; compilation rejects their placement.
	HeaderComments []*Comment `json:"-"`
}

File is a grammar file: a package clause and a list of declarations.

type Gap source

type Gap struct {
	Comments     []*Comment
	PreviousLine int
	NextLine     int
}

Gap holds the comments between two tokens of an expression inside delimiters, where a comment may stand on a line of its own. PreviousLine is the line the token before ends on, NextLine the line the token after starts on, and the comments keep their lines, so the formatter writes a comment on the same line as a token, or on a line of its own, as in the source, and a comment never changes what it belongs to.

type Grammar source

type Grammar struct {
	File File `json:"file"`
}

Grammar is a whole grammar. It is made of one file.

func DecodeJSON source

func DecodeJSON(data []byte) (*Grammar, error)

DecodeJSON decodes one complete grammar JSON value, rejects unknown fields and duplicate object keys, and validates the resulting AST. UnmarshalJSON retains its existing permissive behavior.

func UnmarshalJSON source

func UnmarshalJSON(data []byte) (*Grammar, error)

UnmarshalJSON decodes a grammar from JSON. It requires one complete JSON value and checks structural validity with Validate. Unknown fields and duplicate object keys retain encoding/json's permissive behavior; compilation still performs semantic checks.

func (*Grammar) AllComments source

func (g *Grammar) AllComments() []*Comment

AllComments returns every comment kept in g, in no particular order.

func (*Grammar) AllCommentsContext source

func (g *Grammar) AllCommentsContext(ctx context.Context) (result []*Comment, err error)

AllCommentsContext is AllComments with cooperative cancellation through the grammar, comment copies and attribute arguments. It returns no partial slice on cancellation. Individual allocations and string comparisons may not stop immediately. The caller must not mutate g during collection.

func (*Grammar) Clone source

func (g *Grammar) Clone() *Grammar

Clone returns an independent copy of g, including source metadata and raw formatter trivia. Shared AST children stay shared within the copy. It does not validate the grammar; pointer cycles are preserved for Validate to report. Values must use the supported AST types and attribute argument types. Arbitrary application objects and cyclic attribute maps or slices are not supported.

func (*Grammar) Rules source

func (g *Grammar) Rules() []*RuleDef

Rules returns the rule declarations of the grammar in declaration order.

func (*Grammar) RulesContext source

func (g *Grammar) RulesContext(ctx context.Context) (result []*RuleDef, err error)

RulesContext is Rules with cooperative cancellation. It returns no partial slice on cancellation. The caller must not mutate g during collection.

func (*Grammar) Types source

func (g *Grammar) Types() []TypeDecl

Types returns the type declarations of the grammar in declaration order.

func (*Grammar) TypesContext source

func (g *Grammar) TypesContext(ctx context.Context) (result []TypeDecl, err error)

TypesContext is Types with the same cancellation contract as RulesContext.

func (*Grammar) Vars source

func (g *Grammar) Vars() []*VarDef

Vars returns the variable definitions of the grammar in declaration order.

type Group source

type Group struct {
	SourceInfo `json:"source,omitempty"`
	Expr       Expr       `json:"expr"`
	BodyBreak  *LineBreak `json:"-"`
	CloseBreak *LineBreak `json:"-"`
	OneLine    bool       `json:"-"`
}

Group preserves explicit parentheses and their source layout. It is transparent to matching and value construction.

type IndexRef source

type IndexRef struct {
	SourceInfo `json:"source,omitempty"`
	Index      int `json:"index"`
}

IndexRef is a positional reference $n. $0 is the list of all elements.

type InlineAction source

type InlineAction struct {
	SourceInfo    `json:"source,omitempty"`
	Expr          Expr `json:"expr"`
	Action        Term `json:"action,omitempty"`
	DefaultAction bool `json:"defaultAction,omitempty"`
}

InlineAction maps an expression's value inside a parenthesized grammar expression. Parsing and formatting are supported; compilation is not yet implemented. DefaultAction denotes an explicit => ... instead of Action.

type IntLit source

type IntLit struct {
	SourceInfo `json:"source,omitempty"`
	Value      int `json:"value"`
}

IntLit is an integer literal.

type JSONDecodeError source

type JSONDecodeError struct {
	Path   string
	Offset int
	Msg    string
	Cause  error
}

JSONDecodeError describes a strict grammar JSON intake error. Offset is a zero-based byte offset into the input. For duplicate and unknown keys it points to the offending key token; syntax errors retain their encoding/json cause through Unwrap.

func (*JSONDecodeError) Error source

func (e *JSONDecodeError) Error() string

func (*JSONDecodeError) Unwrap source

func (e *JSONDecodeError) Unwrap() error

Unwrap returns the underlying JSON syntax error, if any.

type JoinType source

type JoinType struct {
	SourceInfo `json:"source,omitempty"`
	Types      []TypeExpr `json:"types"`
}

JoinType is the join T | U of types: the type of the values of any of them.

type Lambda source

type Lambda struct {
	SourceInfo `json:"source,omitempty"`
	Params     []string `json:"params"`
	Body       Term     `json:"body"`

	// TrailingComma records a comma after the last parameter. Format puts the
	// parameters on separate lines when it is set.
	TrailingComma bool `json:"-"`
	// ParamsLayout keeps the comments around the parameters.
	ParamsLayout *ListLayout `json:"-"`
}

Lambda is a function (a, b) => body.

type LineBreak source

type LineBreak struct {
	// Comments are the comments on their own lines before the node, in
	// source order. Comments that Format cannot keep in place, because it
	// joins the lines they end, are added to the nearest preceding
	// LineBreak.
	Comments []*Comment
	// Blank reports whether a blank line directly precedes the node.
	Blank bool
	// Trailing is the comment at the end of the line that starts with the
	// node, if any. When several comments end the line, it stands for all of
	// them (see Comment.Run).
	Trailing *Comment
	// TrailingEnds reports whether a line break follows Trailing in the source
	// before the next token, rather than that token following it on the same
	// line. A block comment that ends its line cannot move to the line of the
	// token after it without changing which node owns it.
	TrailingEnds bool
	// Last is the comment on the line of the last token before the closing
	// parenthesis of a group, which trails that token: Trailing, of the break
	// before a ")", is the comment after the ")".
	Last *Comment
}

LineBreak describes the start of a line in PEGO source: the comments before it and the comment at its end.

type ListConstructor source

type ListConstructor struct {
	SourceInfo `json:"source,omitempty"`
	Elem       TypeExpr `json:"elem"`
	Items      []Term   `json:"items"`

	// The braces keep their comments like a TupleLit's parentheses.
	OpenBreak  *LineBreak `json:"-"`
	BodyBreak  *LineBreak `json:"-"`
	CloseBreak *LineBreak `json:"-"`
	// TrailingComma records a comma after the last item. Format puts the
	// items on separate lines when it is set.
	TrailingComma bool `json:"-"`
}

ListConstructor builds a node list with an explicit element type: []T{...}.

type ListLayout source

type ListLayout struct {
	OpenBreak  *LineBreak
	BodyBreak  *LineBreak
	CloseBreak *LineBreak
	Elems      []*SourceLayout
}

ListLayout keeps the comments of a parenthesized list whose elements are not nodes of their own, such as the arguments of an attribute and the parameters of a lambda. The parentheses keep their comments like those of a TupleType, and Elems[i] holds the comments around the i-th element, which may be nil.

type ListType source

type ListType struct {
	SourceInfo `json:"source,omitempty"`
	Elem       TypeExpr `json:"elem"`
}

ListType is a list type []T.

type Literal source

type Literal struct {
	SourceInfo `json:"source,omitempty"`
	Value      string `json:"value"`
	IgnoreCase bool   `json:"ignoreCase,omitempty"`
}

Literal is a string literal "...". Matching uses its decoded rune sequence: malformed UTF-8 bytes become U+FFFD in both position units. Compilation and generation derive matching data without changing Value.

IgnoreCase is set by the suffix i ("..."i): the ASCII letters of the literal match either case. The #ignorecase pragma sets it on the literals of its expression when the grammar is normalized; the source keeps the pragma.

type MeetType source

type MeetType struct {
	SourceInfo `json:"source,omitempty"`
	Types      []TypeExpr `json:"types"`
}

MeetType is the meet T & U of types: the type of the values in all of them.

type Member source

type Member struct {
	SourceInfo `json:"source,omitempty"`
	X          Term   `json:"x"`
	Name       string `json:"name"`
}

Member is a field reference x.Name, or, when Name is "$" and a capture name, the capture access x.$y, which reads capture y of the node x.

type New source

type New struct {
	SourceInfo `json:"source,omitempty"`
	Type       string       `json:"type"`
	Fields     []*FieldInit `json:"fields,omitempty"`
	Args       []Term       `json:"args,omitempty"`

	// The braces keep their comments like a TupleLit's parentheses.
	OpenBreak  *LineBreak `json:"-"`
	BodyBreak  *LineBreak `json:"-"`
	CloseBreak *LineBreak `json:"-"`
	// TrailingComma records a comma after the last element. Format puts the
	// elements on separate lines when it is set.
	TrailingComma bool `json:"-"`
}

New creates a value of a defined type. A struct constructor names its fields: Type{Field: value, ...}. A node type constructor takes one positional value, Type{value}, held in Args. A constructor uses Fields or Args, never both.

type NilLit source

type NilLit struct {
	SourceInfo `json:"source,omitempty"`
}

NilLit is the empty value nil.

type Not source

type Not struct {
	SourceInfo `json:"source,omitempty"`
	Expr       Expr `json:"expr"`
}

Not is a negative lookahead !a.

type OperatorsRule source

type OperatorsRule struct {
	SourceInfo `json:"source,omitempty"`
	Skip       Expr                    `json:"skip,omitempty"`
	SkipSource SourceInfo              `json:"skipSource,omitempty"`
	Operands   []*OperatorsRuleOperand `json:"operands"`
	Levels     []*OperatorsRuleLevel   `json:"levels"`

	// SkipBreak holds the comments before the skip line, and CloseBreak
	// those before the closing brace.
	SkipBreak  *LineBreak `json:"-"`
	CloseBreak *LineBreak `json:"-"`
}

OperatorsRule is the body of an operators rule declaration. It may appear only at the top level of a rule body.

type OperatorsRuleLevel source

type OperatorsRuleLevel struct {
	SourceInfo `json:"source,omitempty"`
	Name       string                   `json:"name,omitempty"`
	Operators  []*OperatorsRuleOperator `json:"operators"`

	Break *LineBreak `json:"-"`
	// OneLine writes the level on one line ("level { infix left "+" }").
	OneLine bool `json:"-"`
	// CloseBreak holds the comments before the closing brace.
	CloseBreak *LineBreak `json:"-"`
}

OperatorsRuleLevel is a precedence level. Levels declared earlier bind more loosely.

type OperatorsRuleOperand source

type OperatorsRuleOperand struct {
	SourceInfo    `json:"source,omitempty"`
	Expr          Expr `json:"expr"`
	Action        Term `json:"action,omitempty"`
	DefaultAction bool `json:"defaultAction,omitempty"`

	Break *LineBreak `json:"-"`
}

OperatorsRuleOperand is an operand line.

type OperatorsRuleOperator source

type OperatorsRuleOperator struct {
	SourceInfo    `json:"source,omitempty"`
	Kind          string `json:"kind"`
	Assoc         string `json:"assoc,omitempty"`
	Expr          Expr   `json:"expr"`
	Action        Term   `json:"action,omitempty"`
	DefaultAction bool   `json:"defaultAction,omitempty"`

	Break *LineBreak `json:"-"`
}

OperatorsRuleOperator is a declaration of an operator.

type Optional source

type Optional struct {
	SourceInfo `json:"source,omitempty"`
	Expr       Expr `json:"expr"`
}

Optional is an optional expression a?. Its value is the value of a, or nil. Pos is the position where a begins, as in Repeat.

type OptionalType source

type OptionalType struct {
	SourceInfo `json:"source,omitempty"`
	Elem       TypeExpr `json:"elem"`
}

OptionalType is an optional type *T.

type Pkg source

type Pkg struct {
	SourceInfo `json:"source,omitempty"`
	Name       string `json:"name,omitempty"`

	// HeaderComments are the normalized contents of the comments inside the
	// declaration header, between the keyword and the end of the header, in
	// source order: one string per comment, a line comment ending in a line
	// break. Format writes them after the keyword.
	HeaderComments []string `json:"headerComments,omitempty"`

	// Break holds the comments before the package clause (see LineBreak).
	Break *LineBreak `json:"-"`
}

Pkg is the package clause (package Name). A file without one has the zero Pkg.

type Pos source

type Pos struct {
	Line int `json:"line"`
	Col  int `json:"col"`
}

Pos is a 1-based position in the source. The zero value means that the position is unknown.

func (Pos) IsValid source

func (p Pos) IsValid() bool

IsValid reports whether the position is known.

type Predicate source

type Predicate struct {
	SourceInfo `json:"source,omitempty"`
	Term       Term         `json:"term"`
	OpenBreak  *LineBreak   `json:"-"`
	Breaks     []*LineBreak `json:"-"`
	CloseBreak *LineBreak   `json:"-"`
	OneLine    bool         `json:"-"`
}

Predicate is a predicate action { Term }. A nonempty Block lowers to adjacent predicate actions in a sequence, or their grouped sequence in a single expression position, without a new variable or capture scope.

type Recovery source

type Recovery struct {
	SourceInfo `json:"source,omitempty"`
	Expr       Expr       `json:"expr"`
	Skip       Expr       `json:"skip"`
	Break      *LineBreak `json:"-"`
}

Recovery runs Skip when Expr fails, preserving the existing recovery semantics.

type Ref source

type Ref struct {
	SourceInfo `json:"source,omitempty"`
	Name       string `json:"name"`
	Level      string `json:"level,omitempty"`
}

Ref is a call of a rule. If Level is set, the call parses only with that level of the Operators Rule and the levels above it.

type Repeat source

type Repeat struct {
	SourceInfo  `json:"source,omitempty"`
	Expr        Expr       `json:"expr"`
	Min         int        `json:"min"`
	Max         int        `json:"max"`
	PragmaBreak *LineBreak `json:"-"`

	// Spelling holds the comments between the tokens of the pragma
	// #repeat(...). It is nil for a repetition written * or +, or built by
	// code. Format writes the bounds in the canonical spelling and the comments
	// in it; they are layout only.
	Spelling *RepeatSpelling `json:"-"`
}

Repeat is a repetition a #repeat(Min,Max). A negative Max means no upper bound. a* is #repeat(0,) and a+ is #repeat(1,).

Pos is the position where the repeated expression begins (its opening parenthesis, if it is parenthesized).

type RepeatGap source

type RepeatGap struct {
	Comments []*Comment
	// PrevLine and NextLine are the lines of the tokens around the gap.
	PrevLine, NextLine int
}

RepeatGap is the space between two tokens of a #repeat pragma.

type RepeatSpelling source

type RepeatSpelling struct {
	HasMin, Comma, HasMax bool
	// Gaps holds the comments between the tokens: Gaps[0] follows the opening
	// parenthesis and the last gap precedes the closing one, so there is one
	// more gap than there are tokens.
	Gaps []RepeatGap
}

RepeatSpelling is the layout of a #repeat pragma: which of its tokens the source had, and the comments between them. The comma of #repeat is part of its syntax, not a list separator: #repeat(n) is exactly n, #repeat(n,) at least n, #repeat(,m) at most m and #repeat(n, m) from n to m.

The tokens between the parentheses are, in order, the minimum if HasMin, the comma if Comma, and the maximum if HasMax. Format does not keep them: it writes the canonical spelling of Min and Max, and moves each comment to the token it was before, or to the next token that the canonical spelling has.

type RuleDecl source

type RuleDecl interface {
	Decl
	// contains filtered or unexported methods
}

RuleDecl is a rule declaration: a rule definition.

type RuleDef source

type RuleDef struct {
	SourceInfo `json:"source,omitempty"`
	// Attrs are the declaration attributes, in source order. Pos is the
	// position of the first attribute when there are any; Diagnostic is
	// then the position of "rule".
	Attrs  []*Attribute `json:"attrs,omitempty"`
	Name   string       `json:"name"`
	Type   TypeExpr     `json:"type,omitempty"`
	Expr   Expr         `json:"expr"`
	Action Term         `json:"action,omitempty"`
	// DefaultAction preserves an explicit => ...; it has the same value
	// semantics as an omitted action.
	DefaultAction bool `json:"defaultAction,omitempty"`
	// KeywordComments and KeywordDetachedComments are the normalized leading
	// and detached comments on the lines between the last attribute and
	// "rule", which no source-bearing node starts at. They are as the
	// comments of SourceInfo, and Format writes them when KeywordBreak is nil.
	KeywordComments         string   `json:"keywordComments,omitempty"`
	KeywordDetachedComments []string `json:"keywordDetachedComments,omitempty"`

	// HeaderComments are the normalized contents of the comments inside the
	// declaration header, between the keyword and the end of the header, in
	// source order: one string per comment, a line comment ending in a line
	// break. Format writes them after the keyword.
	HeaderComments []string `json:"headerComments,omitempty"`

	// Break holds the comments before the declaration, as for TypeDef: before
	// its first attribute, if it has any.
	Break *LineBreak `json:"-"`
	// AttrBreaks[i], when not nil, puts Attrs[i] on a new line; otherwise
	// Attrs[i] follows the attribute before it on its line. AttrBreaks[0] is
	// always nil, because the first attribute starts the declaration and the
	// comments and line break before it belong to Break; keeping the slot
	// lets AttrBreaks share the indices of Attrs. AttrBreaks may be shorter
	// than Attrs; missing entries are nil.
	AttrBreaks []*LineBreak `json:"-"`
	// KeywordBreak holds the comments between the last attribute and "rule",
	// which always starts a new line after attributes.
	KeywordBreak *LineBreak `json:"-"`
	// BodyBreak, when not nil, puts the body on a new line after "=", and
	// ActionBreak puts "=>" on a new line.
	BodyBreak   *LineBreak `json:"-"`
	ActionBreak *LineBreak `json:"-"`
	CloseBreak  *LineBreak `json:"-"`
}

RuleDef is a rule definition (rule Name Type = Expr => Action), with the declaration attributes written on the lines before it (@start).

func (*RuleDef) DeclName source

func (d *RuleDef) DeclName() string

type Seq source

type Seq struct {
	SourceInfo `json:"source,omitempty"`
	Items      []Expr `json:"items"`

	// Breaks[i], when not nil, puts Items[i] on a new line. Format honors
	// it only in the top-level sequences of a rule body.
	Breaks []*LineBreak `json:"-"`
}

Seq is a sequence a b.

type SourceInfo source

type SourceInfo struct {
	// Layout preserves raw token-boundary trivia for in-memory formatting.
	// It is separate from normalized documentation and is not serialized.
	Layout                  *SourceLayout `json:"-"`
	Pos                     Pos           `json:"pos,omitempty"`
	End                     Pos           `json:"end,omitempty"`
	LeadingComments         string        `json:"leadingComments,omitempty"`
	TrailingComments        []string      `json:"trailingComments,omitempty"`
	LeadingDetachedComments []string      `json:"leadingDetachedComments,omitempty"`
	// DiagnosticPos identifies a diagnostic token when it differs from Pos,
	// such as an operator inside a binary expression.
	DiagnosticPos Pos `json:"diagnosticPos,omitempty"`
}

SourceInfo holds the syntax span and documentation owned by an AST node. Pos and End are 1-based rune positions; End is exclusive. The span excludes comments outside the node. Zero positions indicate unavailable source data.

Comment strings omit their markers and preserve content and line endings. LeadingDetachedComments contains separate paragraphs before the node. TrailingComments lists the comments at the end of the node's line, one string per comment in source order: every comment on the line of the node's last token, when a line break or the end of a scope follows them, and for a comment-only group after a line break, that group.

Format writes a comment string that ends in a line break as line comments, and any other string as one block comment, with a space before its closing delimiter when the string does not end with white space. A block comment cannot hold "*/", so Format writes "* /" for it in a string that is set by hand, and the comment of parsed source never holds it. Formatter comment tokens and layout are stored separately.

func (SourceInfo) Diagnostic source

func (s SourceInfo) Diagnostic() Pos

Diagnostic returns the diagnostic token position, falling back to Pos.

func (*SourceInfo) Source source

func (s *SourceInfo) Source() *SourceInfo

Source returns mutable source information. Embedding SourceInfo makes this method available on all source-bearing grammar nodes.

type SourceLayout source

type SourceLayout struct {
	Before       []*Comment
	PreviousLine int
	NextLine     int
	// After holds the comments between the node and the comma that follows it
	// in a list of elements, fields or arguments.
	After []*Comment
	// ElemLine is the line the node ends on, and AfterLine the line of that
	// comma.
	ElemLine, AfterLine int
	// Trail holds the comments on the line of that comma after it, when they
	// end the line.
	Trail []*Comment
	// Operator holds the comments between the operand of a postfix rule
	// expression (a repetition, an optional, an #atomic, #stream or #recover
	// pragma) and its operator, all on one line with both.
	Operator []*Comment
	// Open holds the comments between the opening parenthesis of a #recover
	// pragma and "skip", Eq those between "skip" and "=", and Close those
	// before the closing parenthesis.
	Open, Eq, Close *Gap
	// OpGap holds the comments between the left operand of a binary operation
	// and its operator.
	OpGap *Gap
	// Sep holds the comments between an alternative of a choice that stands
	// in a #recover pragma and the "/" before it.
	Sep *Gap
	// Lead holds the comments between the "/" before an alternative, or the
	// "=" after "skip" in a #recover pragma, and the first token of the node.
	Lead *Gap
}

SourceLayout retains spelling and placement without assigning comment owners. A nil value uses ordinary canonical formatting. Positions only distinguish adjacent lines and blank lines; they are not offsets in the formatted output.

type SourceNode source

type SourceNode interface {
	Source() *SourceInfo
}

SourceNode is implemented by source-bearing grammar nodes.

type Stream source

type Stream struct {
	SourceInfo `json:"source,omitempty"`
	Expr       Expr       `json:"expr"`
	Break      *LineBreak `json:"-"`
}

Stream hands repetition elements to the streaming parser's caller.

type StringLit source

type StringLit struct {
	SourceInfo `json:"source,omitempty"`
	Value      string `json:"value"`
}

StringLit is a string literal.

type StructType source

type StructType struct {
	SourceInfo `json:"source,omitempty"`
	Fields     []*Field `json:"fields"`

	OneLine    bool       `json:"-"`
	CloseBreak *LineBreak `json:"-"`
}

StructType is an unnamed struct type written in a type expression: { A T; B U }. Its braces keep their source layout like a struct definition's.

type Term source

type Term interface {
	// contains filtered or unexported methods
}

Term is a value expression used in actions and predicates.

type TermGroup source

type TermGroup struct {
	SourceInfo `json:"source,omitempty"`
	Term       Term       `json:"term"`
	OpenBreak  *LineBreak `json:"-"`
	BodyBreak  *LineBreak `json:"-"`
	CloseBreak *LineBreak `json:"-"`
	OneLine    bool       `json:"-"`
}

TermGroup preserves parentheses and source layout in an action expression. It is transparent to value construction and predicate evaluation.

type Top source

type Top struct {
	SourceInfo `json:"source,omitempty"`
}

Top is the top expression _.

type TupleLit source

type TupleLit struct {
	SourceInfo `json:"source,omitempty"`
	Elems      []Term     `json:"elems"`
	OpenBreak  *LineBreak `json:"-"`
	BodyBreak  *LineBreak `json:"-"`
	CloseBreak *LineBreak `json:"-"`
	// TrailingComma records a comma after the last element. Format puts the
	// elements of a tuple of two or more on separate lines when it is set; the
	// comma of a one-element tuple is part of the syntax and does not count.
	TrailingComma bool `json:"-"`
}

TupleLit is a tuple value: () is the unit, (x,) has one element and (x, y) two. Its parentheses keep their source comments like a TermGroup's.

type TupleType source

type TupleType struct {
	SourceInfo `json:"source,omitempty"`
	Types      []TypeExpr `json:"types"`
	OpenBreak  *LineBreak `json:"-"`
	BodyBreak  *LineBreak `json:"-"`
	CloseBreak *LineBreak `json:"-"`
	// TrailingComma records a comma after the last element. Format puts the
	// elements of a tuple of two or more on separate lines when it is set; the
	// comma of a one-element tuple is part of the syntax and does not count.
	TrailingComma bool `json:"-"`
}

TupleType is a tuple type: () is the unit, (T,) has one element and (T, U) two. Its parentheses keep their source comments like a TypeGroup's.

type TypeAlias source

type TypeAlias struct {
	SourceInfo `json:"source,omitempty"`
	Name       string   `json:"name"`
	Type       TypeExpr `json:"type"`

	// HeaderComments are the normalized contents of the comments inside the
	// declaration header, between the keyword and the end of the header, in
	// source order: one string per comment, a line comment ending in a line
	// break. Format writes them after the keyword.
	HeaderComments []string `json:"headerComments,omitempty"`

	// Break holds the comments before the declaration, as for TypeDef.
	Break *LineBreak `json:"-"`
}

TypeAlias is a type alias (type Name ~ Type). It names a type without defining a new one.

func (*TypeAlias) DeclName source

func (d *TypeAlias) DeclName() string

type TypeApp source

type TypeApp struct {
	SourceInfo `json:"source,omitempty"`
	Name       string     `json:"name"`
	Args       []TypeExpr `json:"args"`

	// The brackets keep their comments like a TupleType's.
	OpenBreak  *LineBreak `json:"-"`
	BodyBreak  *LineBreak `json:"-"`
	CloseBreak *LineBreak `json:"-"`
	// TrailingComma records a comma after the last argument. Format puts the
	// arguments on separate lines when it is set.
	TrailingComma bool `json:"-"`
}

TypeApp applies a type to type arguments: Name[Args...], as in node[string].

type TypeDecl source

type TypeDecl interface {
	Decl
	// contains filtered or unexported methods
}

TypeDecl is a type declaration: a type definition or a type alias.

type TypeDef source

type TypeDef struct {
	SourceInfo `json:"source,omitempty"`
	Name       string   `json:"name"`
	Type       TypeExpr `json:"type"`

	// HeaderComments are the normalized contents of the comments inside the
	// declaration header, between the keyword and the end of the header, in
	// source order: one string per comment, a line comment ending in a line
	// break. Format writes them after the keyword.
	HeaderComments []string `json:"headerComments,omitempty"`

	// Break holds the comments before the declaration. When it is nil,
	// Format separates the declaration from the previous one with a blank
	// line.
	Break *LineBreak `json:"-"`
}

TypeDef is a type definition. It defines a new type: a struct type (type Name = { ... }), whose Type is a *StructType, or a named node type (type Name = node[T]), whose Type is a *TypeApp naming node with one argument.

func (*TypeDef) DeclName source

func (d *TypeDef) DeclName() string

func (*TypeDef) Fields source

func (t *TypeDef) Fields() []*Field

Fields returns the fields of the struct type that t defines, and nil when t defines a named node type.

func (*TypeDef) NodeValue source

func (t *TypeDef) NodeValue() TypeExpr

NodeValue returns the value type T of a named node type defined as node[T], or nil when t defines a struct type.

func (*TypeDef) Struct source

func (t *TypeDef) Struct() *StructType

Struct returns the struct type that t defines, or nil when t defines a named node type.

type TypeExpr source

type TypeExpr interface {
	// contains filtered or unexported methods
}

TypeExpr is a reference to a type.

type TypeGroup source

type TypeGroup struct {
	SourceInfo `json:"source,omitempty"`
	Type       TypeExpr   `json:"type"`
	OpenBreak  *LineBreak `json:"-"`
	BodyBreak  *LineBreak `json:"-"`
	CloseBreak *LineBreak `json:"-"`
	OneLine    bool       `json:"-"`
}

TypeGroup preserves parentheses and source layout in a type expression. It is transparent to type resolution.

type TypeRef source

type TypeRef struct {
	SourceInfo `json:"source,omitempty"`
	Name       string `json:"name"`
}

TypeRef is a reference to a type by name. The top type is named _ and the bottom type _|_.

func TypeRefs source

func TypeRefs(node any) []*TypeRef

TypeRefs returns the type references in the tree rooted at node, such as a *Grammar, in the order of the tree: in type definitions, rule types, casts, list constructors and every other place where a type is written. A reference shared by several places is returned once.

type Unary source

type Unary struct {
	SourceInfo `json:"source,omitempty"`
	Op         string `json:"op"`
	X          Term   `json:"x"`
}

Unary is a unary operation op x.

type ValidationError source

type ValidationError struct {
	Path string
	Pos  Pos
	Msg  string
}

ValidationError describes a structural defect in a grammar AST. Path uses JSON field names and zero-based array indexes. Pos is the closest known diagnostic position, when the AST carries source information.

func (*ValidationError) Error source

func (e *ValidationError) Error() string

type VarDecl source

type VarDecl interface {
	Decl
	// contains filtered or unexported methods
}

VarDecl is a variable declaration: a variable definition.

type VarDef source

type VarDef struct {
	SourceInfo `json:"source,omitempty"`
	Name       string   `json:"name"`
	Type       TypeExpr `json:"type,omitempty"`
	Value      Term     `json:"value,omitempty"`

	// HeaderComments are the normalized contents of the comments inside the
	// declaration header, between the keyword and the end of the header, in
	// source order: one string per comment, a line comment ending in a line
	// break. Format writes them after the keyword.
	HeaderComments []string `json:"headerComments,omitempty"`

	// Break holds the comments before the declaration, as for TypeDef.
	Break *LineBreak `json:"-"`
}

VarDef is a variable definition (var Name Type = Value). It declares a parser variable with its type and its initial value. Type is nil when it is omitted and inferred from Value; Value is nil when it is omitted and the initial value is the zero value of the type.

func (*VarDef) DeclName source

func (d *VarDef) DeclName() string

type VarRef source

type VarRef struct {
	SourceInfo `json:"source,omitempty"`
	Name       string `json:"name"`
}

VarRef is a reference name to a variable in a predicate.