opexpr

package
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 21, 2024 License: MIT, MIT Imports: 3 Imported by: 0

Documentation

Overview

Package opexpr provides a a precedence-based expression parser with O(n) performance.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func MakeNodePool

func MakeNodePool[T any, E TreeBuilder[T, E]](capacity int) *nodePool[T, E]

MakeNodePool makes a pool of shadow parse tree nodes for a given tree node type and element type.

func MakeStringSeq added in v1.0.1

func MakeStringSeq(s string) iter.Seq[StringElement]

MakeStringSeq constructs an sequence of StringElements by splitting the input string on the space character.

func ShowParseError

func ShowParseError[EP Element](pe *ParseError[EP]) string

func ShowSimpleNode

func ShowSimpleNode[E Element](n *SimpleNode[E]) string

ShowSimpleNode shows the expression rooted at its argument using '⎡' and '⎦' to delimit parse tree nodes.

Types

type Element

type Element interface {
	// ParenKind returns an integer representing the 'kind' of parenthesis. For
	// example, by assigning different kinds to '()' and '[]' you can require that
	// opening and closing parentheses are appropriately matched. Its value is
	// applicable only for OpenParen, CloseParen and CloseAllParens elements.
	ParenKind() int
	// ExpressionKind returns a value representing the kind of the expression (see
	// docs for ExpressionKind). The boolean argument is true when the expression
	// has a value to its left. This makes it possible to handle operators that
	// can be either prefix or postfix, or operators that can be either binary or
	// unary.
	ExpressionKind(hasExpressionToLeft bool) ExpressionKind
	// Precedence returns an integer representing the operator's precedence
	// relative to other operators. Lower values indicate higher precedence (i.e.
	// operators that bind tighter). The boolean argument is true when the
	// expression has a value to its left. This makes it possible to handle
	// operators that can be either prefix or postfix, or operators that can be
	// either binary or unary.
	Precedence(hasExpressionToLeft bool) int
}

Element should be implemented for pointers to the elements of the input slice

type ExpressionKind

type ExpressionKind int

ExpressionKind represents the 'kind' of an expression, i.e. whether it is a value or operator of a certain arity and associativity.

const BinaryLeftAssoc ExpressionKind = hasLeftArg | hasRightArg

BinaryLeftAssoc is the ExpressionKind for a left associative binary operator.

const BinaryRightAssoc ExpressionKind = hasLeftArg | hasRightArg | isRightAssoc

BinaryRightAssoc is the ExpressionKind for a right associative binary operator.

const CloseAllParens ExpressionKind = isParen | isCloseParen | isCloseAllParen

CloseAllParens is the ExpressionKind for a closing parenthesis that closes all currently open parentheses.

const CloseParen ExpressionKind = isParen | isCloseParen

CloseParen is the ExpressionKind for a closing parenthesis

const OpenParen ExpressionKind = isParen

OpenParen is the ExpressionKind for an opening parenthesis

const Parenthetical ExpressionKind = isParen | hasLeftArg | hasRightArg

Parenthetical is the expression kind for a parenthetical operator (such as C/Javscript's [...] indexation operator).

const Postfix ExpressionKind = hasLeftArg

Postfix is the ExpressionKind for a postfix operator.

const Prefix ExpressionKind = hasRightArg

Prefix is the ExpressionKind for a prefix operator.

const Value ExpressionKind = 0

Value is the ExpressionKind for a value.

func (ExpressionKind) String

func (k ExpressionKind) String() string

type ParseError

type ParseError[EP Element] struct {
	Kind ParseErrorKind
	Elem EP
}

ParseError represents a parse error. Elem is either to a pointer to an element or nil if Kind is ParseErrorMissingClosingParen.

func ParseSeq added in v1.0.1

func ParseSeq[T any, E TreeBuilder[T, E]](seq iter.Seq[E], pool *nodePool[T, E]) (*T, []*ParseError[E])

ParseSeq parses an sequence of input elements. It returns pointer to the root parse tree node, or nil if the input sequence is empty. It should only be necessary to provide the first type parameter (the type of the nodes in the resulting parse tree). The pool argument should be the return value of MakeNodePool().

func ParseSeqWithJuxtaposition added in v1.0.1

func ParseSeqWithJuxtaposition[T any, E TreeBuilder[T, E]](seq iter.Seq[E], juxtapositionElement *E, pool *nodePool[T, E]) (*T, []*ParseError[E])

ParseSeqWithJuxtaposition works like ParseSeq except that it takes an additional operator element. This element is used to combine juxtaposed values.

func ParseSlice

func ParseSlice[T any, E TreeBuilder[T, E]](elements []E, pool *nodePool[T, E]) (*T, []*ParseError[E])

ParseSlice parses a slice of input elements that implement the Element interface. It returns a pointer to the root parse tree node, or nil if the input slice is empty. It should only be necessary to provide the first type parameter (the type of the nodes in the resulting parse tree). The pool argument should be the return value of MakeNodePool().

func ParseSliceWithJuxtaposition

func ParseSliceWithJuxtaposition[T any, E TreeBuilder[T, E]](elements []E, juxtapositionElement *E, pool *nodePool[T, E]) (*T, []*ParseError[E])

ParseSliceWithJuxtaposition works like ParseSlice except that it takes a pointer to an additional operator element. If the pointer is non-nil, the element is used to combine juxtaposed values.

func (ParseError[T]) String

func (pe ParseError[T]) String() string

type ParseErrorKind

type ParseErrorKind int
const (
	ParseErrorUnexpectedOperator      ParseErrorKind = iota // operator found in position where it can't be incorporated into a valid parse
	ParseErrorUnexpectedValue                               // value found in position where it can't be incorporated into a valid parse
	ParseErrorUnexpectedClosingParen                        // closing parent found with no matching opening paren
	ParseErrorWrongKindOfClosingParen                       // opening paren closed with wrong kind of closing paren (e.g. '(' is closed with ']')
	ParseErrorMissingClosingParen                           // missing closing paren
)

func (ParseErrorKind) String

func (k ParseErrorKind) String() string

type SimpleNode

type SimpleNode[T Element] struct {
	Left, Right *SimpleNode[T]
	Value       T
}

SimpleNode has a trivial implementation of the TreeBuilder interface that is useful for debugging and testing

type StringElement

type StringElement string

StringElement provides a toy implementation of Element useful for writing tests.

func MakeStringElements

func MakeStringElements(s string) []StringElement

MakeStringElements constructs a slice of StringElements by splitting the input string on the space character.

func (StringElement) ExpressionKind

func (s StringElement) ExpressionKind(hasExpressionToLeft bool) ExpressionKind

func (StringElement) MakeErrorNode

func (elem StringElement) MakeErrorNode(e *ParseError[StringElement], arg1, arg2 *SimpleNode[StringElement]) *SimpleNode[StringElement]

func (StringElement) MakeNode

func (elem StringElement) MakeNode(arg1, arg2 *SimpleNode[StringElement]) *SimpleNode[StringElement]

func (StringElement) ParenKind

func (s StringElement) ParenKind() int

func (StringElement) Precedence

func (s StringElement) Precedence(_hasExpressionToLeft bool) int

func (StringElement) String

func (se StringElement) String() string

type TreeBuilder

type TreeBuilder[T any, E Element] interface {
	Element
	// Given that the receiver is an operator or an opening parenthesis, make a
	// corresponding parse tree node with the specified children. Either or both
	// of leftArg and rightArg may be nil depending on the arity and
	// prefix/postfix nature of the operator. If the receiver is an opening
	// parenthesis then leftArg is non-nil and rightArg is nil.
	MakeNode(leftArg, rightArg *T) *T
	// MakeErrorNode makes an error node given a parse error and left/right
	// children (either or both of which may be nil).
	MakeErrorNode(pe *ParseError[E], leftChild, rightChild *T) *T
}

TreeBuilder defines methods for building a tree out of input elements

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL