cockroach: github.com/cockroachdb/cockroach/pkg/sql/opt/optgen/lang Index | Files

package lang

import "github.com/cockroachdb/cockroach/pkg/sql/opt/optgen/lang"

Package lang implements a language called Optgen, short for "optimizer generator". Optgen is a domain-specific language (DSL) that provides an intuitive syntax for defining, matching, and replacing nodes in a target expression tree. Here is an example:

[NormalizeEq]
(Eq
  $left:^(Variable)
  $right:(Variable)
)
=>
(Eq $right $left)

The expression above the arrow is called the "match pattern" and the expression below the arrow is called the "replace pattern". If a node in the target expression tree matches the match pattern, then it will be replaced by a node that is constructed according to the replace pattern. Together, the match pattern and replace pattern are called a "rule".

In addition to rules, the Optgen language includes "definitions". Each definition names and describes one of the nodes that the target expression tree may contain. Match and replace patterns can recognize and construct these nodes. Here is an example:

define Eq {
  Left  Expr
  Right Expr
}

The following sections provide more detail on the Optgen language syntax and semantics, as well as some implementation notes.

Definitions

Optgen language input files may contain any number of definitions, in any order. Each definition describes a node in the target expression tree. A definition has a name and a set of "fields" which describe the node's children. A definition may have zero fields, in which case it describes a node with zero children, which is always a "leaf" in the expression tree.

A field definition consists of two parts - the field's name and its type. The Optgen parser treats the field's type as an opaque identifier; it's up to other components to interpret it. However, typically the field type refers to either some primitive type (like string or int), or else refers to the name of some other operator or group of operators.

Here is the syntax for an operator definition:

define <name> {
  <field-1-name> <field-1-type>
  <field-2-name> <field-2-type>
  ...
}

And here is an example:

define Join {
  Left  Expr
  Right Expr
  On    Expr
}

Definition Tags

A "definition tag" is an opaque identifier that describes some property of the defined node. Definitions can have multiple tags or no tags at all, and the same tag can be attached to multiple definitions. Tags can be used to group definitions according to some shared property or logical grouping. For example, arithmetic or boolean operators might be grouped together. Match patterns can then reference those tags in order to match groups of nodes (see "Matching Names" section).

Here is the definition tagging syntax:

[<tag-1-name>, <tag-2-name>, ...]
define <name> {
}

And here is an example:

[Comparison, Inequality]
define Lt {
  Left  Expr
  Right Expr
}

Rules

Optgen language input files may contain any number of rules, in any order. Each rule has a unique name and consists of a match pattern and a corresponding replace pattern. A rule's match pattern is tested against every node in the target expression tree, bottom-up. Each matching node is replaced by a node constructed according to the replace pattern. The replacement node is itself tested against every rule, and so on, until no further rules match.

Note that this is just a conceptual description. Optgen does not actually do any of this matching or replacing itself. Other components use the Optgen library to generate code. These components are free to match however they want, and to replace nodes or keep the new and old nodes side-by-side (as with a typical optimizer MEMO structure).

Similar to define statements, a rule may have a set of tags associated with it. Rule tags logically group rules, and can also serve as directives to the code generator.

Here is the partial rule syntax (see Syntax section for full syntax):

[<rule-name>, <tag-1-name>, <tag-2-name>, ...]
(<match-opname>
  <match-expr>
  <match-expr>
  ...
)
=>
(<replace-opname>
  <replace-expr>
  <replace-expr>
  ...
)

Match Patterns

The top-level match pattern matches the name and children of one or more nodes in the target expression tree. For example:

(Eq * *)

The "*" character is the "wildcard matcher", which matches a child of any kind. Therefore, this pattern matches any node named "Eq" that has at least two children. Matchers can be nested within one another in order to match children, grandchildren, etc. For example:

(Eq (Variable) (Const))

This pattern matches an "Eq" node with a "Variable" node as its left child and a "Const" node as its right child.

Binding

Child patterns within match and replace patterns can be "bound" to a named variable. These variables can then be referenced later in the match pattern or in the replace pattern. This is a critical part of the Optgen language, since virtually every pattern constructs its replacement pattern based on parts of the match pattern. For example:

[EliminateSelect]
(Select $input:* (True)) => $input

The $input variable is bound to the first child of the "Select" node. If the second child is a "True" node, then the "Select" node will be replaced by its input. Variables can also be passed as arguments to custom matchers, which are described below.

Matching Names

In addition to simple name matching, a node matcher can match tag names. Any node type which has the named tag is matched. For example:

[Inequality]
define Lt {
  Left Expr
  Right Expr
}

[Inequality]
define Gt
{
  Left Expr
  Right Expr
}

(Inequality (Variable) (Const))

This pattern matches either "Lt" or "Gt" nodes. This is useful for writing patterns that apply to multiple kinds of nodes, without need for duplicate patterns that only differ in matched node name.

The node matcher also supports multiple names in the match list, separated by '|' characters. The node's name is allowed to match any of the names in the list. For example:

(Eq | Ne | Inequality)

This pattern matches "Eq", "Ne", "Lt", or "Gt" nodes.

Matching Primitive Types

String and numeric constant nodes in the tree can be matched against literals. A literal string or number in a match pattern is interpreted as a matcher of that type, and will be tested for equality with the child node. For example:

[EliminateConcat]
(Concat $left:* (Const "")) => $left

If Concat's right operand is a constant expression with the empty string as its value, then the pattern matches. Similarly, a constant numeric expression can be matched like this:

[LimitScan]
(Limit (Scan $def:*) (Const 1)) => (ScanOneRow $def)

Matching Lists

Nodes can have a child that is a list of nodes rather than a single node. As an example, a function call node might have two children: the name of the function and the list of arguments to the function:

define FuncCall {
  Name Expr
  Args ExprList
}

There are several kinds of list matchers, each of which uses a variant of the list matching bracket syntax. The ellipses signify that 0 or more items can match at either the beginning or end of the list. The item pattern can be any legal match pattern, and can be bound to a variable.

[ ... <item pattern> ... ]

- ANY: Matches if any item in the list matches the item pattern. If multiple items match, then the list matcher binds to the first match.

[ ... $item:* ... ]

- FIRST: Matches if the first item in the list matches the item pattern (and there is at least one item in the list).

[ $item:* ... ]

- LAST: Matches if the last item in the list matches the item pattern (and there is at least one item).

[ ... $item:* ]

- SINGLE: Matches if there is exactly one item in the list, and it matches the item pattern.

[ $item:* ]

- EMPTY: Matches if there are zero items in the list.

[]

Following is a more complete example. The ANY list matcher in the example searches through the Filter child's list, looking for a Subquery node. If a matching node is found, then the list matcher succeeds and binds the node to the $item variable.

(Select
  $input:*
  (Filter [ ... $item:(Subquery) ... ])
)

Custom Matching

When the supported matching syntax is insufficient, Optgen provides an escape mechanism. Custom matching functions can invoke Go functions, passing previously bound variables as arguments, and checking the boolean result for a match. For example:

[EliminateFilters]
(Filters $items:* & (IsEmptyList $items)) => (True)

This pattern passes the $items child node to the IsEmptyList function. If that returns true, then the pattern matches.

Custom matching functions can appear anywhere that other matchers can, and can be combined with other matchers using boolean operators (see the Boolean Expressions section for more details). While variable references are the most common argument, it is also legal to nest function invocations:

(Project
  $input:*
  $projections:* & ^(IsEmpty (FindUnusedColumns $projections))
)

Boolean Expressions

Multiple match expressions of any type can be combined using the boolean & (AND) operator. All must match in order for the overall match to succeed:

(Not
  $input:(Comparison) & (Inequality) & (CanInvert $input)
)

The boolean ^ (NOT) operator negates the result of a boolean match expression. It can be used with any kind of matcher, including custom match functions:

(JoinApply
  $left:^(Select)
  $right:* & ^(IsCorrelated $right $left)
  $on:*
)

This pattern matches only if the left child is not a Select node, and if the IsCorrelated custom function returns false.

Replace Patterns

Once a matching node is found, the replace pattern produces a single substitution node. The most common replace pattern involves constructing one or more new nodes, often with child nodes that were bound in the match pattern. A construction expression specifies the name of the node as its first operand and its children as subsequent arguments. Construction expressions can be nested within one another to any depth. For example:

[HoistSelectExists]
(Select
  $input:*
  $filter:(Exists $subquery:*)
)
=>
(SemiJoinApply
  $input
  $subquery
  (True)
)

The replace pattern in this rule constructs a new SemiJoinApply node, with its first two children bound in the match pattern. The third child is a newly constructed True node.

The replace pattern can also consist of a single variable reference, in the case where the substitution node was already present in the match pattern:

[EliminateAnd]
(And $left:* (True)) => $left

Custom Construction

When Optgen syntax cannot easily produce a result, custom construction functions allow results to be derived in Go code. If a construction expression's name is not recognized as a node name, then it is assumed to be the name of a custom function. For example:

[MergeSelectJoin]
(Select
  (InnerJoin $r:* $s:* $on:*)
  $filter:*
)
=>
(InnerJoin
  $r
  $s
  (ConcatFilters $on $filter)
)

Here, the ConcatFilters custom function is invoked in order to concatenate two filter lists together. Function parameters can include nodes, lists (see the Constructing Lists section), operator names (see the Name parameters section), and the results of nested custom function calls. While custom functions typically return a node, they can return other types if they are parameters to other custom functions.

Constructing Lists

Lists can be constructed and passed as parameters to node construction expressions or custom replace functions. A list consists of multiple items that can be of any parameter type, including nodes, strings, custom function invocations, or lists. Here is an example:

[MergeSelectJoin]
(Select
  (InnerJoin $left:* $right:* $on:*)
  $filters:*
)
=>
(InnerJoin
  $left
  $right
  (And [$on $filters])
)

Dynamic Construction

Sometimes the name of a constructed node can be one of several choices. The built-in "OpName" function can be used to dynamically construct the right kind of node. For example:

[NormalizeVar]
(Eq | Ne
  $left:^(Variable)
  $right:(Variable)
)
=>
((OpName) $right $left)

In this pattern, the name of the constructed result is either Eq or Ne, depending on which is matched. When the OpName function has no arguments, then it is bound to the name of the node matched at the top-level. The OpName function can also take a single variable reference argument. In that case, it refers to the name of the node bound to that variable:

[PushDownSelect]
(Select
  $input:(Join $left:* $right:* $on:*)
  $filter:* & ^(IsCorrelated $filter $right)
)
=>
((OpName $input)
  (Select $left $filter)
  $right
  $on
)

In this pattern, Join is a tag that refers to a group of nodes. The replace expression will construct a node having the same name as the matched join node.

Name Parameters

The OpName built-in function can also be a parameter to a custom match or replace function which needs to know which name matched. For example:

[FoldBinaryNull]
(Binary $left:* (Null) & ^(HasNullableArgs (OpName)))
=>
(Null)

The name of the matched Binary node (e.g. Plus, In, Contains) is passed to the HasNullableArgs function as a symbolic identifier. Here is an example that uses a custom replace function and the OpName function with an argument:

[NegateComparison]
(Not $input:(Comparison $left:* $right:*))
=>
(InvertComparison (OpName $input) $left $right)

As described in the previous section, adding the argument enables OpName to return a name that was matched deeper in the pattern.

In addition to a name returned by the OpName function, custom match and replace functions can accept literal operator names as parameters. The Minus operator name is passed as a parameter to two functions in this example:

[FoldMinus]
(UnaryMinus
  (Minus $left $right) & (OverloadExists Minus $right $left)
)
=>
(ConstructBinary Minus $right $left)

Type Inference

Expressions in both the match and replace patterns are assigned a data type that describes the kind of data that will be returned by the expression. These types are inferred using a combination of top-down and bottom-up type inference rules. For example:

define Select {
  Input  Expr
  Filter Expr
}

(Select $input:(LeftJoin | RightJoin) $filter:*) => $input

The type of $input is inferred as "LeftJoin | RightJoin" by bubbling up the type of the bound expression. That type is propagated to the $input reference in the replace pattern. By contrast, the type of the * expression is inferred to be "Expr" using a top-down type inference rule, since the second argument to the Select operator is known to have type "Expr".

When multiple types are inferred for an expression using different type inference rules, the more restrictive type is assigned to the expression. For example:

(Select $input:* & (LeftJoin)) => $input

Here, the left input to the And expression was inferred to have type "Expr" and the right input to have type "LeftJoin". Since "LeftJoin" is the more restrictive type, the And expression and the $input binding are typed as "LeftJoin".

Type inference detects and reports type contradictions, which occur when multiple incompatible types are inferred for an expression. For example:

(Select $input:(InnerJoin) & (LeftJoin)) => $input

Because the input cannot be both an InnerJoin and a LeftJoin, Optgen reports a type contradiction error.

Syntax

This section describes the Optgen language syntax in a variant of extended Backus-Naur form. The non-terminals correspond to methods in the parser. The terminals correspond to tokens returned by the scanner. Whitespace and comment tokens can be freely interleaved between other tokens in the grammar.

root         = tags (define | rule)
tags         = '[' IDENT (',' IDENT)* ']'

define       = 'define' define-name '{' define-field* '}'
define-name  = IDENT
define-field = field-name field-type
field-name   = IDENT
field-type   = IDENT

rule         = func '=>' replace
match        = func
replace      = func | ref
func         = '(' func-name arg* ')'
func-name    = names | func
names        = name ('|' name)*
arg          = bind and | ref | and
and          = expr ('&' and)
expr         = func | not | list | any | name | STRING | NUMBER
not          = '^' expr
list         = '[' list-child* ']'
list-child   = list-any | arg
list-any     = '...'
bind         = '$' label ':' and
ref          = '$' label
any          = '*'
name         = IDENT
label        = IDENT

Here are the pseudo-regex definitions for the lexical tokens that aren't represented as single-quoted strings above:

STRING     = " [^"\n]* "
NUMBER     = UnicodeDigit+
IDENT      = (UnicodeLetter | '_') (UnicodeLetter | '_' | UnicodeNumber)*
COMMENT    = '#' .* \n
WHITESPACE = UnicodeSpace+

The support directory contains syntax coloring files for several editors, including Vim, TextMate, and Visual Studio Code. JetBrains editor (i.e. GoLand) can also import TextMate bundles to provide syntax coloring.

Components

The lang package contains a scanner that breaks input files into lexical tokens, a parser that assembles an abstract syntax tree (AST) from the tokens, and a compiler that performs semantic checks and creates a rudimentary symbol table.

The compiled rules and definitions become the input to a separate code generation package which generates parts of the Cockroach DB SQL optimizer. However, the Optgen language itself is not Cockroach or SQL specific, and can be used in other contexts. For example, the Optgen language parser generates its own AST expressions using itself (compiler bootstrapping).

Index

Package Files

compiler.go data_type.go doc.go expr.go expr.og.go operator.og.go operator_string.go parser.go scanner.go token_string.go

Variables

var AnyDataType = &ExternalDataType{Name: "<any>"}

AnyDataType is a data type about which nothing is known, and so could be any data type. Among other uses, it is assigned to custom functions:

(Scan $def:*) => (ConstrainScan $def)

The ConstrainScan custom function has the AnyDataType assigned to it, since the return type of the function is not known.

var Int64DataType = &ExternalDataType{Name: "<int64>"}

Int64DataType is a singleton instance of the "int64" external data type.

var ListDataType = &ExternalDataType{Name: "<list>"}

ListDataType indicates that a pattern matches or constructs a list of expressions. For example:

(Tuple $list:[ $item:* ]) => $item

The $list binding will have the ListDataType.

var StringDataType = &ExternalDataType{Name: "<string>"}

StringDataType is a singleton instance of the "string" external data type.

func DoTypesContradict Uses

func DoTypesContradict(dt1, dt2 DataType) bool

DoTypesContradict returns true if two types cannot both be assigned to same expression.

func IsBuiltinType Uses

func IsBuiltinType(dt DataType) bool

IsBuiltinType returns true if the data type is one of List, String, or Int64.

func IsTypeMoreRestrictive Uses

func IsTypeMoreRestrictive(dt1, dt2 DataType) bool

IsTypeMoreRestrictive returns true if the first data type gives more complete and detailed information than the second.

type AndExpr Uses

type AndExpr struct {
    Left  Expr
    Right Expr
    Src   *SourceLoc
    Typ   DataType
}

func (*AndExpr) Child Uses

func (e *AndExpr) Child(nth int) Expr

func (*AndExpr) ChildCount Uses

func (e *AndExpr) ChildCount() int

func (*AndExpr) ChildName Uses

func (e *AndExpr) ChildName(nth int) string

func (*AndExpr) Format Uses

func (e *AndExpr) Format(buf *bytes.Buffer, level int)

func (*AndExpr) InferredType Uses

func (e *AndExpr) InferredType() DataType

func (*AndExpr) Op Uses

func (e *AndExpr) Op() Operator

func (*AndExpr) Source Uses

func (e *AndExpr) Source() *SourceLoc

func (*AndExpr) String Uses

func (e *AndExpr) String() string

func (*AndExpr) Value Uses

func (e *AndExpr) Value() interface{}

func (*AndExpr) Visit Uses

func (e *AndExpr) Visit(visit VisitFunc) Expr

type AnyExpr Uses

type AnyExpr struct {
    Src *SourceLoc
    Typ DataType
}

func (*AnyExpr) Child Uses

func (e *AnyExpr) Child(nth int) Expr

func (*AnyExpr) ChildCount Uses

func (e *AnyExpr) ChildCount() int

func (*AnyExpr) ChildName Uses

func (e *AnyExpr) ChildName(nth int) string

func (*AnyExpr) Format Uses

func (e *AnyExpr) Format(buf *bytes.Buffer, level int)

func (*AnyExpr) InferredType Uses

func (e *AnyExpr) InferredType() DataType

func (*AnyExpr) Op Uses

func (e *AnyExpr) Op() Operator

func (*AnyExpr) Source Uses

func (e *AnyExpr) Source() *SourceLoc

func (*AnyExpr) String Uses

func (e *AnyExpr) String() string

func (*AnyExpr) Value Uses

func (e *AnyExpr) Value() interface{}

func (*AnyExpr) Visit Uses

func (e *AnyExpr) Visit(visit VisitFunc) Expr

type BindExpr Uses

type BindExpr struct {
    Label  StringExpr
    Target Expr
    Src    *SourceLoc
    Typ    DataType
}

func (*BindExpr) Child Uses

func (e *BindExpr) Child(nth int) Expr

func (*BindExpr) ChildCount Uses

func (e *BindExpr) ChildCount() int

func (*BindExpr) ChildName Uses

func (e *BindExpr) ChildName(nth int) string

func (*BindExpr) Format Uses

func (e *BindExpr) Format(buf *bytes.Buffer, level int)

func (*BindExpr) InferredType Uses

func (e *BindExpr) InferredType() DataType

func (*BindExpr) Op Uses

func (e *BindExpr) Op() Operator

func (*BindExpr) Source Uses

func (e *BindExpr) Source() *SourceLoc

func (*BindExpr) String Uses

func (e *BindExpr) String() string

func (*BindExpr) Value Uses

func (e *BindExpr) Value() interface{}

func (*BindExpr) Visit Uses

func (e *BindExpr) Visit(visit VisitFunc) Expr

type CommentExpr Uses

type CommentExpr string

func (*CommentExpr) Child Uses

func (e *CommentExpr) Child(nth int) Expr

func (*CommentExpr) ChildCount Uses

func (e *CommentExpr) ChildCount() int

func (*CommentExpr) ChildName Uses

func (e *CommentExpr) ChildName(nth int) string

func (*CommentExpr) Format Uses

func (e *CommentExpr) Format(buf *bytes.Buffer, level int)

func (*CommentExpr) InferredType Uses

func (e *CommentExpr) InferredType() DataType

func (*CommentExpr) Op Uses

func (e *CommentExpr) Op() Operator

func (*CommentExpr) Source Uses

func (e *CommentExpr) Source() *SourceLoc

func (*CommentExpr) String Uses

func (e *CommentExpr) String() string

func (*CommentExpr) Value Uses

func (e *CommentExpr) Value() interface{}

func (*CommentExpr) Visit Uses

func (e *CommentExpr) Visit(visit VisitFunc) Expr

type CommentsExpr Uses

type CommentsExpr []CommentExpr

func (*CommentsExpr) Child Uses

func (e *CommentsExpr) Child(nth int) Expr

func (*CommentsExpr) ChildCount Uses

func (e *CommentsExpr) ChildCount() int

func (*CommentsExpr) ChildName Uses

func (e *CommentsExpr) ChildName(nth int) string

func (*CommentsExpr) Format Uses

func (e *CommentsExpr) Format(buf *bytes.Buffer, level int)

func (*CommentsExpr) InferredType Uses

func (e *CommentsExpr) InferredType() DataType

func (*CommentsExpr) Op Uses

func (e *CommentsExpr) Op() Operator

func (*CommentsExpr) Source Uses

func (e *CommentsExpr) Source() *SourceLoc

func (*CommentsExpr) String Uses

func (e *CommentsExpr) String() string

func (*CommentsExpr) Value Uses

func (e *CommentsExpr) Value() interface{}

func (*CommentsExpr) Visit Uses

func (e *CommentsExpr) Visit(visit VisitFunc) Expr

type CompiledExpr Uses

type CompiledExpr struct {
    Defines    DefineSetExpr
    Rules      RuleSetExpr
    DefineTags []string
    // contains filtered or unexported fields
}

CompiledExpr is the result of Optgen scanning, parsing, and semantic analysis. It contains the set of definitions and rules that were compiled from the Optgen input files.

func (*CompiledExpr) LookupDefine Uses

func (c *CompiledExpr) LookupDefine(name string) *DefineExpr

LookupDefine returns the DefineExpr with the given name.

func (*CompiledExpr) LookupMatchingDefines Uses

func (c *CompiledExpr) LookupMatchingDefines(name string) DefineSetExpr

LookupMatchingDefines returns the set of define expressions which either exactly match the given name, or else have a tag that matches the given name. If no matches can be found, then LookupMatchingDefines returns nil.

func (*CompiledExpr) LookupMatchingRules Uses

func (c *CompiledExpr) LookupMatchingRules(name string) RuleSetExpr

LookupMatchingRules returns the set of rules that match the given opname at the top-level, or nil if none do. For example, "InnerJoin" would match this rule:

[CommuteJoin]
(InnerJoin $r:* $s:*) => (InnerJoin $s $r)

func (*CompiledExpr) String Uses

func (c *CompiledExpr) String() string

type Compiler Uses

type Compiler struct {
    // contains filtered or unexported fields
}

Compiler compiles Optgen language input files and builds a CompiledExpr result from them. Compilation consists of scanning/parsing the files, which produces an AST, and is followed by semantic analysis and limited rewrites on the AST which the compiler performs.

func NewCompiler Uses

func NewCompiler(files ...string) *Compiler

NewCompiler constructs a new instance of the Optgen compiler, with the specified list of file paths as its input files. The Compile method must be called in order to compile the input files.

func (*Compiler) Compile Uses

func (c *Compiler) Compile() *CompiledExpr

Compile parses and compiles the input files and returns the resulting CompiledExpr. If there are errors, then Compile returns nil, and the errors are returned by the Errors function.

func (*Compiler) Errors Uses

func (c *Compiler) Errors() []error

Errors returns the collection of errors that occurred during compilation. If no errors occurred, then Errors returns nil.

func (*Compiler) SetFileResolver Uses

func (c *Compiler) SetFileResolver(resolver FileResolver)

SetFileResolver overrides the default method of opening input files. The default resolver will use os.Open to open input files from disk. Callers can use this method to open input files in some other way.

type CustomFuncExpr Uses

type CustomFuncExpr struct {
    Name NameExpr
    Args SliceExpr
    Src  *SourceLoc
    Typ  DataType
}

func (*CustomFuncExpr) Child Uses

func (e *CustomFuncExpr) Child(nth int) Expr

func (*CustomFuncExpr) ChildCount Uses

func (e *CustomFuncExpr) ChildCount() int

func (*CustomFuncExpr) ChildName Uses

func (e *CustomFuncExpr) ChildName(nth int) string

func (*CustomFuncExpr) Format Uses

func (e *CustomFuncExpr) Format(buf *bytes.Buffer, level int)

func (*CustomFuncExpr) InferredType Uses

func (e *CustomFuncExpr) InferredType() DataType

func (*CustomFuncExpr) Op Uses

func (e *CustomFuncExpr) Op() Operator

func (*CustomFuncExpr) Source Uses

func (e *CustomFuncExpr) Source() *SourceLoc

func (*CustomFuncExpr) String Uses

func (e *CustomFuncExpr) String() string

func (*CustomFuncExpr) Value Uses

func (e *CustomFuncExpr) Value() interface{}

func (*CustomFuncExpr) Visit Uses

func (e *CustomFuncExpr) Visit(visit VisitFunc) Expr

type DataType Uses

type DataType interface {
    String() string
    // contains filtered or unexported methods
}

DataType is a marker interface implemented by structs that describe the kind of data that will be returned by an expression in a match or replace pattern. See DataType implementations for more specific information.

type DefineExpr Uses

type DefineExpr struct {
    Comments CommentsExpr
    Tags     TagsExpr
    Name     StringExpr
    Fields   DefineFieldsExpr
    Src      *SourceLoc
}

func (*DefineExpr) Child Uses

func (e *DefineExpr) Child(nth int) Expr

func (*DefineExpr) ChildCount Uses

func (e *DefineExpr) ChildCount() int

func (*DefineExpr) ChildName Uses

func (e *DefineExpr) ChildName(nth int) string

func (*DefineExpr) Format Uses

func (e *DefineExpr) Format(buf *bytes.Buffer, level int)

func (*DefineExpr) InferredType Uses

func (e *DefineExpr) InferredType() DataType

func (*DefineExpr) Op Uses

func (e *DefineExpr) Op() Operator

func (*DefineExpr) Source Uses

func (e *DefineExpr) Source() *SourceLoc

func (*DefineExpr) String Uses

func (e *DefineExpr) String() string

func (*DefineExpr) Value Uses

func (e *DefineExpr) Value() interface{}

func (*DefineExpr) Visit Uses

func (e *DefineExpr) Visit(visit VisitFunc) Expr

type DefineFieldExpr Uses

type DefineFieldExpr struct {
    Comments CommentsExpr
    Name     StringExpr
    Type     StringExpr
    Src      *SourceLoc
}

func (*DefineFieldExpr) Child Uses

func (e *DefineFieldExpr) Child(nth int) Expr

func (*DefineFieldExpr) ChildCount Uses

func (e *DefineFieldExpr) ChildCount() int

func (*DefineFieldExpr) ChildName Uses

func (e *DefineFieldExpr) ChildName(nth int) string

func (*DefineFieldExpr) Format Uses

func (e *DefineFieldExpr) Format(buf *bytes.Buffer, level int)

func (*DefineFieldExpr) InferredType Uses

func (e *DefineFieldExpr) InferredType() DataType

func (*DefineFieldExpr) Op Uses

func (e *DefineFieldExpr) Op() Operator

func (*DefineFieldExpr) Source Uses

func (e *DefineFieldExpr) Source() *SourceLoc

func (*DefineFieldExpr) String Uses

func (e *DefineFieldExpr) String() string

func (*DefineFieldExpr) Value Uses

func (e *DefineFieldExpr) Value() interface{}

func (*DefineFieldExpr) Visit Uses

func (e *DefineFieldExpr) Visit(visit VisitFunc) Expr

type DefineFieldsExpr Uses

type DefineFieldsExpr []*DefineFieldExpr

func (*DefineFieldsExpr) Child Uses

func (e *DefineFieldsExpr) Child(nth int) Expr

func (*DefineFieldsExpr) ChildCount Uses

func (e *DefineFieldsExpr) ChildCount() int

func (*DefineFieldsExpr) ChildName Uses

func (e *DefineFieldsExpr) ChildName(nth int) string

func (*DefineFieldsExpr) Format Uses

func (e *DefineFieldsExpr) Format(buf *bytes.Buffer, level int)

func (*DefineFieldsExpr) InferredType Uses

func (e *DefineFieldsExpr) InferredType() DataType

func (*DefineFieldsExpr) Op Uses

func (e *DefineFieldsExpr) Op() Operator

func (*DefineFieldsExpr) Source Uses

func (e *DefineFieldsExpr) Source() *SourceLoc

func (*DefineFieldsExpr) String Uses

func (e *DefineFieldsExpr) String() string

func (*DefineFieldsExpr) Value Uses

func (e *DefineFieldsExpr) Value() interface{}

func (*DefineFieldsExpr) Visit Uses

func (e *DefineFieldsExpr) Visit(visit VisitFunc) Expr

type DefineSetDataType Uses

type DefineSetDataType struct {
    Defines DefineSetExpr
}

DefineSetDataType indicates that a pattern matches or constructs one of several possible defined operators. For example:

(Eq | Ne $left:* $right:*) => (True)

The top-level match pattern would have a DefineSetDataType that referenced the defines for the Eq and Ne operators.

func (*DefineSetDataType) String Uses

func (d *DefineSetDataType) String() string

String is part of the DataType interface.

type DefineSetExpr Uses

type DefineSetExpr []*DefineExpr

func (*DefineSetExpr) Child Uses

func (e *DefineSetExpr) Child(nth int) Expr

func (*DefineSetExpr) ChildCount Uses

func (e *DefineSetExpr) ChildCount() int

func (*DefineSetExpr) ChildName Uses

func (e *DefineSetExpr) ChildName(nth int) string

func (*DefineSetExpr) Format Uses

func (e *DefineSetExpr) Format(buf *bytes.Buffer, level int)

func (*DefineSetExpr) InferredType Uses

func (e *DefineSetExpr) InferredType() DataType

func (*DefineSetExpr) Op Uses

func (e *DefineSetExpr) Op() Operator

func (*DefineSetExpr) Source Uses

func (e *DefineSetExpr) Source() *SourceLoc

func (*DefineSetExpr) String Uses

func (e *DefineSetExpr) String() string

func (*DefineSetExpr) Value Uses

func (e *DefineSetExpr) Value() interface{}

func (*DefineSetExpr) Visit Uses

func (e *DefineSetExpr) Visit(visit VisitFunc) Expr

func (DefineSetExpr) WithTag Uses

func (e DefineSetExpr) WithTag(tag string) DefineSetExpr

WithTag returns the subset of defines in the set that have the given tag.

func (DefineSetExpr) WithoutTag Uses

func (e DefineSetExpr) WithoutTag(tag string) DefineSetExpr

WithoutTag returns the subset of defines in the set that do not have the given tag.

type Expr Uses

type Expr interface {
    // Op returns the operator type of the expression (RuleOp, StringOp, etc).
    Op() Operator

    // ChildCount returns the number of children of the expression.
    ChildCount() int

    // Child returns the nth child of this expression.
    Child(nth int) Expr

    // ChildName returns the name of the nth child of this expression. If the
    // child has no name, or if there is no such child, then ChildName returns
    // the empty string.
    ChildName(nth int) string

    // Value returns the value stored by "leaf" expressions that are
    // represented as a primitive type like string or int. Other expression
    // types just return nil.
    Value() interface{}

    // Visit invokes the visit function for each child of the expression. The
    // function can return the child as-is, with no changes, or it can construct
    // and return a replacement expression. If any children have been replaced,
    // then Visit will construct a new instance of this expression that has the
    // new children. Callers can use the Visit function to traverse and rewrite
    // the expression tree, in either pre or post order. Here is a pre-order
    // example:
    //
    //   func myVisitFunc(e Expr) Expr {
    //     // Replace SomeOp, leave everything else as-is. This check is before
    //     // the call to Visit, so it's a pre-order traversal.
    //     if e.Op() == SomeOp {
    //       return &SomeOtherOp{}
    //     }
    //     return e.Visit(myVisitFunc)
    //   }
    //   newExpr := oldExpr.Visit(myVisitFunc)
    Visit(visit VisitFunc) Expr

    // InferredType describes the kind of data that will be returned when this
    // expression is evaluated. Type inference rules work top-down and bottom-
    // up to establish the type. For example:
    //
    //   define Select {
    //     Input  Node
    //     Filter Node
    //   }
    //
    //   define True {}
    //
    //   (Select $input:* $filter:(True)) => $input
    //
    // The type of the $input binding and ref would be inferred as Node, since
    // that's as specific as can be inferred. The type of $filter would be
    // inferred as TrueOp, since a more specific type than Node is possible to
    // infer in this case.
    //
    // The compiler uses this information to ensure that every match pattern has
    // a statically known set of ops it can match, and that every replace pattern
    // has a statically known set of ops it can construct. Code generators can
    // also use this information to generate strongly-typed code.
    InferredType() DataType

    // Source returns the original source location of the expression, including
    // file name, line number, and column position. If the source location is
    // not available, then Source returns nil.
    Source() *SourceLoc

    // String returns a human-readable string representation of the expression
    // tree.
    String() string

    // Format writes the expression's string representation into the given
    // buffer, at the specified level of indentation.
    Format(buf *bytes.Buffer, level int)
}

Expr is implemented by all Optgen AST expressions, exposing its properties, children, and string representation.

type ExternalDataType Uses

type ExternalDataType struct {
    Name string
}

ExternalDataType indicates that a pattern matches or constructs a non- operator type referenced in a Define. For example:

define Scan {
  Def ScanDef
}

(Scan $def:*) => (ConstrainScan $def)

Here, $def will have an ExternalDataType with Name equal to "ScanDef".

func (*ExternalDataType) String Uses

func (d *ExternalDataType) String() string

String is part of the DataType interface.

type FileResolver Uses

type FileResolver func(name string) (io.Reader, error)

FileResolver is used by the parser to abstract the opening and reading of input files. Callers of the parser can override the default behavior (os.Open) in order to open files in some other way (e.g. for testing).

type FuncExpr Uses

type FuncExpr struct {
    Name Expr
    Args SliceExpr
    Src  *SourceLoc
    Typ  DataType
}

func (*FuncExpr) Child Uses

func (e *FuncExpr) Child(nth int) Expr

func (*FuncExpr) ChildCount Uses

func (e *FuncExpr) ChildCount() int

func (*FuncExpr) ChildName Uses

func (e *FuncExpr) ChildName(nth int) string

func (*FuncExpr) Format Uses

func (e *FuncExpr) Format(buf *bytes.Buffer, level int)

func (*FuncExpr) HasDynamicName Uses

func (e *FuncExpr) HasDynamicName() bool

HasDynamicName returns true if this is a construction function which can construct several different operators; which it constructs is not known until runtime. For example:

(Select $input:(Left | InnerJoin $left:* $right:* $on))
=>
((OpName $input) $left $right $on)

The replace pattern uses a constructor function that dynamically constructs either a Left or InnerJoin operator.

func (*FuncExpr) InferredType Uses

func (e *FuncExpr) InferredType() DataType

func (*FuncExpr) NameChoice Uses

func (e *FuncExpr) NameChoice() NamesExpr

NameChoice returns the set of names that this function can have. Multiple choices are possible when this is a match function.

func (*FuncExpr) Op Uses

func (e *FuncExpr) Op() Operator

func (*FuncExpr) SingleName Uses

func (e *FuncExpr) SingleName() string

SingleName returns the name of the function when there is exactly one choice. If there is zero or more than one choice, SingleName will panic.

func (*FuncExpr) Source Uses

func (e *FuncExpr) Source() *SourceLoc

func (*FuncExpr) String Uses

func (e *FuncExpr) String() string

func (*FuncExpr) Value Uses

func (e *FuncExpr) Value() interface{}

func (*FuncExpr) Visit Uses

func (e *FuncExpr) Visit(visit VisitFunc) Expr

type ListAnyExpr Uses

type ListAnyExpr struct {
    Src *SourceLoc
}

func (*ListAnyExpr) Child Uses

func (e *ListAnyExpr) Child(nth int) Expr

func (*ListAnyExpr) ChildCount Uses

func (e *ListAnyExpr) ChildCount() int

func (*ListAnyExpr) ChildName Uses

func (e *ListAnyExpr) ChildName(nth int) string

func (*ListAnyExpr) Format Uses

func (e *ListAnyExpr) Format(buf *bytes.Buffer, level int)

func (*ListAnyExpr) InferredType Uses

func (e *ListAnyExpr) InferredType() DataType

func (*ListAnyExpr) Op Uses

func (e *ListAnyExpr) Op() Operator

func (*ListAnyExpr) Source Uses

func (e *ListAnyExpr) Source() *SourceLoc

func (*ListAnyExpr) String Uses

func (e *ListAnyExpr) String() string

func (*ListAnyExpr) Value Uses

func (e *ListAnyExpr) Value() interface{}

func (*ListAnyExpr) Visit Uses

func (e *ListAnyExpr) Visit(visit VisitFunc) Expr

type ListExpr Uses

type ListExpr struct {
    Items SliceExpr
    Src   *SourceLoc
    Typ   DataType
}

func (*ListExpr) Child Uses

func (e *ListExpr) Child(nth int) Expr

func (*ListExpr) ChildCount Uses

func (e *ListExpr) ChildCount() int

func (*ListExpr) ChildName Uses

func (e *ListExpr) ChildName(nth int) string

func (*ListExpr) Format Uses

func (e *ListExpr) Format(buf *bytes.Buffer, level int)

func (*ListExpr) InferredType Uses

func (e *ListExpr) InferredType() DataType

func (*ListExpr) Op Uses

func (e *ListExpr) Op() Operator

func (*ListExpr) Source Uses

func (e *ListExpr) Source() *SourceLoc

func (*ListExpr) String Uses

func (e *ListExpr) String() string

func (*ListExpr) Value Uses

func (e *ListExpr) Value() interface{}

func (*ListExpr) Visit Uses

func (e *ListExpr) Visit(visit VisitFunc) Expr

type NameExpr Uses

type NameExpr string

func (*NameExpr) Child Uses

func (e *NameExpr) Child(nth int) Expr

func (*NameExpr) ChildCount Uses

func (e *NameExpr) ChildCount() int

func (*NameExpr) ChildName Uses

func (e *NameExpr) ChildName(nth int) string

func (*NameExpr) Format Uses

func (e *NameExpr) Format(buf *bytes.Buffer, level int)

func (*NameExpr) InferredType Uses

func (e *NameExpr) InferredType() DataType

func (*NameExpr) Op Uses

func (e *NameExpr) Op() Operator

func (*NameExpr) Source Uses

func (e *NameExpr) Source() *SourceLoc

func (*NameExpr) String Uses

func (e *NameExpr) String() string

func (*NameExpr) Value Uses

func (e *NameExpr) Value() interface{}

func (*NameExpr) Visit Uses

func (e *NameExpr) Visit(visit VisitFunc) Expr

type NamesExpr Uses

type NamesExpr []NameExpr

func (*NamesExpr) Child Uses

func (e *NamesExpr) Child(nth int) Expr

func (*NamesExpr) ChildCount Uses

func (e *NamesExpr) ChildCount() int

func (*NamesExpr) ChildName Uses

func (e *NamesExpr) ChildName(nth int) string

func (*NamesExpr) Format Uses

func (e *NamesExpr) Format(buf *bytes.Buffer, level int)

func (*NamesExpr) InferredType Uses

func (e *NamesExpr) InferredType() DataType

func (*NamesExpr) Op Uses

func (e *NamesExpr) Op() Operator

func (*NamesExpr) Source Uses

func (e *NamesExpr) Source() *SourceLoc

func (*NamesExpr) String Uses

func (e *NamesExpr) String() string

func (*NamesExpr) Value Uses

func (e *NamesExpr) Value() interface{}

func (*NamesExpr) Visit Uses

func (e *NamesExpr) Visit(visit VisitFunc) Expr

type NotExpr Uses

type NotExpr struct {
    Input Expr
    Src   *SourceLoc
    Typ   DataType
}

func (*NotExpr) Child Uses

func (e *NotExpr) Child(nth int) Expr

func (*NotExpr) ChildCount Uses

func (e *NotExpr) ChildCount() int

func (*NotExpr) ChildName Uses

func (e *NotExpr) ChildName(nth int) string

func (*NotExpr) Format Uses

func (e *NotExpr) Format(buf *bytes.Buffer, level int)

func (*NotExpr) InferredType Uses

func (e *NotExpr) InferredType() DataType

func (*NotExpr) Op Uses

func (e *NotExpr) Op() Operator

func (*NotExpr) Source Uses

func (e *NotExpr) Source() *SourceLoc

func (*NotExpr) String Uses

func (e *NotExpr) String() string

func (*NotExpr) Value Uses

func (e *NotExpr) Value() interface{}

func (*NotExpr) Visit Uses

func (e *NotExpr) Visit(visit VisitFunc) Expr

type NumberExpr Uses

type NumberExpr int64

func (*NumberExpr) Child Uses

func (e *NumberExpr) Child(nth int) Expr

func (*NumberExpr) ChildCount Uses

func (e *NumberExpr) ChildCount() int

func (*NumberExpr) ChildName Uses

func (e *NumberExpr) ChildName(nth int) string

func (*NumberExpr) Format Uses

func (e *NumberExpr) Format(buf *bytes.Buffer, level int)

func (*NumberExpr) InferredType Uses

func (e *NumberExpr) InferredType() DataType

func (*NumberExpr) Op Uses

func (e *NumberExpr) Op() Operator

func (*NumberExpr) Source Uses

func (e *NumberExpr) Source() *SourceLoc

func (*NumberExpr) String Uses

func (e *NumberExpr) String() string

func (*NumberExpr) Value Uses

func (e *NumberExpr) Value() interface{}

func (*NumberExpr) Visit Uses

func (e *NumberExpr) Visit(visit VisitFunc) Expr

type Operator Uses

type Operator int
const (
    UnknownOp Operator = iota

    RootOp
    DefineSetOp
    RuleSetOp
    DefineOp
    CommentsOp
    CommentOp
    TagsOp
    TagOp
    DefineFieldsOp
    DefineFieldOp
    RuleOp
    FuncOp
    NamesOp
    NameOp
    AndOp
    NotOp
    ListOp
    ListAnyOp
    BindOp
    RefOp
    AnyOp
    SliceOp
    StringOp
    NumberOp
    CustomFuncOp
)

func (Operator) String Uses

func (i Operator) String() string

type Parser Uses

type Parser struct {
    // contains filtered or unexported fields
}

Parser parses Optgen language input files and builds an abstract syntax tree (AST) from them. Typically the Optgen compiler invokes the parser and then performs semantic checks on the resulting AST. For more details on the Optgen language syntax, see the Syntax section of docs.go.

func NewParser Uses

func NewParser(files ...string) *Parser

NewParser constructs a new instance of the Optgen parser, with the specified list of file paths as its input files. The Parse method must be called in order to parse the input files.

func (*Parser) Errors Uses

func (p *Parser) Errors() []error

Errors returns the collection of errors that occurred during parsing. If no errors occurred, then Errors returns nil.

func (*Parser) Parse Uses

func (p *Parser) Parse() *RootExpr

Parse parses the input files and returns the root expression of the AST. If there are parse errors, then Parse returns nil, and the errors are returned by the Errors function.

func (*Parser) SetFileResolver Uses

func (p *Parser) SetFileResolver(resolver FileResolver)

SetFileResolver overrides the default method of opening input files. The default resolver will use os.Open to open input files from disk. Callers can use this method to open input files in some other way.

type RefExpr Uses

type RefExpr struct {
    Label StringExpr
    Src   *SourceLoc
    Typ   DataType
}

func (*RefExpr) Child Uses

func (e *RefExpr) Child(nth int) Expr

func (*RefExpr) ChildCount Uses

func (e *RefExpr) ChildCount() int

func (*RefExpr) ChildName Uses

func (e *RefExpr) ChildName(nth int) string

func (*RefExpr) Format Uses

func (e *RefExpr) Format(buf *bytes.Buffer, level int)

func (*RefExpr) InferredType Uses

func (e *RefExpr) InferredType() DataType

func (*RefExpr) Op Uses

func (e *RefExpr) Op() Operator

func (*RefExpr) Source Uses

func (e *RefExpr) Source() *SourceLoc

func (*RefExpr) String Uses

func (e *RefExpr) String() string

func (*RefExpr) Value Uses

func (e *RefExpr) Value() interface{}

func (*RefExpr) Visit Uses

func (e *RefExpr) Visit(visit VisitFunc) Expr

type RootExpr Uses

type RootExpr struct {
    Defines DefineSetExpr
    Rules   RuleSetExpr
    Src     *SourceLoc
}

func (*RootExpr) Child Uses

func (e *RootExpr) Child(nth int) Expr

func (*RootExpr) ChildCount Uses

func (e *RootExpr) ChildCount() int

func (*RootExpr) ChildName Uses

func (e *RootExpr) ChildName(nth int) string

func (*RootExpr) Format Uses

func (e *RootExpr) Format(buf *bytes.Buffer, level int)

func (*RootExpr) InferredType Uses

func (e *RootExpr) InferredType() DataType

func (*RootExpr) Op Uses

func (e *RootExpr) Op() Operator

func (*RootExpr) Source Uses

func (e *RootExpr) Source() *SourceLoc

func (*RootExpr) String Uses

func (e *RootExpr) String() string

func (*RootExpr) Value Uses

func (e *RootExpr) Value() interface{}

func (*RootExpr) Visit Uses

func (e *RootExpr) Visit(visit VisitFunc) Expr

type RuleExpr Uses

type RuleExpr struct {
    Comments CommentsExpr
    Name     StringExpr
    Tags     TagsExpr
    Match    *FuncExpr
    Replace  Expr
    Src      *SourceLoc
}

func (*RuleExpr) Child Uses

func (e *RuleExpr) Child(nth int) Expr

func (*RuleExpr) ChildCount Uses

func (e *RuleExpr) ChildCount() int

func (*RuleExpr) ChildName Uses

func (e *RuleExpr) ChildName(nth int) string

func (*RuleExpr) Format Uses

func (e *RuleExpr) Format(buf *bytes.Buffer, level int)

func (*RuleExpr) InferredType Uses

func (e *RuleExpr) InferredType() DataType

func (*RuleExpr) Op Uses

func (e *RuleExpr) Op() Operator

func (*RuleExpr) Source Uses

func (e *RuleExpr) Source() *SourceLoc

func (*RuleExpr) String Uses

func (e *RuleExpr) String() string

func (*RuleExpr) Value Uses

func (e *RuleExpr) Value() interface{}

func (*RuleExpr) Visit Uses

func (e *RuleExpr) Visit(visit VisitFunc) Expr

type RuleSetExpr Uses

type RuleSetExpr []*RuleExpr

func (*RuleSetExpr) Child Uses

func (e *RuleSetExpr) Child(nth int) Expr

func (*RuleSetExpr) ChildCount Uses

func (e *RuleSetExpr) ChildCount() int

func (*RuleSetExpr) ChildName Uses

func (e *RuleSetExpr) ChildName(nth int) string

func (*RuleSetExpr) Format Uses

func (e *RuleSetExpr) Format(buf *bytes.Buffer, level int)

func (*RuleSetExpr) InferredType Uses

func (e *RuleSetExpr) InferredType() DataType

func (*RuleSetExpr) Op Uses

func (e *RuleSetExpr) Op() Operator

func (RuleSetExpr) Sort Uses

func (e RuleSetExpr) Sort(less func(left, right *RuleExpr) bool)

Sort sorts the rules in the set, given a less function, while keeping the original order of equal elements. A rule that is "less than" another rule is stored stored earlier in the set.

Note that the rule set is updated in place to reflect the sorted order.

func (*RuleSetExpr) Source Uses

func (e *RuleSetExpr) Source() *SourceLoc

func (*RuleSetExpr) String Uses

func (e *RuleSetExpr) String() string

func (*RuleSetExpr) Value Uses

func (e *RuleSetExpr) Value() interface{}

func (*RuleSetExpr) Visit Uses

func (e *RuleSetExpr) Visit(visit VisitFunc) Expr

func (RuleSetExpr) WithTag Uses

func (e RuleSetExpr) WithTag(tag string) RuleSetExpr

WithTag returns the subset of rules in the set that have the given tag.

type Scanner Uses

type Scanner struct {
    // contains filtered or unexported fields
}

Scanner breaks a sequence of characters into a sequence of lexical tokens that are consumed by the parser in order to construct an Optgen AST. Each token is associated with a literal that is the string representation of that token. For many tokens, its literal is a constant. But for other tokens, like string and identifier tokens, the literal is the custom text that was scanned from the input file. Scanning stops unrecoverably at EOF, the first I/O error, or a token too large to fit in the buffer.

func NewScanner Uses

func NewScanner(r io.Reader) *Scanner

NewScanner constructs a new scanner that will tokenize the given input.

func (*Scanner) LineLoc Uses

func (s *Scanner) LineLoc() (line, pos int)

LineLoc returns the current 0-based line number and column position of the scanner in the current file.

func (*Scanner) Literal Uses

func (s *Scanner) Literal() string

Literal returns the literal associated with the last token that was scanned.

func (*Scanner) Scan Uses

func (s *Scanner) Scan() Token

Scan reads the next token from the input and returns it. The Token, Literal, and LineLoc methods are also initialized with information about the token that was read.

func (*Scanner) Token Uses

func (s *Scanner) Token() Token

Token returns the last token that was scanned.

type SliceExpr Uses

type SliceExpr []Expr

func (*SliceExpr) Child Uses

func (e *SliceExpr) Child(nth int) Expr

func (*SliceExpr) ChildCount Uses

func (e *SliceExpr) ChildCount() int

func (*SliceExpr) ChildName Uses

func (e *SliceExpr) ChildName(nth int) string

func (*SliceExpr) Format Uses

func (e *SliceExpr) Format(buf *bytes.Buffer, level int)

func (*SliceExpr) InferredType Uses

func (e *SliceExpr) InferredType() DataType

func (*SliceExpr) Op Uses

func (e *SliceExpr) Op() Operator

func (*SliceExpr) Source Uses

func (e *SliceExpr) Source() *SourceLoc

func (*SliceExpr) String Uses

func (e *SliceExpr) String() string

func (*SliceExpr) Value Uses

func (e *SliceExpr) Value() interface{}

func (*SliceExpr) Visit Uses

func (e *SliceExpr) Visit(visit VisitFunc) Expr

type SourceLoc Uses

type SourceLoc struct {
    File string
    Line int
    Pos  int
}

SourceLoc provides the original source location of an expression, including file name and line number and column position within that file. The file is the full path of the file, and the line and column locations are 0-based.

func (SourceLoc) String Uses

func (l SourceLoc) String() string

String returns the source location in "file:line:pos" format.

type StringExpr Uses

type StringExpr string

func (*StringExpr) Child Uses

func (e *StringExpr) Child(nth int) Expr

func (*StringExpr) ChildCount Uses

func (e *StringExpr) ChildCount() int

func (*StringExpr) ChildName Uses

func (e *StringExpr) ChildName(nth int) string

func (*StringExpr) Format Uses

func (e *StringExpr) Format(buf *bytes.Buffer, level int)

func (*StringExpr) InferredType Uses

func (e *StringExpr) InferredType() DataType

func (*StringExpr) Op Uses

func (e *StringExpr) Op() Operator

func (*StringExpr) Source Uses

func (e *StringExpr) Source() *SourceLoc

func (*StringExpr) String Uses

func (e *StringExpr) String() string

func (*StringExpr) Value Uses

func (e *StringExpr) Value() interface{}

func (*StringExpr) Visit Uses

func (e *StringExpr) Visit(visit VisitFunc) Expr

type TagExpr Uses

type TagExpr string

func (*TagExpr) Child Uses

func (e *TagExpr) Child(nth int) Expr

func (*TagExpr) ChildCount Uses

func (e *TagExpr) ChildCount() int

func (*TagExpr) ChildName Uses

func (e *TagExpr) ChildName(nth int) string

func (*TagExpr) Format Uses

func (e *TagExpr) Format(buf *bytes.Buffer, level int)

func (*TagExpr) InferredType Uses

func (e *TagExpr) InferredType() DataType

func (*TagExpr) Op Uses

func (e *TagExpr) Op() Operator

func (*TagExpr) Source Uses

func (e *TagExpr) Source() *SourceLoc

func (*TagExpr) String Uses

func (e *TagExpr) String() string

func (*TagExpr) Value Uses

func (e *TagExpr) Value() interface{}

func (*TagExpr) Visit Uses

func (e *TagExpr) Visit(visit VisitFunc) Expr

type TagsExpr Uses

type TagsExpr []TagExpr

func (*TagsExpr) Child Uses

func (e *TagsExpr) Child(nth int) Expr

func (*TagsExpr) ChildCount Uses

func (e *TagsExpr) ChildCount() int

func (*TagsExpr) ChildName Uses

func (e *TagsExpr) ChildName(nth int) string

func (TagsExpr) Contains Uses

func (e TagsExpr) Contains(tag string) bool

Contains returns true if the given tag is one of the tags in the collection.

func (*TagsExpr) Format Uses

func (e *TagsExpr) Format(buf *bytes.Buffer, level int)

func (*TagsExpr) InferredType Uses

func (e *TagsExpr) InferredType() DataType

func (*TagsExpr) Op Uses

func (e *TagsExpr) Op() Operator

func (*TagsExpr) Source Uses

func (e *TagsExpr) Source() *SourceLoc

func (*TagsExpr) String Uses

func (e *TagsExpr) String() string

func (*TagsExpr) Value Uses

func (e *TagsExpr) Value() interface{}

func (*TagsExpr) Visit Uses

func (e *TagsExpr) Visit(visit VisitFunc) Expr

type Token Uses

type Token int

Token is the kind of lexical token returned by the scanner (string, parentheses, comment, etc).

const (
    // ILLEGAL is the invalid token that indicates the scanner has encountered
    // an invalid lexical pattern.
    ILLEGAL Token = iota
    // ERROR indicates that the scanner encountered an error while reading from
    // the input files. The text of the error can be accessed via the Literal
    // method.
    ERROR
    // EOF indicates the scanner has reached the end of the input.
    EOF
    // IDENT is an identifier composed of Unicode letter and number runes:
    // UnicodeLetter (UnicodeLetter | UnicodeNumber)*
    IDENT
    // STRING is a literal string delimited by double quotes that cannot extend
    // past the end of a line: " [^"\n]* "
    STRING
    // NUMBER is an numeric literal composed of Unicode numeric digits:
    // UnicodeDigit+
    NUMBER
    // WHITESPACE is any sequence of Unicode whitespace characters.
    WHITESPACE
    // COMMENT is a code comment that extends to end of line: # .* EOL
    COMMENT
    // LPAREN is the open parentheses rune: (
    LPAREN
    // RPAREN is the close parentheses rune: )
    RPAREN
    // LBRACKET is the open square bracket rune: [
    LBRACKET
    // RBRACKET is the close square bracket rune: ]
    RBRACKET
    // LBRACE is the open curly brace rune: {
    LBRACE
    // RBRACE is the close curly brace rune: }
    RBRACE
    // DOLLAR is the dollar sign rune: $
    DOLLAR
    // COLON is the colon rune: :
    COLON
    // ASTERISK is the asterisk rune: *
    ASTERISK
    // EQUALS is the equals sign rune: =
    EQUALS
    // ARROW is an equals sign followed by a greater than sign: =>
    ARROW
    // AMPERSAND is the ampersand rune: &
    AMPERSAND
    // COMMA is the comma rune: ,
    COMMA
    // CARET is the caret rune: ^
    CARET
    // ELLIPSES is three periods in succession: ...
    ELLIPSES
    // PIPE is the vertical line rune: |
    PIPE
)

func (Token) String Uses

func (i Token) String() string

type VisitFunc Uses

type VisitFunc func(e Expr) Expr

VisitFunc is called by the Visit method of an expression for each child of that expression. The function can return the expression as-is, with no changes, or it can construct and return a replacement expression that the visitor will graft into a replacement tree.

Package lang imports 11 packages (graph) and is imported by 1 packages. Updated 2019-09-15. Refresh now. Tools for package owners.