parser

package
v0.24.8 Latest Latest
Warning

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

Go to latest
Published: Aug 18, 2024 License: BSD-3-Clause Imports: 6 Imported by: 1

Documentation

Overview

Package parser

The parser requires a grammar built of Scanner commands.

Grammar

The parser contains a tree of Scanners. A successful match returns an implementation of the "Results" interface. Branching scanners generally produce a "ResultsList". Terminal nodes each have a matching "Results" type.

Branching scanners:

  • AllOf matches the passed matchers in order.
  • AnyOf matches any one of the passed Scanners; whichever first matches.
  • Focus changes the bounds for subsequent scanners. For instance, searching only though held objects.
  • Target changes the bounds of its first scanner in response to the results of its last scanner. Generally, this means that the last scanner should be Noun{}.

Terminal scanners:

  • Action terminates a matcher sequence, resolving to the named action. returns ResolvedAction

  • Multi matches one or more objects. returns ResolvedMulti

  • Noun matches one object held by the context. returns ResolvedNoun

  • Word matches one word. returns ResolvedWords{1}

Context

Scanners read from the world model using "Context".

  • test for plurals
  • the set of objects in reach of the player
  • the set of objects available to another object. ( ex. inside or on )

Results

The result of a successful parsing is most often a ResultList, the .Last element() of which is usually an action.

Index

Constants

View Source
const (
	// fix: anonymous kinds should be permitted to target the most recently named noun
	AllowMany genFlag = 1 << iota
	AllowAnonymous
	OnlyOne
	OnlyNamed
)

Variables

View Source
var AllWords = []string{"all", "each", "every", "both", "everything"}
View Source
var Scanners = []Scanner{
	(*Action)(nil),
	(*AllOf)(nil),
	(*AnyOf)(nil),
	(*Focus)(nil),
	(*Multi)(nil),
	(*Noun)(nil),
	(*Reverse)(nil),
	(*Refine)(nil),
	(*Word)(nil),
}

Functions

func Commas

func Commas(ids []string) (ret string)

Commas - strings into a comma separated string

func DepthOf

func DepthOf(e interface{}) (ret int)

func RankNouns

func RankNouns(bounds Bounds, cs Cursor, r RankNoun) bool

RankNouns visits each noun in a bounds, calling RankNoun. it returns false if RankNoun returns false.

Types

type Action

type Action struct {
	Name string
	Args []call.Arg
}

Action terminates a matcher sequence, resolving to the named action.

func (*Action) Scan

func (a *Action) Scan(ctx Context, bounds Bounds, cs Cursor) (ret Result, err error)

Scan matches only if the cursor has finished with all words.

type AllOf

type AllOf struct {
	Match []Scanner
}

AllOf matches the passed Scanners in order.

func (*AllOf) Scan

func (m *AllOf) Scan(ctx Context, bounds Bounds, cs Cursor) (Result, error)

type AlwaysError added in v0.24.7

type AlwaysError struct{}

func (AlwaysError) Scan added in v0.24.7

func (n AlwaysError) Scan(ctx Context, bounds Bounds, cs Cursor) (ret Result, err error)

type AmbiguousObject

type AmbiguousObject struct {
	Nouns []NounInstance
	Depth
}

func (AmbiguousObject) Error

func (a AmbiguousObject) Error() string

type AnyOf

type AnyOf struct {
	Match []Scanner
}

AnyOf matches any one of the passed Scanners; whichever first matches.

func (*AnyOf) Scan

func (m *AnyOf) Scan(ctx Context, bounds Bounds, cs Cursor) (ret Result, err error)

Scan implements Scanner.

type Bounds

type Bounds func(NounVisitor) bool

Bounds encapsulates some set of objects. Searches visits every object in the set defined by the bounds. note: we use a visitor to support map traversal without copying keys if need be.

type Commands

type Commands struct {
	*Action
	*AllOf
	*AnyOf
	*Focus
	*Multi
	*Noun
	*Refine
	*Word
}

Commands - reference for all of objects implementing Scanner

type Context

type Context interface {
	Surveyor
	Language
}

type Cursor

type Cursor struct {
	Pos   int
	Words []string
}

func (Cursor) CurrentWord

func (cs Cursor) CurrentWord() (ret string)

func (Cursor) Skip

func (cs Cursor) Skip(i int) Cursor

type Depth

type Depth int

func (Depth) ErrorDepth

func (d Depth) ErrorDepth() int

type Eat

type Eat struct {
	Scanner Scanner
}

Eat absorbs existing results

func (*Eat) Scan

func (w *Eat) Scan(ctx Context, bounds Bounds, cs Cursor) (ret Result, err error)

type ErrorDepth

type ErrorDepth interface {
	ErrorDepth() int
}

type Filter

type Filter interface {
	MatchesNoun(NounInstance) bool
}

type FilterSpec

type FilterSpec struct {
	*HasAttr
	*HasClass
	*Filters
}

type Filters

type Filters []Filter

func (Filters) MatchesNoun

func (fs Filters) MatchesNoun(n NounInstance) bool

type Focus

type Focus struct {
	Where string
	Match Scanner
}

Focus - a Scanner which changes the bounds for subsequent scanners. For instance, searching only though held objects.

func (*Focus) Scan

func (a *Focus) Scan(ctx Context, _ Bounds, cs Cursor) (ret Result, err error)

type HasAttr

type HasAttr struct {
	Name string
}

func (*HasAttr) MatchesNoun

func (f *HasAttr) MatchesNoun(n NounInstance) bool

type HasClass

type HasClass struct {
	Name string
}

func (*HasClass) MatchesNoun

func (f *HasClass) MatchesNoun(n NounInstance) bool

type Language

type Language interface {
	// return true if the passed word is a plural word.
	IsPlural(word string) bool
}

type MismatchedWord

type MismatchedWord struct {
	Want, Have string
	Depth
}

func (MismatchedWord) Error

func (a MismatchedWord) Error() string

type MissingObject

type MissingObject struct {
	Depth
}

func (MissingObject) Error

func (a MissingObject) Error() string

type Multi

type Multi struct {
	Filters Filters
}

Multi matches one or more objects. (plus or minus some ambiguity)

func (*Multi) Scan

func (try *Multi) Scan(ctx Context, bounds Bounds, cs Cursor) (ret Result, err error)

type NoSuchObjects

type NoSuchObjects struct {
	Depth
}

NoSuchObjects after asking for multiple items, and finding none.

func (NoSuchObjects) Error

func (NoSuchObjects) Error() string

type Noun

type Noun struct {
	Filters Filters
}

Noun matches one object held by the context. (plus or minus some ambiguity)

func (*Noun) Scan

func (try *Noun) Scan(ctx Context, bounds Bounds, cs Cursor) (ret Result, err error)

type NounInstance

type NounInstance interface {
	// String id of the noun. Returned via ResultList.Objects() on a successful match.
	String() string
	// does the passed plural string apply to this object?
	// low-bar would be to return the same result as class,
	// better might be looking at plural printed name.
	HasPlural(string) bool
	// does the passed name apply to this object?
	HasName(string) bool
	// does the noun satisfy the passed named class?
	HasClass(string) bool
	// does the noun have the passed name attribute?
	HasAttribute(string) bool
}

NounInstance - allows parser to ask questions about a particular object. fix? it might be nicer for callers if these methods were part of context

type NounVisitor

type NounVisitor func(NounInstance) bool

If the visitor function returns true, the search terminates and returns true; otherwise it returns false.

type Overflow

type Overflow struct {
	Depth
}

Overflow when we expect to be done, but input tokens remain.

func (Overflow) Error

func (Overflow) Error() string

type RankAll

type RankAll struct {
	Filters
	Context Context
	// we dont know what follows the keyword "all"
	// if it turns out that its a word which identifies one or more objects
	// then we really dont want "all" anymore, we simply want those objects.
	// in the meantime, accumulate all "unmentioned" objects
	Implied   []NounInstance
	Plurals   []string
	WordCount int
	Ranking
}

func (*RankAll) RankNoun

func (m *RankAll) RankNoun(cs Cursor, n NounInstance) bool

RankNoun - never returns fals.

type RankNoun

type RankNoun interface {
	// returning false indicates some critical error that should cancel ranking.
	RankNoun(Cursor, NounInstance) bool
}

RankNoun implementations accumulate targets for actions during calls to RankNouns.

type RankOne

type RankOne struct {
	Filters
	Ranking
}

func (*RankOne) RankNoun

func (m *RankOne) RankNoun(cs Cursor, n NounInstance) bool

RankNoun - never returns false

type Ranking

type Ranking struct {
	Rank  int
	Nouns []NounInstance
}

Ranking accumulates Nouns at a given Rank. Rank counts the number of words that match a given NounInstance It's possible for different nouns to share the same rank for some given set of words. For example, the "real eiffel tower" and the "toy eiffel tower" would share a rank of two for the words: "tower eiffel"

func (*Ranking) AddRanking

func (r *Ranking) AddRanking(n NounInstance, rank int)

func (*Ranking) Empty

func (r *Ranking) Empty() bool

type Refine

type Refine struct {
	Match []Scanner
}

Refine changes the bounds of its first scanner in response to the results of its last scanner. Generally, this means that the preceding scanner should be Noun{}.

func (*Refine) Scan

func (a *Refine) Scan(ctx Context, bounds Bounds, start Cursor) (ret Result, err error)

type ResolvedAction

type ResolvedAction struct {
	*Action
}

func (ResolvedAction) String

func (f ResolvedAction) String() string

func (ResolvedAction) WordsMatched

func (f ResolvedAction) WordsMatched() int

type ResolvedMulti

type ResolvedMulti struct {
	Nouns     []NounInstance
	WordCount int
}

func (ResolvedMulti) String

func (f ResolvedMulti) String() string

func (ResolvedMulti) WordsMatched

func (f ResolvedMulti) WordsMatched() int

type ResolvedNoun

type ResolvedNoun struct {
	NounInstance NounInstance
	Words        []string // what the user said to identify the object
}

func (ResolvedNoun) String

func (f ResolvedNoun) String() string

func (ResolvedNoun) WordsMatched

func (f ResolvedNoun) WordsMatched() int

type ResolvedWords

type ResolvedWords struct {
	Words     string
	WordCount int
}

func (ResolvedWords) String

func (f ResolvedWords) String() string

func (ResolvedWords) WordsMatched

func (f ResolvedWords) WordsMatched() int

type Result

type Result interface {
	// the number of words used to match this result.
	WordsMatched() int
}

Results used by the parser include, a list of results, a resolved object, a resolved action, etc. On success, the parser generally returns a ResultList as its primary result.

type ResultList

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

ResultList contains multiple results. Its methods help tease out its contents. Most often when a parsing succeeds, it will return a ResultList and the .Last() element of the list will be an Action

func (*ResultList) Last

func (rs *ResultList) Last() (ret Result, okay bool)

Last result in the list, true if the list was not empty. Generally, when the parser succeeds, this is an Action.

func (*ResultList) Objects

func (rs *ResultList) Objects() (ret []string)

Objects -- all nouns used by this result. the returned objects are strings in the string id format

func (*ResultList) PrettyObjects

func (rs *ResultList) PrettyObjects() string

func (*ResultList) Results

func (rs *ResultList) Results() []Result

func (*ResultList) String

func (rs *ResultList) String() string

func (*ResultList) WordsMatched

func (rs *ResultList) WordsMatched() int

WordsMatched returns the number of words matched.

type Reverse

type Reverse struct {
	Match []Scanner
}

Reverse swaps the first and last matches after scanning as per "AllOf". Generally, the first and last scanners are nouns.

func (*Reverse) Scan

func (m *Reverse) Scan(ctx Context, bounds Bounds, cs Cursor) (ret Result, err error)

type Scanner

type Scanner interface {
	// Scan for results.
	// note: by design, cursor may be out of range when scan is called.
	Scan(Context, Bounds, Cursor) (Result, error)
}

Scanner searches words looking for good results. ( perhaps its truly a tokenzer and the results, tokens )

type Surveyor

type Surveyor interface {
	// the range of the player's known universe.
	// string names are defined by the "Focus" parts of a Scanner grammar.
	// for example, maybe "held" for objects held by the player.
	// the empty string is used as the default range when no focus has been declared.
	GetBounds(who, where string) (Bounds, error)
}

type Underflow

type Underflow struct {
	Depth
}

Underflow when we expect a word, but the input is empty

func (Underflow) Error

func (Underflow) Error() string

type UnknownObject

type UnknownObject struct {
	Depth
}

func (UnknownObject) Error

func (UnknownObject) Error() string

type Word

type Word struct {
	Word string
}

Word matches one word.

func (*Word) Scan

func (w *Word) Scan(ctx Context, bounds Bounds, cs Cursor) (ret Result, err error)

type Words

type Words []string

Words - match one of the specified words. if the last word is blank and nothing matches, it will defer the decision re: a/an/--

func (Words) Scan

func (ws Words) Scan(ctx Context, bounds Bounds, cs Cursor) (ret Result, err error)

Jump to

Keyboard shortcuts

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