Documentation
¶
Overview ¶
Package tabnas provides a lenient JSON parser that supports relaxed syntax including unquoted keys, implicit objects/arrays, comments, trailing commas, single-quoted strings, path diving (nested object shorthand), and more.
It is a Go port of the tabnas TypeScript library, faithfully implementing the same matcher-based lexer and rule-based parser architecture.
Index ¶
- Constants
- Variables
- func Deep(base any, rest ...any) any
- func Describe(j *Tabnas) string
- func IsFuncRef(s string) bool
- func IsSkip(v any) bool
- func IsUndefined(v any) bool
- func Keys(m map[string]any) []string
- func LookupRef(ref map[FuncRef]any, name string) any
- func ModList(list []any, opts *ModListOpts) []any
- func NodeListAppend(node any, val any) any
- func NodeMapSet(node any, key string, val any) any
- func NormAlt(alt *AltSpec) error
- func NormAlts(spec *RuleSpec) error
- func Omap(m map[string]any, fn func(Entry) []any) map[string]any
- func RegisterTextParser(p func(src string) (any, error))
- func RequireRef(ref map[FuncRef]any, name string, kind string) (any, error)
- func ResolveFuncRefs(obj any, ref map[FuncRef]any) any
- func Scan(src string, startSI, startRI, startCI int, spec *ScanSpec, out *ScanOut) bool
- func Snip(s string, maxlen int) string
- func Str(val any, maxlen int) string
- func StrInject(template string, vals any) string
- func UnwrapUndefined(v any) any
- func ValidateGroupTags(g string) error
- func Values(m map[string]any) []any
- type AltAction
- type AltCond
- type AltError
- type AltModListOpts
- type AltModifier
- type AltSpec
- type ColorConfig
- type ColorOptions
- type CommentDef
- type CommentOptions
- type CondOp
- type ConfigModifier
- type Context
- type EagerRegexp
- type Entry
- type ErrMsgOptions
- type FixedOptions
- type FuncRef
- type GrammarAltListSpec
- type GrammarAltSpec
- type GrammarInjectSpec
- type GrammarRuleSpec
- type GrammarSetting
- type GrammarSettingAlt
- type GrammarSettingRule
- type GrammarSpec
- type InfoOptions
- type Lex
- type LexCheck
- type LexCheckResult
- type LexConfig
- type LexMatcher
- type LexOptions
- type LexSub
- type LineOptions
- type ListOptions
- type ListRef
- type MakeLexMatcher
- type MapMergeFunc
- type MapOptions
- type MapRef
- type MatchOptions
- type MatchSpec
- type MatchTokenEntry
- type MatchValueEntry
- type MatchValueSpec
- type MatcherEntry
- type ModListOpts
- type NumberOptions
- type Options
- type ParseOptions
- type Parser
- type ParserOptions
- type Plugin
- type Point
- type PropertyOptions
- type ResultOptions
- type RewindOptions
- type Rule
- func (r *Rule) Eq(counter string, limit int) bool
- func (r *Rule) Gt(counter string, limit int) bool
- func (r *Rule) Gte(counter string, limit int) bool
- func (r *Rule) Lt(counter string, limit int) bool
- func (r *Rule) Lte(counter string, limit int) bool
- func (r *Rule) Process(ctx *Context, lex *Lex) *Rule
- type RuleDefiner
- type RuleOptions
- type RuleSpec
- func (rs *RuleSpec) Actions(phase string) []StateAction
- func (rs *RuleSpec) AddAC(action StateAction) *RuleSpec
- func (rs *RuleSpec) AddAO(action StateAction) *RuleSpec
- func (rs *RuleSpec) AddBC(action StateAction) *RuleSpec
- func (rs *RuleSpec) AddBO(action StateAction) *RuleSpec
- func (rs *RuleSpec) AddClose(alts ...*AltSpec) *RuleSpec
- func (rs *RuleSpec) AddOpen(alts ...*AltSpec) *RuleSpec
- func (rs *RuleSpec) Clear() *RuleSpec
- func (rs *RuleSpec) ClearActions(phases ...string) *RuleSpec
- func (rs *RuleSpec) ClearClose() *RuleSpec
- func (rs *RuleSpec) ClearOpen() *RuleSpec
- func (rs *RuleSpec) CloseAlts() []*AltSpec
- func (rs *RuleSpec) Fnref(ref map[FuncRef]any) *RuleSpec
- func (rs *RuleSpec) HasAC() bool
- func (rs *RuleSpec) HasAO() bool
- func (rs *RuleSpec) HasBC() bool
- func (rs *RuleSpec) HasBO() bool
- func (rs *RuleSpec) ModifyClose(mods *AltModListOpts) *RuleSpec
- func (rs *RuleSpec) ModifyOpen(mods *AltModListOpts) *RuleSpec
- func (rs *RuleSpec) OpenAlts() []*AltSpec
- func (rs *RuleSpec) PrependAC(action StateAction) *RuleSpec
- func (rs *RuleSpec) PrependAO(action StateAction) *RuleSpec
- func (rs *RuleSpec) PrependBC(action StateAction) *RuleSpec
- func (rs *RuleSpec) PrependBO(action StateAction) *RuleSpec
- func (rs *RuleSpec) PrependClose(alts ...*AltSpec) *RuleSpec
- func (rs *RuleSpec) PrependOpen(alts ...*AltSpec) *RuleSpec
- type RuleState
- type RuleSub
- type SafeOptions
- type ScanOut
- type ScanSpec
- type SpaceOptions
- type StateAction
- type StringOptions
- type Tabnas
- func (j *Tabnas) Config() *LexConfig
- func (j *Tabnas) Decorate(name string, value any) *Tabnas
- func (j *Tabnas) Decoration(name string) any
- func (j *Tabnas) Derive(opts ...Options) (result *Tabnas, err error)
- func (j *Tabnas) FixedSrc(src string) Tin
- func (j *Tabnas) FixedTin(tin Tin) string
- func (j *Tabnas) Grammar(gs *GrammarSpec, setting ...*GrammarSetting) (err error)
- func (j *Tabnas) GrammarText(text string, setting ...*GrammarSetting) (err error)
- func (j *Tabnas) Id() string
- func (j *Tabnas) Options() Options
- func (j *Tabnas) Parse(src string) (any, error)
- func (j *Tabnas) ParseMeta(src string, meta map[string]any) (any, error)
- func (j *Tabnas) PluginOptions(name string) map[string]any
- func (j *Tabnas) Plugins() []Plugin
- func (j *Tabnas) RSM() map[string]*RuleSpec
- func (j *Tabnas) Rule(name string, definer RuleDefiner) *Tabnas
- func (j *Tabnas) SetOptions(opts Options) *Tabnas
- func (j *Tabnas) SetOptionsText(text string) (result *Tabnas, err error)
- func (j *Tabnas) SetPluginOptions(name string, opts map[string]any)
- func (j *Tabnas) SetTokenSet(name string, tins []Tin)
- func (j *Tabnas) Sub(lexSub LexSub, ruleSub RuleSub) *Tabnas
- func (j *Tabnas) TinName(tin Tin) string
- func (j *Tabnas) Token(name string, src ...string) Tin
- func (j *Tabnas) TokenSet(name string) []Tin
- func (j *Tabnas) Use(plugin Plugin, opts ...map[string]any) (err error)
- func (j *Tabnas) UseDefaults(plugin Plugin, defaults map[string]any, opts ...map[string]any) (err error)
- func (j *Tabnas) Util() UtilBag
- type TabnasError
- type Text
- type TextOptions
- type Tin
- type Token
- type TokenValFunc
- type UtilBag
- type ValModifier
- type ValueDef
- type ValueDefEntry
- type ValueOptions
Constants ¶
const ( ScanConsume int32 = 1 << 16 // Consume the char and advance position. ScanIsRow int32 = 1 << 17 // rI++ and cI = 1 ScanCIReset int32 = 1 << 18 // cI = 1 without rI++ (line chars in multi-line strings) ScanStop int32 = 1 << 19 // End the walk after applying this action. ScanStateMask int32 = 0xffff // Bits holding the next state. )
Scan action flags and state mask (TS: CONSUME, IS_ROW, CI_RESET, STOP, STATE_MASK).
const BUILTIN_SCHEMA_VERSION = 2
BUILTIN_SCHEMA_VERSION is the config-schema version these builtins implement. A serialized grammar declaring GrammarSpec.V greater than this is refused at load. Absent (zero) ⇒ treated as version 1.
const Version = "0.2.0"
Version is the current version of the tabnas Go module.
Variables ¶
var ( TinSetIGNORE = map[Tin]bool{TinSP: true, TinLN: true, TinCM: true} // Tokens skipped during parsing: space, line, comment. TinSetVAL = []Tin{TinTX, TinNR, TinST, TinVL} // Tins allowed as a value: text, number, string, value. TinSetKEY = []Tin{TinTX, TinNR, TinST, TinVL} // Tins allowed as a key (same set as VAL). )
Named groupings of token Tins used by the lexer and parser.
var BUILTIN_REFS = map[FuncRef]any{ "@node$": AltAction(builtinNode), "@capture$": AltAction(builtinCapture), "@bubble$": AltAction(builtinBubble), "@probeInit$": AltAction(builtinProbeInit), "@probeDecide$": AltAction(builtinProbeDecide), "@probePhase0$": AltCond(builtinProbePhase0), "@probePhase1$": AltCond(builtinProbePhase1), "@probePhase2$": AltCond(builtinProbePhase2), "@object$": AltAction(builtinObject), "@array$": AltAction(builtinArray), "@reset$": AltAction(builtinReset), "@key$": AltAction(builtinKey), "@setval$": AltAction(builtinSetval), "@push$": AltAction(builtinPush), "@value$": AltAction(builtinValue), }
BUILTIN_REFS is the standard builtin library. Tree/probe/value actions are registered as AltAction; the phase guards as AltCond — the resolver type-asserts the concrete type per field.
var FixedTokens = map[string]Tin{ "{": TinOB, "}": TinCB, "[": TinOS, "]": TinCS, ":": TinCL, ",": TinCA, }
Fixed token source map: character -> Tin
var NoToken = &Token{Name: "", Tin: -1, SI: -1, RI: -1, CI: -1}
NoToken is a sentinel token indicating "no token".
var Skip any = &skipType{}
var Undefined any = &undefinedType{}
Functions ¶
func Deep ¶
Deep recursively merges values (maps, slices, structs via reflection); zero/nil overlays preserve base. Deep(map[string]any{"a":1}, map[string]any{"b":2}) // => {"a":1,"b":2}
func Describe ¶
Describe returns a human-readable description of a Tabnas instance's configuration. It lists tokens, fixed tokens, rules, custom matchers, plugins, subscriptions, and key config settings.
func IsFuncRef ¶
IsFuncRef reports whether a string is a function reference (starts with "@"). IsFuncRef("@foo") // => true; IsFuncRef("foo") // => false
func IsUndefined ¶
IsUndefined checks if a value is the Undefined sentinel.
func Keys ¶
Keys returns the map's keys in sorted order; a nil map returns an empty slice. Keys(map[string]any{"b":2,"a":1}) // => ["a","b"]; Keys(nil) // => []
func LookupRef ¶
LookupRef returns the FuncRef value for name, or nil when absent. LookupRef(map[FuncRef]any{"@f":fn}, "@x") // => nil
func ModList ¶
func ModList(list []any, opts *ModListOpts) []any
ModList applies delete, then move, then custom operations to a list (mirrors the TypeScript modlist()). ModList([]any{"a","b"}, &ModListOpts{Delete: []int{0}}) // => ["b"]
func NodeListAppend ¶
NodeListAppend appends val to node — either a ListRef wrapper (info mode) or a plain []any — and returns the (possibly reallocated) node. Promoted from @tabnas/json. Go slices are value types, so the caller must use the returned node (and re-publish it to the parent rule).
func NodeMapSet ¶
NodeMapSet assigns val under key into node — either a MapRef wrapper (info mode) or a plain map[string]any — and returns the node. Promoted from @tabnas/json so the info-aware native-value builders (@setval$) operate on the engine's own value model. The map contents are a reference type, so the assignment is visible through any copy of the MapRef value.
func NormAlt ¶
NormAlt normalizes an AltSpec by converting a declarative CD condition into a C function and validating the G tag format. Returns a non-nil error if any G tag fails the group-tag regex; callers must check the return value and surface the error (no panics).
func NormAlts ¶
NormAlts normalizes all alternates in a RuleSpec. Returns the first validation error encountered, if any.
func Omap ¶
Omap maps over an object's entries, where fn returns alternating key/value items: [k,v] rewrites the pair, [k,v,k2,v2,...] adds keys, [nil,_] drops it. Omap(map[string]any{"a":1}, func(e Entry) []any { return []any{e.Key, 9} }) // => {"a":9}
func RegisterTextParser ¶
RegisterTextParser sets the parser used by SetOptionsText and GrammarText. Grammar packages call this from init(); the last registration wins.
func RequireRef ¶
RequireRef looks up a FuncRef by name, returning a grammar error when absent (kind labels the error). RequireRef(map[FuncRef]any{"@f":fn}, "@f", "val") // => (fn, nil)
func Scan ¶
Scan walks src from (startSI, startRI, startCI) according to spec, writing the reached positions into out. Reports whether any byte was consumed (TS: scan).
Takes raw position numbers rather than a Point because some callers (notably the comment matcher) track positions as locals against a sliced fwd string rather than on the lex's pnt.
func Snip ¶
Snip truncates s to maxlen bytes and replaces \r, \n, \t with '.' (for debug/display output). Snip("a\nbcd", 3) // => "a.b"
func Str ¶
Str renders a value to a string, truncating to maxlen ("..." marks truncation) then snipping \r\n\t. Returns "" when maxlen <= 0. Mirrors the TypeScript str() + snip() pipeline. Str("hello", 4) // => "h..."
func StrInject ¶
StrInject substitutes {key} / {key.subkey} placeholders in template from a map or array; unknown vals returns template unchanged. StrInject("hi {n}", map[string]any{"n":"x"}) // => "hi x"
func UnwrapUndefined ¶
UnwrapUndefined converts Undefined sentinels to nil in the result.
func ValidateGroupTags ¶
ValidateGroupTags returns an error if any tag in the supplied comma-separated string fails the group-tag regex.
Types ¶
type AltCond ¶
AltCond is a condition function for an alternate.
func MakeRuleCond ¶
MakeRuleCond creates an AltCond function from a comparison operator, property path, and value. Matches the TypeScript makeRuleCond(co, prop, subprop, val) function. When the property is not set (missing), the condition returns true.
type AltModListOpts ¶
type AltModListOpts struct {
Clear bool // Empty the existing list before applying.
Delete []int // Indices to delete (supports negative).
Move []int // Pairs: [from, to, from, to, ...].
Custom func(list []*AltSpec) []*AltSpec // Custom modification callback.
}
AltModListOpts configures modifications to a RuleSpec alternate list (TS ListMods).
type AltModifier ¶
AltModifier can modify an alt match result. Returns the (possibly modified) AltSpec.
type AltSpec ¶
type AltSpec struct {
S [][]Tin // Per-position Tin sets to match: S[i] for lookahead token i (empty = wildcard)
P string // Push rule name (create child)
R string // Replace rule name (create sibling)
B int // Move token pointer backward (backtrack)
C AltCond // Custom condition (function)
CD map[string]any // Declarative condition (converted to C by NormAlt)
N map[string]int // Counter increments
A AltAction // Match action
U map[string]any // Custom props added to Rule.U
K map[string]any // Custom props added to Rule.K (propagated)
G string // Named group tags (comma-separated)
H AltModifier // Alt modifier (called after match to potentially modify the alt)
E AltError // Error generation
PF func(r *Rule, ctx *Context) string // Dynamic push rule name
RF func(r *Rule, ctx *Context) string // Dynamic replace rule name
BF func(r *Rule, ctx *Context) int // Dynamic backtrack
}
AltSpec defines a parse alternate specification.
func ParseAlts ¶
ParseAlts attempts to match one of the alternates.
Supports arbitrary N-token lookahead: an alt's S slice may declare any number of positions (previously capped at 2). Tokens are fetched lazily - position i is only requested after position i-1 matches.
func ResolveGrammarAltStatic ¶
func ResolveGrammarAltStatic(ga *GrammarAltSpec, ref map[FuncRef]any) *AltSpec
ResolveGrammarAltStatic converts a GrammarAltSpec to a concrete AltSpec using only built-in token resolution. Used by the internal Grammar(). Errors cause the returned alt to have nil fields (best-effort).
type ColorConfig ¶
type ColorConfig struct {
Active bool // When false, Codes returns empty strings.
Reset string // Reset/clear escape sequence.
Hi string // High-emphasis (highlight) escape sequence.
Lo string // Low-emphasis (dim) escape sequence.
Line string // Line-number escape sequence.
}
Resolved ANSI-escape palette for error formatting; when Active is false all codes emit as empty strings.
func (ColorConfig) Codes ¶
func (c ColorConfig) Codes() (hi, lo, line, reset string)
Codes returns the four escape sequences the formatter needs as plain strings. When Active is false they are all empty, so the formatter can append them unconditionally.
type ColorOptions ¶
type ColorOptions struct {
Active *bool // Toggle colour output; *Active false disables it entirely. Default: true.
Reset string // Clears all colour/style attributes. Default: ESC[0m.
Hi string // Highlights the error header ([tag/code]:). Default: ESC[91m.
Lo string // Dims trailing suffix material (diagnostics, links). Default: ESC[2m.
Line string // Colours the source-location arrow and line-number gutter. Default: ESC[34m.
}
ColorOptions sets the ANSI escape codes used when formatting a TabnasError (TS options.color).
type CommentDef ¶
type CommentDef struct {
Line bool // true = line comment, false = block comment.
Start string // Start marker, e.g. "#", "//", "/*".
End string // End marker for block comments, e.g. "*/".
Lex *bool // Enable this comment type. Default: true.
EatLine *bool // Also consume trailing line chars. Default: false.
// Suffix terminates a comment body at an extra marker beyond its natural end
// (line char for line comments, End for block); the matched suffix is CONSUMED
// as the last part of the body. EatLine only fires for line-char termination
// and does not stack with Suffix consumption (TS options.comment.def.<name>.suffix).
// Accepts one of:
// string — single suffix marker.
// []string — any of these markers terminates.
// LexMatcher — custom terminator probe; a non-nil token terminates and
// len(token.Src) characters are consumed.
Suffix any
}
CommentDef defines a single comment type.
type CommentOptions ¶
type CommentOptions struct {
Lex *bool // Enable all comment lexing. Default: true.
Def map[string]*CommentDef // Comment type definitions.
Check LexCheck // Hook invoked before the comment matcher runs (TS options.comment.check).
}
CommentOptions controls comment lexing.
type CondOp ¶
type CondOp struct {
Op string // Comparison operator ($eq, $ne, $lt, $lte, $gt, $gte).
Val int // Value to compare the rule property against.
}
CondOp is a declarative comparison (operator + value) used in AltSpec.CD, e.g. { 'n.pk': { $lte: 0 } }.
type ConfigModifier ¶
ConfigModifier is a function that modifies the LexConfig after construction.
type Context ¶
type Context struct {
UI int // Unique rule ID counter (TS: uI).
// Generalized lookahead buffer: T[i] is the token at position i, or NoToken
// if that slot is not yet fetched. Supersedes the legacy T0/T1 two-slot
// fields, which are kept in sync for backward compatibility.
T []*Token
T0 *Token // Alias of T[0] (legacy), kept in sync with T[0].
T1 *Token // Alias of T[1] (legacy), kept in sync with T[1].
V1 *Token // Previous token (TS: v1).
V2 *Token // Previous-previous token (TS: v2).
// Consumed-token rewind history: V holds the tokens consumed so far, bounded
// by cfg.RewindHistory (a ring buffer trimmed from the front). VAbs is the
// absolute consumed count used as the Mark() value, decoupled from len(V) so
// the ring-buffer cap can evict old tokens without invalidating live marks.
V []*Token // Retained consumed-token ring buffer (TS: v).
VAbs int // Absolute count of consumed tokens; the Mark() value (TS: vAbs).
Lex *Lex // Attached by startParse; used by Rewind to re-feed tokens.
RS []*Rule // Rule stack (TS: rs).
RSI int // Rule stack index (TS: rsI).
RSM map[string]*RuleSpec // Rule spec map (TS: rsm).
KI int // Iteration counter (TS: kI).
Rule *Rule // Current parsing rule (TS: rule).
Meta map[string]any // Parse metadata (TS: meta).
LexSubs []LexSub // Lex event subscribers (TS: sub.lex).
RuleSubs []RuleSub // Rule event subscribers (TS: sub.rule).
ParseErr *Token // Error token; when set, halts the parse.
Opts *Options // Tabnas instance options (TS: opts).
Cfg *LexConfig // Tabnas instance config (TS: cfg).
Src string // Source text being parsed (TS: src).
Inst *Tabnas // Current Tabnas instance (TS: inst).
U map[string]any // Custom plugin data bag (TS: u).
Root *Rule // Root rule (TS: root).
TC int // Token count (TS: tC).
F func(any) string // Format a value as a string (TS: F).
Log func(...any) // Debug logger (TS: log).
NOTOKEN *Token // Sentinel no-token (TS: NOTOKEN).
NORULE *Rule // Sentinel no-rule (TS: NORULE).
}
Mutable parse state threaded through every rule, matching the TS Context type.
func (*Context) Mark ¶
Mark records a rewind point at the current parse position. The returned value can be passed to Rewind to replay the tokens consumed since the mark. Mirrors TS ctx.mark().
func (*Context) Rewind ¶
Rewind replays the tokens consumed since the given mark, re-feeding them through the lexer's pending-token queue so the parser re-reads them. Returns an error if the mark has been evicted from the retained history window (cfg.RewindHistory was too small for the grammar). Mirrors TS ctx.rewind(), which throws in that case; Go reports it as an error to preserve the no-panic guarantee.
type EagerRegexp ¶
ResolveFuncRefs recursively rewrites FuncRef strings within nested maps/slices:
- "@@prefix" → literal "@prefix"
- "@SKIP" → Skip sentinel
- "@/pattern/flags" → *regexp.Regexp
- "@name" → function from ref map
ResolveFuncRefs("@SKIP", nil) // => Skip EagerRegexp wraps a match-token regexp flagged eager: it opts out of the lexer's "expected at this rule position" gating, firing whenever its pattern matches. Produced by the @~/pattern/flags ref form; carried into Options.Match.TokenEager by MapToOptions.
type ErrMsgOptions ¶
type ErrMsgOptions struct {
// Name sets the error tag in formatted messages.
// Default: "tabnas". E.g. Name="bar" → "[bar/unexpected]: ..."
Name string
// Suffix controls trailing text after an error message (TS bool|string|func).
// Permitted concrete types (stored as any for parity with the polymorphic TS field):
// bool — true (default) enables the standard suffix, false disables.
// string — literal text appended to the error message.
// func(code, src string) string — dynamic suffix computation.
Suffix any
// Link is an optional "see also" line (e.g. a docs URL) rendered inside
// the standard error suffix. Only shown when Suffix is unset or true.
Link string
}
ErrMsgOptions controls error message formatting (TS options.errmsg).
type FixedOptions ¶
type FixedOptions struct {
Lex *bool // Enable fixed tokens. Default: true.
// Token overrides the source string for named fixed tokens.
// Mirrors TS `options.fixed.token` (a StrMap of name → src).
// Keys are token names (e.g. "#CA"). Values:
// - non-nil string pointer: set that name's fixed source, removing any
// previous source for the same name ("#CA" → ";" swaps the comma).
// Unknown names are allocated a new Tin (matches (*Tabnas).Token).
// - nil pointer: remove the name's fixed mapping(s) from the lexer.
Token map[string]*string
// Check is a LexCheck hook invoked before the fixed matcher runs; return nil
// to continue normal matching or a LexCheckResult to override (TS options.fixed.check).
Check LexCheck
}
FixedOptions controls fixed token recognition.
type FuncRef ¶
type FuncRef = string
FuncRef is a string starting with "@" that references a function in a Ref map.
type GrammarAltListSpec ¶
type GrammarAltListSpec struct {
Alts []*GrammarAltSpec // Alternates to install.
Inject *GrammarInjectSpec // How to merge Alts into existing alternates (nil = default prepend).
}
Alt specs paired with injection modifiers controlling how they merge into a rule.
type GrammarAltSpec ¶
type GrammarAltSpec struct {
S any // Token spec: string ("#KEY #CL", each name a slot) or []string (per-element alternatives).
B any // Backtrack: int or FuncRef string.
P string // Push rule name or FuncRef.
R string // Replace rule name or FuncRef.
A any // Action: FuncRef string, or []any of refs/AltActions run in order.
E FuncRef // Error function ref.
H FuncRef // Modifier function ref.
C any // Condition: FuncRef string or map[string]any for declarative.
N map[string]int // Counter increments.
U map[string]any // Custom props.
K map[string]any // Propagated custom props.
G string // Group tags (comma-separated).
}
Declarative alternate spec: token fields use "#NAME" strings, function fields use "@name" FuncRefs.
type GrammarInjectSpec ¶
type GrammarInjectSpec struct {
Append bool // If true, append; if false, prepend (default).
Clear bool // If true, empty the existing alternates before inserting.
Delete []int // Indices to delete (supports negative).
Move []int // Pairs: [from, to, from, to, ...].
}
GrammarInjectSpec controls how alts are merged into existing rule alternates.
type GrammarRuleSpec ¶
type GrammarRuleSpec struct {
Open any // Opening alternates: []*GrammarAltSpec or *GrammarAltListSpec.
Close any // Closing alternates: []*GrammarAltSpec or *GrammarAltListSpec.
}
Open and close alternates for a single rule (each: []*GrammarAltSpec or *GrammarAltListSpec).
type GrammarSetting ¶
type GrammarSetting struct {
Rule *GrammarSettingRule // Rule-level settings to apply across the grammar.
}
Optional settings applied when a grammar spec is installed; its Rule.Alt.G tags are appended to every rule-alt G.
type GrammarSettingAlt ¶
type GrammarSettingAlt struct {
G any // Group tag(s) appended to each alt's G: string (comma-separated) or []string.
}
Per-alt grammar settings (currently only group tags).
type GrammarSettingRule ¶
type GrammarSettingRule struct {
Alt *GrammarSettingAlt // Per-alt settings applied to every rule-alt.
}
Rule-level grammar settings, wrapping alt-level settings.
type GrammarSpec ¶
type GrammarSpec struct {
Ref map[FuncRef]any // Maps FuncRef strings (e.g. "@finish") to Go functions.
Options *Options // Typed options merged in (via SetOptions) before rules are processed.
OptionsMap map[string]any // Map-form options; FuncRef values resolved via Ref before applying.
Rule map[string]*GrammarRuleSpec // Open/close alternates keyed by rule name.
V int // Builtin config-schema version; engine refuses V > BUILTIN_SCHEMA_VERSION. Zero ⇒ 1.
}
Declarative grammar specification; mirrors the TypeScript GrammarSpec type.
type InfoOptions ¶
type InfoOptions struct {
Map *bool // Return maps as MapRef (with Implicit flag) not map[string]any. Default: false.
List *bool // Return lists as ListRef (with Implicit flag) not []any. Default: false.
Text *bool // Wrap string/text values in Text structs carrying the quote char. Default: false.
Marker string // Key under which info metadata is stored on wrapped values. Default: "__info__".
}
InfoOptions controls metadata attachment to parsed output nodes (TS options.info).
type Lex ¶
type Lex struct {
Src string // Source text being lexed.
Ctx *Context // Parse context (includes Ctx.Rule for context-sensitive lexing).
Config *LexConfig // Resolved lexer configuration.
Err error // First error encountered during lexing.
// contains filtered or unexported fields
}
The lexer: produces tokens from source text.
func (*Lex) Bad ¶
Bad creates an error token at the current position. Matches TS lex.bad(why, pstart, pend).
func (*Lex) Cursor ¶
Cursor returns a pointer to the lexer's current position. Custom matchers use this to read and advance the position.
func (*Lex) Fwd ¶
Fwd returns a forward-looking substring from the current position. maxlen limits the length of the returned string. Matches TS lex.fwd.
func (*Lex) Next ¶
Next returns the next non-IGNORE token, passing the current parsing rule to custom matchers for context-sensitive lexing. On error (unterminated string, unterminated comment, unexpected character), the error is stored in l.Err and a ZZ (end) token is returned to allow the parser to wind down gracefully.
type LexCheck ¶
type LexCheck func(lex *Lex) *LexCheckResult
Hook that can intercept a matcher before it runs; nil continues normal matching, a result overrides.
type LexCheckResult ¶
type LexCheckResult struct {
Done bool // If true, use Token as the match result (even if nil).
Token *Token // The token to return (nil means "no match").
}
Outcome of a LexCheck hook controlling matcher behavior.
type LexConfig ¶
type LexConfig struct {
// Lex enable/disable flags (matching TS options.*.lex)
FixedLex bool // Enable fixed token recognition. Default: true.
SpaceLex bool // Enable space lexing. Default: true.
LineLex bool // Enable line lexing. Default: true.
TextLex bool // Enable text matching. Default: true.
NumberLex bool // Enable number matching. Default: true.
CommentLex bool // Enable comment matching. Default: true.
StringLex bool // Enable string matching. Default: true.
ValueLex bool // Enable value keyword matching. Default: true.
StringChars map[rune]bool // Quote characters.
MultiChars map[rune]bool // Multiline quote characters.
EscapeChar rune // String escape lead character (backslash).
EscapeMap map[string]string // Custom escape mappings, e.g. {"n": "\n"}.
EscapeRemoved map[string]bool // Built-in escapes removed via {"v": ""}; consulted before the hardcoded switch.
EscapeStrict bool // Disable the non-standard \xHH and \u{...} structural escapes.
RewindHistory int // Max consumed tokens retained for ctx.Rewind. <=0 means unbounded. Default 64.
SpaceChars map[rune]bool // Characters lexed as space (#SP).
LineChars map[rune]bool // Characters lexed as line endings (#LN).
RowChars map[rune]bool // Line characters that increment the row counter.
CommentLine []string // Line comment starters: "#", "//".
CommentBlock [][2]string // Block comment [start, end] pairs.
NumberHex bool // Recognize hex literals (0x...).
NumberOct bool // Recognize octal literals (0o...).
NumberBin bool // Recognize binary literals (0b...).
NumberSep rune // Digit separator char (underscore).
AllowUnknownEscape bool // Keep an unknown escape's char rather than erroring.
StringAbandon bool // On string error, return nil instead of bad token.
StringReplace map[rune]string // Character replacements during string scanning.
// Value definitions: keyword → value (e.g. "true" → true)
// If nil, uses built-in defaults (true, false, null).
ValueDef map[string]any
// ValueDefRe holds regex-processed value definitions (TS: cfg.value.defre).
// Sorted by name at configure time for deterministic iteration.
ValueDefRe []*ValueDefEntry
// Match options (TS: cfg.match)
MatchLex bool // Enable custom matching. Default: false.
MatchTokens map[Tin]*regexp.Regexp // Custom token tin → regexp (storage).
MatchTokensEager map[Tin]bool // Custom token tin → eager (skips the rule-position gate).
MatchTokenFns map[Tin]LexMatcher // Custom token tin → function matcher (storage).
MatchTokensSorted []*MatchTokenEntry // Sorted-by-tin view for deterministic iteration.
MatchValues []*MatchValueEntry // Custom value matchers, sorted by name.
// Number options
NumberExclude func(string) bool // Exclude certain number-like strings.
// Line options
LineSingle bool // Generate separate tokens per newline.
// Text options
TextModify []ValModifier // Pipeline of text value modifiers.
// Comment options (per-def eatline stored on CommentDef)
CommentLineEatLine map[string]bool // Line comment starter → eatline flag.
CommentBlockEatLine map[string]bool // Block comment start → eatline flag.
// Comment suffix terminators — optional, non-consuming.
// Per start-marker, a list of string prefixes that terminate the
// comment body when encountered. The suffix remains in the input.
CommentLineSuffixes map[string][]string
CommentBlockSuffixes map[string][]string
// LexMatcher-form suffix terminators. Invoked at each candidate
// position inside the comment body; a non-nil returned token signals
// termination at that offset. The returned token is discarded.
CommentLineSuffixFuncs map[string]LexMatcher
CommentBlockSuffixFuncs map[string]LexMatcher
// Color carries the resolved ANSI escape codes for error formatting.
// Populated from Options.Color by buildConfig.
Color ColorConfig
// ErrorMessages holds error message templates by code (TS: cfg.error).
// Options.Error entries are merged over the package defaults by
// buildConfig. Templates may use {key} placeholders (code, src, ...).
ErrorMessages map[string]string
// Hints holds explanatory hint templates by code (TS: cfg.hint).
// Options.Hint entries are merged over the package defaults.
Hints map[string]string
// ErrTag is the error header name (TS: errmsg.name). "" → "tabnas".
ErrTag string
// ErrSuffix mirrors TS errmsg.suffix: nil/true renders the standard
// internal suffix block, false suppresses it, string/func replace it.
ErrSuffix any
// ErrLink is an optional "see also" line (TS: errmsg.link) rendered
// inside the standard suffix block.
ErrLink string
// Tag is the instance tag (TS: options.tag), shown in the internal
// error suffix.
Tag string
// Map/List options
MapExtend bool // Deep-merge duplicate keys. Default: true.
MapMerge MapMergeFunc // Custom merge function for duplicate keys.
MapChild bool // Parse bare colon in maps as child$ key. Default: false.
ListProperty bool // Allow named properties in arrays. Default: true.
ListPair bool // Push pairs as object elements in arrays. Default: false.
// Safe options
SafeKey bool // Prevent __proto__ keys. Default: true.
// Rule options
FinishRule bool // Auto-close unclosed structures at EOF
RuleStart string // Starting rule name. Default: "val".
// EnderChars lists additional characters that end text and number tokens.
EnderChars map[rune]bool
// Per-instance fixed token map (cloned from global FixedTokens).
// Plugins can add custom fixed tokens here. Supports multi-char keys.
FixedTokens map[string]Tin
// FixedSorted is the list of fixed token strings sorted by length (longest first).
// Rebuilt by SortFixedTokens() after adding custom tokens.
FixedSorted []string
// Custom token names: Tin → name for plugin-defined tokens.
TinNames map[Tin]string
// Custom lexer matchers added by plugins, sorted by priority.
CustomMatchers []*MatcherEntry
// TextInfo wraps string/text output values in Text structs.
TextInfo bool
// ListRef wraps list output values in ListRef structs.
ListRef bool
// ListChild enables bare colon (:value) syntax in lists to set a child value.
ListChild bool
// MapRef wraps map output values in MapRef structs.
MapRef bool
// InfoMarker is the key name to protect from user data when info options
// are enabled. Keys matching this value are dropped during parsing.
// Matches TS cfg.info.marker. Empty string means no protection.
InfoMarker string
// IgnoreSet is the per-instance set of token Tins to skip during lexing.
// Matches TS cfg.tokenSetTins.IGNORE. Plugins can customize this per-instance.
IgnoreSet map[Tin]bool
// ValSet is the per-instance VAL token set (text, number, string, value).
// Matches TS cfg.tokenSet.VAL. Plugins can customize this per-instance.
ValSet []Tin
// KeySet is the per-instance KEY token set (text, number, string, value).
// Matches TS cfg.tokenSet.KEY. Plugins can customize this per-instance.
KeySet []Tin
// ParsePrepare hooks called before parsing begins.
ParsePrepare []func(ctx *Context)
// ResultFail is a list of values that are treated as parse failures.
ResultFail []any
// LexCheck callbacks allow plugins to intercept and override matchers.
// Each returns nil to continue normal matching, or a LexCheckResult to short-circuit.
FixedCheck LexCheck
SpaceCheck LexCheck
LineCheck LexCheck
StringCheck LexCheck
CommentCheck LexCheck
NumberCheck LexCheck
TextCheck LexCheck
MatchCheck LexCheck
// contains filtered or unexported fields
}
LexConfig holds lexer configuration.
func DefaultLexConfig ¶
func DefaultLexConfig() *LexConfig
DefaultLexConfig returns the default lexer configuration matching tabnas defaults.
func (*LexConfig) RebuildMatchTokensSorted ¶
func (cfg *LexConfig) RebuildMatchTokensSorted()
RebuildMatchTokensSorted projects MatchTokens and MatchTokenFns into MatchTokensSorted ([]*MatchTokenEntry) in ascending Tin order. Call this after any mutation of either map so the lexer can iterate deterministically without sorting during parse. A function matcher takes precedence over a regexp registered for the same tin.
func (*LexConfig) SortFixedTokens ¶
func (cfg *LexConfig) SortFixedTokens()
SortFixedTokens rebuilds FixedSorted from FixedTokens, sorted by length descending. Call this after adding multi-char fixed tokens to ensure longest-match-first behavior.
type LexMatcher ¶
LexMatcher is a custom lexer matcher: returns a Token (advancing the cursor) or nil to pass. The rule parameter allows context-sensitive lexing (e.g. rule.K, rule.U, rule.N, rule.State).
type LexOptions ¶
type LexOptions struct {
Empty *bool // Allow empty source. Default: true.
EmptyResult any // Result for empty source. Default: nil.
Match map[string]*MatchSpec // Custom lexer matchers keyed by name (TS lex.match: { name: { order, make } }).
}
LexOptions controls global lex behavior.
type LineOptions ¶
type LineOptions struct {
Lex *bool // Enable line lexing. Default: true.
Chars string // Line characters. Default: "\r\n".
RowChars string // Row-counting characters. Default: "\n".
Single *bool // Generate separate tokens per newline. Default: false.
Check LexCheck // Hook invoked before the line matcher runs (TS options.line.check).
}
LineOptions controls line-ending lexing.
type ListOptions ¶
type ListOptions struct {
Property *bool // Allow named properties in arrays [a:1]. Default: true.
Pair *bool // Push pairs as object elements: [a:1] → [{"a":1}]. Default: false.
Child *bool // Parse bare colon as child value: [:1] → ListRef with Child=1. Default: false.
}
ListOptions controls array/list behavior.
type ListRef ¶
type ListRef struct {
Val []any // List contents.
Implicit bool // True if created implicitly (no brackets), false if brackets were explicit.
Child any // Child value from bare colon syntax (:value); merged if multiple, nil if absent.
Meta map[string]any // Custom-parser scratch map, initialized when created in the BO (before-open) phase.
}
ListRef wraps a list value with creation metadata, used when the ListRef option is enabled.
type MakeLexMatcher ¶
type MakeLexMatcher func(cfg *LexConfig, opts *Options) LexMatcher
MakeLexMatcher is a factory that builds a LexMatcher from the lex config and options.
type MapMergeFunc ¶
MapMergeFunc is a custom merge function for duplicate map keys. Receives the previous value, new value, rule, and context.
type MapOptions ¶
type MapOptions struct {
Extend *bool // Deep-merge duplicate keys. Default: true.
Child *bool // Parse bare colon as child$ key: {:1} → {"child$":1}. Default: false.
Merge MapMergeFunc // Custom merge function for duplicate keys. Takes precedence over Extend.
}
MapOptions controls object/map behavior.
type MapRef ¶
type MapRef struct {
Val map[string]any // Map contents.
Implicit bool // True if created implicitly (no braces), false if braces were explicit.
Meta map[string]any // Custom-parser scratch map, initialized when created in the BO (before-open) phase.
}
MapRef wraps a map value with creation metadata, used when the MapRef option is enabled.
type MatchOptions ¶
type MatchOptions struct {
Lex *bool // Enable custom matching. Default: true.
Token map[string]*regexp.Regexp // "#NAME" → regexp pattern for custom tokens.
TokenEager map[string]bool // "#NAME" → true when eager (skips the rule-position gate; from @~/…/).
// TokenOrder fixes the Tin-allocation order of Token entries so the
// lexer's deterministic (Tin-ascending) match-token iteration reflects
// a caller-chosen precedence. Names listed here are allocated first, in
// order; any remaining Token keys are allocated afterwards (sorted by
// name for determinism). Mirrors the TS engine, where match.token is an
// ordered object and the first matching matcher wins. Optional; when
// nil the previous (map-iteration) behaviour applies but sorted by name.
TokenOrder []string
Value map[string]*MatchValueSpec // name → {Match, Val} for custom value matchers.
TokenFn map[string]LexMatcher // "#NAME" → function-form token matcher (TS match.token LexMatcher branch).
Check LexCheck // Hook invoked before the match matcher runs (TS options.match.check).
}
MatchOptions controls custom token and value matching (TS options.match: RegExp|LexMatcher per entry). Go splits the union: Token/Value hold regexp forms; TokenFn and MatchValueSpec.Fn hold function forms.
type MatchSpec ¶
type MatchSpec struct {
Order int // Priority order (lower runs first).
Make MakeLexMatcher // Factory that builds the matcher.
}
MatchSpec is a custom matcher registered via options (TS: { order, make }).
type MatchTokenEntry ¶
type MatchTokenEntry struct {
Tin Tin // The token type this matcher produces; the sort key.
Match *regexp.Regexp // Regexp form.
Fn LexMatcher // Function-form matcher; takes precedence over Match.
Eager bool // When true, fire regardless of the rule-position gate.
}
A Tin paired with its matcher (regexp or function), sorted by Tin for deterministic lexing.
type MatchValueEntry ¶
type MatchValueEntry struct {
Name string // User-supplied name; the sort key.
Match *regexp.Regexp // Regexp form; submatch groups fed to Val.
Val func([]string) any // Builds the value from the regexp submatches.
Fn LexMatcher // Function-form matcher; takes precedence over Match.
}
A resolved match.value matcher entry, sorted by Name for deterministic iteration.
type MatchValueSpec ¶
type MatchValueSpec struct {
Match *regexp.Regexp // Regexp pattern to match against.
Val func([]string) any // Optional value transformer, receives match groups.
Fn LexMatcher // Function-form matcher; when set, Match/Val ignored, its non-nil Token is the match.
}
MatchValueSpec defines a custom value matcher (TS options.match.value[name]: RegExp|LexMatcher).
type MatcherEntry ¶
type MatcherEntry struct {
Name string // Matcher name (unique key).
Priority int // Ordering priority; < 2e6 runs before all built-ins.
Match LexMatcher // The matcher function.
}
MatcherEntry is a named custom matcher ordered by priority (lower runs first). Built-ins: fixed=2e6, space=3e6, line=4e6, string=5e6, comment=6e6, number=7e6, text=8e6.
type ModListOpts ¶
type ModListOpts struct {
Delete []int // Indices to delete (supports negative indices).
Move []int // Move pairs: [from, to, from, to, ...].
Custom func(list []any) []any // Custom modification callback, applied last.
}
List modification options for ModList (mirrors the TypeScript ListMods type).
type NumberOptions ¶
type NumberOptions struct {
Lex *bool // Enable number matching. Default: true.
Hex *bool // Support 0x hex format. Default: true.
Oct *bool // Support 0o octal format. Default: true.
Bin *bool // Support 0b binary format. Default: true.
Sep string // Number separator character. Default: "_". Empty string disables.
Exclude func(string) bool // Exclude certain number-like strings from number matching.
Check LexCheck // Hook invoked before the number matcher runs (TS options.number.check).
}
NumberOptions controls numeric literal lexing.
type Options ¶
type Options struct {
Safe *SafeOptions // Prototype-pollution-style key safety.
Fixed *FixedOptions // Fixed token recognition ({, }, [, ], :, ,).
Match *MatchOptions // Custom regexp/function token and value matching (TS options.match).
TokenSet map[string][]string // Custom token sets, VAL/KEY/etc. (TS options.tokenSet).
Space *SpaceOptions // Space/tab lexing.
Line *LineOptions // Line-ending lexing.
Text *TextOptions // Unquoted text lexing.
Number *NumberOptions // Numeric literal lexing.
Comment *CommentOptions // Comment lexing.
String *StringOptions // Quoted string lexing.
Map *MapOptions // Object/map merging behavior.
List *ListOptions // Array/list behavior.
Value *ValueOptions // Keyword literal matching (true, false, null, etc.).
Ender []string // Additional characters that end text tokens.
Rule *RuleOptions // Parser rule behavior.
Lex *LexOptions // Global lexer behavior (empty source, etc.).
Parse *ParseOptions // Parse-time hooks (TS options.parse); distinct from Parser.
Parser *ParserOptions // Custom parser entrypoint override.
Result *ResultOptions // Parse result validation.
Error map[string]string // Custom error message templates keyed by error code.
Hint map[string]string // Additional explanatory text per error code.
ErrMsg *ErrMsgOptions // Error message formatting.
Info *InfoOptions // Metadata attachment to parsed output nodes (TS options.info).
Rewind *RewindOptions // Consumed-token retention for ctx.Rewind (TS options.rewind).
Property *PropertyOptions // Go-specific options not present in the TypeScript version.
Color *ColorOptions // ANSI colour codes in formatted error messages (TS options.color).
Tag string // Instance identifier tag.
}
Options configures a Tabnas parser instance; nil pointer fields mean "use default".
func MapToOptions ¶
MapToOptions builds an Options struct from a map[string]any (FuncRefs already resolved), covering common grammar option fields. MapToOptions(map[string]any{"tag":"x"}) // => Options{Tag:"x"}
type ParseOptions ¶
type ParseOptions struct {
// Prepare holds named callbacks invoked once at the start of every parse, in
// name order. The map form matches TS so plugins can replace entries by name.
Prepare map[string]func(ctx *Context)
}
ParseOptions holds parse-time hooks (TS options.parse).
type Parser ¶
type Parser struct {
Config *LexConfig // Lexer/parser configuration.
RSM map[string]*RuleSpec // Rule spec map, keyed by rule name.
MaxMul int // Max rule occurrence multiplier. Default: 3.
ErrorMessages map[string]string // Custom error message templates.
Hints map[string]string // Explanatory hints per error code.
ErrTag string // Custom error tag (TS: errmsg.name). Default: "tabnas".
}
Parser orchestrates the parsing process for one grammar configuration.
type ParserOptions ¶
type ParserOptions struct {
Start func(src string, j *Tabnas, meta map[string]any) (any, error) // Replacement parser entrypoint.
}
ParserOptions allows custom parser overrides.
type Plugin ¶
Plugin modifies a Tabnas instance (tokens, matchers, rules); errors on init failure.
var Debug Plugin = func(j *Tabnas, opts map[string]any) error { if opts != nil { if trace, ok := opts["trace"]; ok { if traceBool, ok := trace.(bool); ok && traceBool { addTrace(j) } } } return nil }
Debug is a plugin that provides introspection and tracing capabilities. It matches the TypeScript Debug plugin functionality.
Usage:
j := tabnas.Make()
j.Use(tabnas.Debug, map[string]any{"trace": true})
fmt.Println(tabnas.Describe(j))
type Point ¶
type Point struct {
Len int // Total length of the source text.
SI int // Source (string) index, 0-based.
RI int // Row index, 1-based.
CI int // Column index, 1-based.
}
Cursor position within the source text.
type PropertyOptions ¶
type PropertyOptions struct {
ConfigModify map[string]ConfigModifier // Callbacks run after config construction, keyed by name.
}
PropertyOptions holds Go-specific options not present in the TypeScript version.
type ResultOptions ¶
type ResultOptions struct {
// Fail lists values treated as parse failures: a result matching any of them
// yields an "unexpected" error. E.g. Fail: []any{nil} makes nil results fail.
Fail []any
}
ResultOptions controls parse result validation (TS options.result).
type RewindOptions ¶
type RewindOptions struct {
// History caps consumed tokens retained for ctx.Rewind; non-positive means
// unbounded (TS Infinity). Default: 64. ctx.Rewind errors if its target mark
// has been evicted from the retained window.
History *int
}
RewindOptions bounds the consumed-token history retained for ctx.Rewind (TS options.rewind).
type Rule ¶
type Rule struct {
I int // Unique rule id within this parse run.
Name string // Rule name (matches its RuleSpec).
Spec *RuleSpec // The RuleSpec this rule applies.
Node any // Value node this rule is building.
State RuleState // Current phase: open ("o") or close ("c").
D int // Stack depth at which this rule was pushed.
Child *Rule // Rule pushed by this rule (NoRule if none).
Parent *Rule // Rule that pushed this rule (NoRule if none).
Prev *Rule // Rule this one replaced (NoRule if none).
Next *Rule // Rule to process after this one.
// Generalized per-position matched tokens. O[i] holds the token
// matched at the i-th lookahead position during OPEN (mirroring C
// for CLOSE). ON / CN give the number of matched positions. This
// supersedes the legacy O0/O1/OS (and C0/C1/CS) two-slot fields,
// which are still maintained below for backward compatibility.
O []*Token // Tokens matched in the open phase, by position.
ON int // Count of tokens matched in the open phase.
C []*Token // Tokens matched in the close phase, by position.
CN int // Count of tokens matched in the close phase.
// Legacy two-slot aliases. Kept in sync with O[0..1] / C[0..1] by
// ParseAlts so existing grammar code and plugins that read r.O0,
// r.O1, r.C0, r.C1, r.OS, r.CS continue to work unchanged.
O0 *Token // Open token at position 0 (alias of O[0]).
O1 *Token // Open token at position 1 (alias of O[1]).
C0 *Token // Close token at position 0 (alias of C[0]).
C1 *Token // Close token at position 1 (alias of C[1]).
OS int // Open match count (alias of ON).
CS int // Close match count (alias of CN).
N map[string]int // Named counters tracked across the rule.
U map[string]any // Custom user props (not propagated to children).
K map[string]any // Custom keep props (propagated via push/replace).
Why string // Internal tracing field; set when a rule fails.
}
Rule is a rule instance created during parsing (the runtime counterpart of a RuleSpec).
var NoRule *Rule
NoRule is the sentinel "no rule" value; its Node is Undefined (TS NORULE.node === undefined).
type RuleDefiner ¶
RuleDefiner modifies a RuleSpec, adding alternates, actions, or conditions to a grammar rule.
type RuleOptions ¶
type RuleOptions struct {
Start string // Starting rule name. Default: "val".
Finish *bool // Auto-close unclosed structures at EOF. Default: true.
MaxMul *int // Max rule occurrence multiplier. Default: 3.
Include string // Comma-separated group tags; keep only alts whose G has one of these. Applied before Exclude.
Exclude string // Comma-separated group tags; drop alts whose G has any of these. Applied after Include.
}
RuleOptions controls parser rule behavior.
type RuleSpec ¶
type RuleSpec struct {
Name string // Rule name (key in the rule spec map).
// contains filtered or unexported fields
}
RuleSpec is the specification for a parsing rule; its alternate and action lists are unexported and mutated only via methods (mirroring the TS RuleSpec).
func (*RuleSpec) Actions ¶
func (rs *RuleSpec) Actions(phase string) []StateAction
Actions returns the registered lifecycle actions for a phase ("bo", "ao", "bc", "ac"); an unknown phase returns nil.
func (*RuleSpec) AddAC ¶
func (rs *RuleSpec) AddAC(action StateAction) *RuleSpec
AddAC appends an after-close action.
func (*RuleSpec) AddAO ¶
func (rs *RuleSpec) AddAO(action StateAction) *RuleSpec
AddAO appends an after-open action.
func (*RuleSpec) AddBC ¶
func (rs *RuleSpec) AddBC(action StateAction) *RuleSpec
AddBC appends a before-close action.
func (*RuleSpec) AddBO ¶
func (rs *RuleSpec) AddBO(action StateAction) *RuleSpec
AddBO appends a before-open action.
func (*RuleSpec) ClearActions ¶
ClearActions removes the registered lifecycle actions for the named phases (any of "bo", "ao", "bc", "ac"); with no arguments, all four are cleared. The fnref dedup/replace bookkeeping for those phases is reset too, so a subsequent wireStateActions re-installs cleanly. Alternates are untouched.
func (*RuleSpec) ClearClose ¶
ClearClose removes this rule's close alternates (see ClearOpen).
func (*RuleSpec) ClearOpen ¶
ClearOpen removes this rule's open alternates without touching close or the lifecycle actions. A later plugin can call this, then AddOpen, to replace the open alternates contributed by earlier plugins.
func (*RuleSpec) Fnref ¶
Fnref installs lifecycle state actions from a funcref map, using the reserved `@<rule>-<phase>` naming (with the optional `/prepend`, `/append`, `/replace` suffixes). Mirrors the TS `rs.fnref(frm)` method, giving append-by-funcref parity for code-built grammars without going through Grammar(). Returns the RuleSpec for chaining.
func (*RuleSpec) HasBO ¶
HasBO reports whether any before-open action is registered (mirrors the TS RuleSpec.bo boolean presence flag); likewise HasAO/HasBC/HasAC.
func (*RuleSpec) ModifyClose ¶
func (rs *RuleSpec) ModifyClose(mods *AltModListOpts) *RuleSpec
ModifyClose applies delete/move/custom modifications to the close alternates list.
func (*RuleSpec) ModifyOpen ¶
func (rs *RuleSpec) ModifyOpen(mods *AltModListOpts) *RuleSpec
ModifyOpen applies delete/move/custom modifications to the open alternates list. Matches TS `rs.open(alts, mods)` where mods has delete/move/custom.
func (*RuleSpec) OpenAlts ¶
OpenAlts returns this rule's open alternates. The returned slice is the live backing slice — read-only by convention; mutate via the Add/Modify/ Clear methods. (Read accessor; the lists themselves are unexported, as in the TS RuleSpec.)
func (*RuleSpec) PrependAC ¶
func (rs *RuleSpec) PrependAC(action StateAction) *RuleSpec
PrependAC inserts an after-close action at the front.
func (*RuleSpec) PrependAO ¶
func (rs *RuleSpec) PrependAO(action StateAction) *RuleSpec
PrependAO inserts an after-open action at the front.
func (*RuleSpec) PrependBC ¶
func (rs *RuleSpec) PrependBC(action StateAction) *RuleSpec
PrependBC inserts a before-close action at the front.
func (*RuleSpec) PrependBO ¶
func (rs *RuleSpec) PrependBO(action StateAction) *RuleSpec
PrependBO inserts a before-open action at the front (runs first).
func (*RuleSpec) PrependClose ¶
PrependClose inserts alternates at the beginning of the close list.
func (*RuleSpec) PrependOpen ¶
PrependOpen inserts alternates at the beginning of the open list.
type RuleState ¶
type RuleState = string
RuleState represents whether a rule is in open or close state.
type SafeOptions ¶
type SafeOptions struct {
Key *bool // Prevent __proto__ keys. Default: true.
}
SafeOptions controls key safety.
type ScanOut ¶
type ScanOut struct {
SI int // Source byte index reached.
RI int // Row index reached.
CI int // Column index reached.
}
ScanOut is caller-owned scratch holding the position a Scan ended at (TS: ScanOut).
type ScanSpec ¶
type ScanSpec struct {
InitialState int // State the walk starts in.
NClasses int // Number of byte-classes the spec uses.
ClassOf [256]uint8 // Per-ASCII-byte class index.
Table []int32 // Packed action keyed on state*NClasses + class.
// Fallback classifies non-ASCII runes (lead byte >= 0x80); when set, the
// driver decodes the full UTF-8 rune and consumes it as one column. Nil
// means pure byte mode. Mirrors the TS fallback class fn for codes >= 256.
Fallback func(r rune) uint8
}
ScanSpec is a declarative byte-walk specification (TS: ScanSpec).
func BuildCharRunSpec ¶
BuildCharRunSpec builds a 2-class run spec from a char set. Class 0 = not in set, class 1 = in set. Used by the space matcher (TS: buildCharRunSpec).
func BuildLineRunSpec ¶
BuildLineRunSpec builds a 3-class line-run spec from line/row char sets. Class 0 = not a line char, class 1 = line char, class 2 = line char that also advances the row counter. Used by the line matcher (when not in `single` mode) and by the comment matcher's eatline tails (TS: buildLineRunSpec).
func BuildStringBodySpec ¶
BuildStringBodySpec builds a string-body scan spec for one quote char. Class 0 = BODY (consume, advance col); class 1 = STOP (caller decides what to do); class 2 = LINE (multi-line strings only — consume, reset col); class 3 = LINE+ROW (multi-line — consume, reset col, advance row). The opening/closing quote, the escape char, the replace chars, and any control char that can't be consumed in the current quote context all map to class 1.
One spec per quote char because the quote char is encoded in the class table; the string matcher caches them per config (TS: buildStringBodySpec).
type SpaceOptions ¶
type SpaceOptions struct {
Lex *bool // Enable space lexing. Default: true.
Chars string // Space characters. Default: " \t".
Check LexCheck // Hook invoked before the space matcher runs (TS options.space.check).
}
SpaceOptions controls space lexing.
type StateAction ¶
StateAction is a before/after action on a rule state transition.
type StringOptions ¶
type StringOptions struct {
Lex *bool // Enable string matching. Default: true.
Chars string // Quote characters. Default: `'"` + "`".
MultiChars string // Multiline quote characters. Default: "`".
EscapeChar string // Escape character. Default: "\\".
Escape map[string]string // Escape mappings, e.g. {"n": "\n"}. An entry mapped to "" removes a built-in escape (e.g. {"v": ""} rejects \v).
AllowUnknown *bool // Allow unknown escapes. Default: true.
// EscapeStrict disables the non-standard escapes \xHH and \u{...} (plain \uXXXX
// stays). Default: false. With escape-map removals and AllowUnknown:false this
// yields JSON.parse-conformant handling.
EscapeStrict *bool
Abandon *bool // On string error, return nil to let next matcher try. Default: false.
Replace map[rune]string // Character replacements applied during string scanning.
Check LexCheck // Hook invoked before the string matcher runs (TS options.string.check).
}
StringOptions controls quoted string lexing.
type Tabnas ¶
type Tabnas struct {
// contains filtered or unexported fields
}
Tabnas is a configured parser instance, equivalent to TypeScript's Tabnas.make().
func Empty ¶
Empty creates a Tabnas instance with no grammar rules. Matches TS tabnas.empty(). Since the engine ships no grammar (matching the TS package), this is equivalent to Make for a fresh instance, but also clears any rules contributed by plugins in the passed options.
func Make ¶
Make creates a new Tabnas parser instance with the given options. Unset option fields fall back to defaults, matching TypeScript Tabnas.make().
func (*Tabnas) Config ¶
Config returns the parser's LexConfig for direct inspection or modification. Use with care — prefer Token(), Rule(), and options.lex.match for most work.
func (*Tabnas) Decorate ¶
Decorate sets a named value on this instance. This is the Go equivalent of the TypeScript pattern where plugins add properties to the tabnas instance (e.g. tabnas.foo = () => 'FOO'). Decorations are inherited by Derive.
func (*Tabnas) Decoration ¶
Decoration returns a named value previously set by Decorate. Returns nil if the name has not been set.
func (*Tabnas) Derive ¶
Derive creates a new Tabnas instance inheriting this instance's config, rules, plugins, and custom tokens. Changes to the child do not affect the parent. This matches TypeScript's tabnas.make(options, parent).
func (*Tabnas) FixedSrc ¶
FixedSrc returns the Tin for a fixed token source string (e.g. "{" → TinOB). Returns 0 if the source string is not a fixed token. Matches TS `tabnas.fixed('b')`.
func (*Tabnas) FixedTin ¶
FixedTin returns the source string for a fixed token Tin (e.g. TinOB → "{"). Returns "" if the Tin is not a fixed token. Matches TS `tabnas.fixed(18)`.
func (*Tabnas) Grammar ¶
func (j *Tabnas) Grammar(gs *GrammarSpec, setting ...*GrammarSetting) (err error)
Grammar applies a declarative grammar specification to this Tabnas instance. Options are applied first, then rules are processed. An optional *GrammarSetting may be supplied to append a tag (or tags) to every rule-alt G property in the spec. Returns an error if any FuncRef is missing or has the wrong type.
func (*Tabnas) GrammarText ¶
func (j *Tabnas) GrammarText(text string, setting ...*GrammarSetting) (err error)
GrammarText parses a tabnas grammar text string into a GrammarSpec and applies it. The text is parsed using a default Tabnas instance, and the resulting map is used as the OptionsMap of a GrammarSpec. An optional *GrammarSetting may be supplied to append a tag (or tags) to every rule-alt G property in the spec. This is a convenience that replaces:
gs := tabnas.Make()
parsed, _ := gs.Parse(text)
j.Grammar(&GrammarSpec{OptionsMap: parsed.(map[string]any)})
func (*Tabnas) Id ¶
Id returns the unique instance identifier for this Tabnas instance. Matches TS tabnas.id.
func (*Tabnas) ParseMeta ¶
ParseMeta parses a tabnas string with metadata passed through to the parse context. The meta map is accessible in rule actions/conditions via ctx.Meta.
func (*Tabnas) PluginOptions ¶
PluginOptions returns the options stored for a named plugin. Matches TS `tabnas.options.plugin[name]`.
func (*Tabnas) Rule ¶
func (j *Tabnas) Rule(name string, definer RuleDefiner) *Tabnas
Rule modifies or creates a grammar rule by name. The definer callback receives the RuleSpec and can modify its Open/Close alternates, and BO/BC/AO/AC state actions.
If the rule does not exist, a new empty RuleSpec is created. A nil definer deletes the rule from the rule-spec map, if present (mirrors the TypeScript rule(name, null) idiom). Deleting an absent rule is a no-op. Returns the Tabnas instance for chaining.
Example:
j.Rule("val", func(rs *RuleSpec, p *Parser) {
rs.open = append([]*AltSpec{{
S: [][]Tin{{myToken}},
A: func(r *Rule, ctx *Context) { r.Node = "custom" },
}}, rs.open...)
})
func (*Tabnas) SetOptions ¶
SetOptions deep-merges new options into this instance and rebuilds the config. Existing grammar rules (including plugin modifications) are preserved — matching the TypeScript clone/inherit pattern where options() does not rebuild the grammar. When called from within a plugin (during re-apply), skips plugin re-application to avoid infinite recursion. Returns the instance for chaining.
func (*Tabnas) SetOptionsText ¶
SetOptionsText parses a tabnas-format options string, converts it to an Options struct via MapToOptions, and applies it via SetOptions. Returns the instance for chaining and any parse error encountered. Complement to SetOptions that accepts a textual specification of the desired options tree. Requires a registered text parser (see RegisterTextParser).
func (*Tabnas) SetPluginOptions ¶
SetPluginOptions stores options for a named plugin. Matches TS `tabnas.options({ plugin: { name: opts } })`.
func (*Tabnas) SetTokenSet ¶
SetTokenSet registers a custom named token set. Matches TS options.tokenSet. Also updates the per-instance config sets (IgnoreSet, ValSet, KeySet) to keep them in sync, matching TS cfg.tokenSetTins behavior.
func (*Tabnas) Sub ¶
Sub subscribes to lex and/or rule events. LexSub fires after each non-ignored token is lexed. RuleSub fires after each rule processing step. Returns the Tabnas instance for chaining.
func (*Tabnas) TinName ¶
TinName returns the name for a Tin value, checking both built-in and custom tokens.
func (*Tabnas) Token ¶
Token registers a new token type or looks up an existing one. With just a name, it returns the Tin for an existing token. With a name and source character(s), it registers a new fixed token.
Returns the Tin (token identification number) for the token.
Example:
// Register a new fixed token
TT := j.Token("#TL", "~")
// Look up existing token
OB := j.Token("#OB", "")
func (*Tabnas) TokenSet ¶
TokenSet returns a named set of Tin values. Built-in sets: "IGNORE" (space, line, comment), "VAL" (text, number, string, value), "KEY" (text, number, string, value). Custom sets can be added via SetTokenSet. Returns nil if the set name is not recognized.
func (*Tabnas) Use ¶
Use registers and invokes a plugin on this Tabnas instance. The plugin function is called with the Tabnas instance and optional options. Returns an error if the plugin fails to initialize.
Example:
j := tabnas.Make()
err := j.Use(myPlugin, map[string]any{"key": "value"})
func (*Tabnas) UseDefaults ¶
func (j *Tabnas) UseDefaults(plugin Plugin, defaults map[string]any, opts ...map[string]any) (err error)
UseDefaults registers and invokes a plugin, merging default options with user-provided options before calling the plugin. This matches the TS pattern where plugins have a .defaults property:
deep({}, plugin.defaults || {}, plugin_options || {})
Example:
j := tabnas.Make()
err := j.UseDefaults(hoover.Hoover, hoover.Defaults, map[string]any{...})
type TabnasError ¶
type TabnasError struct {
Code string // Error code keying errorMessages/defaultHints, e.g. "unexpected", "unterminated_string".
Detail string // Human-readable detail message (e.g. "unterminated string: \"abc")
Pos int // 0-based character position in source
Row int // 1-based line number
Col int // 1-based column number
Src string // Source fragment at the error (the token text)
Hint string // Additional explanatory text for this error code
// contains filtered or unexported fields
}
Structured error returned by Parse, carrying the failure location, cause, and formatting context.
func (*TabnasError) Error ¶
func (e *TabnasError) Error() string
Error returns a formatted error message matching the TypeScript TabnasError format:
[tabnas/<code>]: <message>
--> <file>:<row>:<col>
<line-2> | <source>
<line-1> | <source>
<line> | <source with error>
^^^^ <message>
<line+1> | <source>
<line+2> | <source>
<hint, indented>
<errmsg.link, when configured>
--internal: tag=...; rule=...; token=...; plugins=...--
When e.color.Active is true the header, arrow, caret, line-number gutter, and suffix are wrapped in ANSI escapes — matching TS error.ts output. The trailing suffix block follows TS `errmsg.suffix`: rendered by default (or when true), suppressed when false, and replaced when a string or func(code, src string) string is configured.
type Text ¶
type Text struct {
Quote string // Source quote char (`"`, `'`, or backtick); empty for unquoted text.
Str string // String value, with escapes processed for quoted strings.
}
Text wraps a string value with its source quoting, used when the TextInfo option is enabled.
type TextOptions ¶
type TextOptions struct {
Lex *bool // Enable text matching. Default: true.
Modify []ValModifier // Pipeline of value modifiers applied after text matching.
Check LexCheck // Hook invoked before the text matcher runs (TS options.text.check).
}
TextOptions controls unquoted text lexing.
type Tin ¶
type Tin = int
Tin is a token identification number.
const ( TinBD Tin = 1 // #BD - BAD TinZZ Tin = 2 // #ZZ - END TinUK Tin = 3 // #UK - UNKNOWN TinAA Tin = 4 // #AA - ANY TinSP Tin = 5 // #SP - SPACE TinLN Tin = 6 // #LN - LINE TinCM Tin = 7 // #CM - COMMENT TinNR Tin = 8 // #NR - NUMBER TinST Tin = 9 // #ST - STRING TinTX Tin = 10 // #TX - TEXT TinVL Tin = 11 // #VL - VALUE (true, false, null) TinOB Tin = 12 // #OB - Open Brace { TinCB Tin = 13 // #CB - Close Brace } TinOS Tin = 14 // #OS - Open Square [ TinCS Tin = 15 // #CS - Close Square ] TinCL Tin = 16 // #CL - Colon : TinCA Tin = 17 // #CA - Comma , TinMAX Tin = 18 // Next available Tin )
Standard token Tins - assigned in order matching the TypeScript implementation.
type Token ¶
type Token struct {
Name string // Token name (#OB, #ST, etc.).
Tin Tin // Token identification number.
Val any // Resolved value, or a lazy TokenValFunc.
Src string // Matched source text.
SI int // Source index where the token starts.
RI int // Row index of the token.
CI int // Column index of the token.
Err string // Error code, empty when valid.
Why string // Reason/trace marker for debugging.
Use map[string]any // Custom plugin metadata (TS: token.use).
}
A single lexical token produced by the lexer.
func (*Token) Bad ¶
Bad converts this token to an error token with the given error code. Matches TS token.bad(err, details).
type TokenValFunc ¶
Signature for a lazy token value, evaluated at parse time by ResolveVal.
type UtilBag ¶
type UtilBag struct {
Deep func(base any, rest ...any) any // Recursive deep merge.
Keys func(m map[string]any) []string // Sorted map keys.
Values func(m map[string]any) []any // Values in key-sorted order.
Entries func(m map[string]any) []Entry // Key/value pairs, key-sorted.
Omap func(m map[string]any, fn func(Entry) []any) map[string]any // Map over object entries.
Str func(val any, maxlen int) string // Value to truncated string.
StrInject func(template string, vals any) string // Fill {key} placeholders.
// Lex scan primitives, for building matchers on the same driver.
Scan func(src string, startSI, startRI, startCI int, spec *ScanSpec, out *ScanOut) bool // Run the scan state machine.
BuildCharRunSpec func(chars map[rune]bool) *ScanSpec // Spec matching a run of chars.
BuildLineRunSpec func(lineChars, rowChars map[rune]bool) *ScanSpec // Spec matching line whitespace.
BuildStringBodySpec func(cfg *LexConfig, q rune) *ScanSpec // Spec matching a quoted string body.
}
Bag of helper functions exposed to plugins, mirroring TS tabnas.util.
type ValModifier ¶
ValModifier transforms a text token value after lexing.
type ValueDef ¶
type ValueDef struct {
Val any // Value to produce for this keyword.
Match *regexp.Regexp // Regexp matching the keyword instead of an exact string (TS value.def[name].match).
ValFunc func(match []string) any // Produces the value from regex match groups (TS value.def[name].val as function).
Consume bool // Match against full forward source, not just the text token; regexp should start with ^.
}
ValueDef defines a keyword value.
type ValueDefEntry ¶
type ValueDefEntry struct {
Name string // The sort key.
Def *ValueDef // The regex-based value definition.
}
A name-tagged regex value definition, sorted by Name for deterministic lexing (TS: cfg.value.defre).
type ValueOptions ¶
type ValueOptions struct {
Lex *bool // Enable value matching. Default: true.
Def map[string]*ValueDef // Keyword definitions, e.g. {"true": {Val: true}}.
}
ValueOptions controls keyword value matching.