import "github.com/jsonicjs/jsonic/go"Parse a string using default settings. Convenience function that creates a fresh parser for each call.
result, err := jsonic.Parse("a:1, b:2")
// result: map[string]any{"a": float64(1), "b": float64(2)}Parse using an instance's configuration.
j := jsonic.Make()
result, err := j.Parse("a:1")Parse with metadata accessible in rule actions via ctx.Meta.
result, err := j.ParseMeta("a:1", map[string]any{"filename": "config.jsonic"})Create a new parser instance. Unset option fields use defaults.
j := jsonic.Make(jsonic.Options{
Comment: &jsonic.CommentOptions{Lex: boolp(false)},
Number: &jsonic.NumberOptions{Hex: boolp(false)},
})Create a child instance inheriting the parent's configuration, plugins, custom tokens, and subscriptions. Changes to the child do not affect the parent.
child := j.Derive(jsonic.Options{
Comment: &jsonic.CommentOptions{Lex: boolp(false)},
})Deep-merge new options into the instance and rebuild the configuration,
grammar, and plugins. Nil/zero fields in opts do not overwrite existing values,
matching the TypeScript options() setter behavior. Returns the instance for
chaining.
Returns a copy of the instance's current options.
Set a named value on the instance. This is the Go equivalent of the
TypeScript pattern where plugins add properties dynamically
(jsonic.foo = () => 'FOO'). Decorations are inherited by Derive.
j.Use(func(j *jsonic.Jsonic, opts map[string]any) {
j.Decorate("greet", func(name string) string {
return "hello " + name
})
})Returns a named value previously set by Decorate, or nil.
fn := j.Decoration("greet").(func(string) string)
fmt.Println(fn("world")) // "hello world"Modify or create a grammar rule. The definer callback receives the
*RuleSpec and can modify its Open/Close alternate lists and state
actions (BO, BC, AO, AC).
j.Rule("val", func(rs *jsonic.RuleSpec) {
rs.Open = append([]*jsonic.AltSpec{{
S: [][]jsonic.Tin{{myToken}},
A: func(r *jsonic.Rule, ctx *jsonic.Context) {
r.Node = "custom"
},
}}, rs.Open...)
})Returns the rule spec map for direct inspection.
Register a new token type or look up an existing one. With src, registers
a fixed token mapping.
TL := j.Token("#TL", "~") // register ~ as #TL token
OB := j.Token("#OB", "") // look up existing #OB tokenGet a named token set:
"IGNORE"-- space, line, comment tokens"VAL"-- text, number, string, value tokens"KEY"-- text, number, string, value tokens
Returns the name for a token identification number.
Register and execute a plugin. Returns the instance for chaining.
j.Use(myPlugin, map[string]any{"key": "value"})type Plugin func(j *Jsonic, opts map[string]any)Returns the list of installed plugins.
Add a custom lexer matcher. Matchers are tried in priority order (lower first). Built-in priorities:
| Matcher | Priority |
|---|---|
| fixed | 2,000,000 |
| space | 3,000,000 |
| line | 4,000,000 |
| string | 5,000,000 |
| comment | 6,000,000 |
| number | 7,000,000 |
| text | 8,000,000 |
Use a priority below 2,000,000 to run before all built-ins.
type LexMatcher func(lex *Lex, rule *Rule) *TokenThe matcher reads the current position via lex.Cursor() and must advance
the cursor if it produces a token.
Subscribe to lex and/or rule events. Pass nil for either to skip.
j.Sub(func(tkn *jsonic.Token, rule *jsonic.Rule, ctx *jsonic.Context) {
fmt.Println("token:", tkn)
}, nil)type LexSub func(tkn *Token, rule *Rule, ctx *Context)
type RuleSub func(rule *Rule, ctx *Context)Returns the parser's internal configuration for direct inspection or
modification. Prefer Token(), Rule(), and AddMatcher() for most work.
Remove grammar alternates tagged with the given group names.
j.Exclude("jsonic") // keep only JSON-tagged rules for strict parsingParse errors are returned as *JsonicError:
type JsonicError struct {
Code string // "unexpected", "unterminated_string", "unterminated_comment"
Detail string // Human-readable message
Pos int // 0-based character position
Row int // 1-based line number
Col int // 1-based column number
Src string // Source fragment at error
Hint string // Additional context (if configured)
}result, err := jsonic.Parse("{a:")
if err != nil {
if je, ok := err.(*jsonic.JsonicError); ok {
fmt.Println(je.Code, "at line", je.Row)
}
}Go requires a pointer to pass *bool option fields. A common pattern:
func boolp(b bool) *bool { return &b }
jsonic.Options{
Comment: &jsonic.CommentOptions{Lex: boolp(false)},
}const Version = "0.1.6"The current version of the jsonic Go module.