1
0

only use tracing when explicitly enabled

This commit is contained in:
Arpad Ryszka 2026-06-06 21:48:50 +02:00
parent 752e4d2275
commit a009c1918d
14 changed files with 127 additions and 84 deletions

View File

@ -20,6 +20,9 @@ type checkOptions struct {
// InputString specifies the input content as an inline string. // InputString specifies the input content as an inline string.
InputString *string InputString *string
// MaxTraceLength enables tracing when set to a positive integer.
MaxTraceLength int
} }
// check parses input content against the provided syntax definition and fails if the input does not match. // check parses input content against the provided syntax definition and fails if the input does not match.
@ -38,7 +41,7 @@ func check(o checkOptions, stdin io.Reader, args ...string) error {
} }
defer finalizeInput() defer finalizeInput()
s := &treerack.Syntax{} s := &treerack.Syntax{MaxTraceLength: o.MaxTraceLength}
if err := s.ReadSyntax(syntax); err != nil { if err := s.ReadSyntax(syntax); err != nil {
if terr := treerack.Trace(os.Stderr, err); terr != nil { if terr := treerack.Trace(os.Stderr, err); terr != nil {
err = errors.Join(err, terr) err = errors.Join(err, terr)

View File

@ -14,6 +14,9 @@ type checkSyntaxOptions struct {
// SyntaxString specifies the syntax as an inline string. // SyntaxString specifies the syntax as an inline string.
SyntaxString *string SyntaxString *string
// MaxTraceLength enables tracing when set to a positive integer.
MaxTraceLength int
} }
// checkSyntax validates a syntax definition. The syntax may be provided via a file path (using an option or a // checkSyntax validates a syntax definition. The syntax may be provided via a file path (using an option or a
@ -25,7 +28,7 @@ func checkSyntax(o checkSyntaxOptions, stdin io.Reader, args ...string) error {
} }
defer finalize() defer finalize()
s := &treerack.Syntax{} s := &treerack.Syntax{MaxTraceLength: o.MaxTraceLength}
if err := s.ReadSyntax(syntax); err != nil { if err := s.ReadSyntax(syntax); err != nil {
if terr := treerack.Trace(os.Stderr, err); terr != nil { if terr := treerack.Trace(os.Stderr, err); terr != nil {
err = errors.Join(err, terr) err = errors.Join(err, terr)

View File

@ -12,28 +12,32 @@ func init() {
docreflect.Register("main.checkOptions", "") docreflect.Register("main.checkOptions", "")
docreflect.Register("main.checkOptions.Input", "Input specifies the filename of the input content to be validated.\n") docreflect.Register("main.checkOptions.Input", "Input specifies the filename of the input content to be validated.\n")
docreflect.Register("main.checkOptions.InputString", "InputString specifies the input content as an inline string.\n") docreflect.Register("main.checkOptions.InputString", "InputString specifies the input content as an inline string.\n")
docreflect.Register("main.checkOptions.MaxTraceLength", "MaxTraceLength enables tracing when set to a positive integer.\n")
docreflect.Register("main.checkOptions.Syntax", "Syntax specifies the filename of the syntax definition file.\n") docreflect.Register("main.checkOptions.Syntax", "Syntax specifies the filename of the syntax definition file.\n")
docreflect.Register("main.checkOptions.SyntaxString", "SyntaxString specifies the syntax as an inline string.\n") docreflect.Register("main.checkOptions.SyntaxString", "SyntaxString specifies the syntax as an inline string.\n")
docreflect.Register("main.checkSyntax", "checkSyntax validates a syntax definition. The syntax may be provided via a file path (using an option or a\npositional argument), an inline string, or piped from standard input.\n\nfunc(o, stdin, args)") docreflect.Register("main.checkSyntax", "checkSyntax validates a syntax definition. The syntax may be provided via a file path (using an option or a\npositional argument), an inline string, or piped from standard input.\n\nfunc(o, stdin, args)")
docreflect.Register("main.checkSyntaxOptions", "") docreflect.Register("main.checkSyntaxOptions", "")
docreflect.Register("main.checkSyntaxOptions.MaxTraceLength", "MaxTraceLength enables tracing when set to a positive integer.\n")
docreflect.Register("main.checkSyntaxOptions.Syntax", "Syntax specifies the filename of the syntax definition file.\n") docreflect.Register("main.checkSyntaxOptions.Syntax", "Syntax specifies the filename of the syntax definition file.\n")
docreflect.Register("main.checkSyntaxOptions.SyntaxString", "SyntaxString specifies the syntax as an inline string.\n") docreflect.Register("main.checkSyntaxOptions.SyntaxString", "SyntaxString specifies the syntax as an inline string.\n")
docreflect.Register("main.errInvalidFilename", "") docreflect.Register("main.errInvalidFilename", "")
docreflect.Register("main.errMultipleInputs", "") docreflect.Register("main.errMultipleInputs", "")
docreflect.Register("main.errNoInput", "") docreflect.Register("main.errNoInput", "")
docreflect.Register("main.format", "format input syntax. Accepts syntax from one or more files, inline syntax string or stdin. Use the --in-place\noption, when formatting files in place, or print the formatted syntax to stdout.\n\nfunc(o, stdin, stdout, syntax)") docreflect.Register("main.format", "format input syntax. Accepts syntax from one or more files, inline syntax string or stdin. Use the --in-place\noption, when formatting files in place, or print the formatted syntax to stdout.\n\nfunc(o, stdin, stdout, syntax)")
docreflect.Register("main.formatFile", "\nfunc(name, inPlace, out)") docreflect.Register("main.formatFile", "\nfunc(name, inPlace, maxTraceLength, out)")
docreflect.Register("main.formatFiles", "\nfunc(files, inPlace, out)") docreflect.Register("main.formatFiles", "\nfunc(files, inPlace, maxTraceLength, out)")
docreflect.Register("main.formatInline", "\nfunc(syntax, out)") docreflect.Register("main.formatInline", "\nfunc(syntax, out, maxTraceLength)")
docreflect.Register("main.formatOptions", "") docreflect.Register("main.formatOptions", "")
docreflect.Register("main.formatOptions.InPlace", "") docreflect.Register("main.formatOptions.InPlace", "InPlace specifies if an input file should be formatted in-place instead of printing the formatted\nresults to the standard output.\n")
docreflect.Register("main.formatOptions.Syntax", "") docreflect.Register("main.formatOptions.MaxTraceLength", "MaxTraceLength enables tracing when set to a positive integer.\n")
docreflect.Register("main.formatOptions.SyntaxString", "") docreflect.Register("main.formatOptions.Syntax", "Syntax specifies the filename of the syntax definition file.\n")
docreflect.Register("main.formatStdin", "\nfunc(in, out)") docreflect.Register("main.formatOptions.SyntaxString", "SyntaxString specifies the syntax as an inline string.\n")
docreflect.Register("main.formatSyntax", "\nfunc(in, out)") docreflect.Register("main.formatStdin", "\nfunc(in, out, maxTraceLength)")
docreflect.Register("main.formatSyntax", "\nfunc(in, out, maxTraceLength)")
docreflect.Register("main.generate", "generate generates Go code that can parse arbitrary input with the provided syntax, and can be used embedded\nin an application.\n\nThe syntax may be provided via a file path (using an option or a positional argument), an\ninline string, or piped from standard input.\n\nfunc(o, stdin, stdout, args)") docreflect.Register("main.generate", "generate generates Go code that can parse arbitrary input with the provided syntax, and can be used embedded\nin an application.\n\nThe syntax may be provided via a file path (using an option or a positional argument), an\ninline string, or piped from standard input.\n\nfunc(o, stdin, stdout, args)")
docreflect.Register("main.generateOptions", "") docreflect.Register("main.generateOptions", "")
docreflect.Register("main.generateOptions.Export", "Export determines whether the generated parse function is exported (visible outside its package).\n") docreflect.Register("main.generateOptions.Export", "Export determines whether the generated parse function is exported (visible outside its package).\n")
docreflect.Register("main.generateOptions.MaxTraceLength", "MaxTraceLength enables tracing when set to a positive integer.\n")
docreflect.Register("main.generateOptions.PackageName", "PackageName specifies the package name for the generated code. Defaults to main.\n") docreflect.Register("main.generateOptions.PackageName", "PackageName specifies the package name for the generated code. Defaults to main.\n")
docreflect.Register("main.generateOptions.Syntax", "Syntax specifies the filename of the syntax definition file.\n") docreflect.Register("main.generateOptions.Syntax", "Syntax specifies the filename of the syntax definition file.\n")
docreflect.Register("main.generateOptions.SyntaxString", "SyntaxString specifies the syntax as an inline string.\n") docreflect.Register("main.generateOptions.SyntaxString", "SyntaxString specifies the syntax as an inline string.\n")
@ -53,6 +57,7 @@ func init() {
docreflect.Register("main.showOptions.Indent", "Indent specifies a custom indentation string for the output.\n") docreflect.Register("main.showOptions.Indent", "Indent specifies a custom indentation string for the output.\n")
docreflect.Register("main.showOptions.Input", "Input specifies the filename of the input content to be validated.\n") docreflect.Register("main.showOptions.Input", "Input specifies the filename of the input content to be validated.\n")
docreflect.Register("main.showOptions.InputString", "InputString specifies the input content as an inline string.\n") docreflect.Register("main.showOptions.InputString", "InputString specifies the input content as an inline string.\n")
docreflect.Register("main.showOptions.MaxTraceLength", "MaxTraceLength enables tracing when set to a positive integer.\n")
docreflect.Register("main.showOptions.Pretty", "Pretty enables indented, human-readable output.\n") docreflect.Register("main.showOptions.Pretty", "Pretty enables indented, human-readable output.\n")
docreflect.Register("main.showOptions.Syntax", "Syntax specifies the filename of the syntax definition file.\n") docreflect.Register("main.showOptions.Syntax", "Syntax specifies the filename of the syntax definition file.\n")
docreflect.Register("main.showOptions.SyntaxString", "SyntaxString specifies the syntax as an inline string.\n") docreflect.Register("main.showOptions.SyntaxString", "SyntaxString specifies the syntax as an inline string.\n")

View File

@ -10,13 +10,23 @@ import (
) )
type formatOptions struct { type formatOptions struct {
// InPlace specifies if an input file should be formatted in-place instead of printing the formatted
// results to the standard output.
InPlace bool InPlace bool
// SyntaxString specifies the syntax as an inline string.
SyntaxString *string SyntaxString *string
// Syntax specifies the filename of the syntax definition file.
Syntax []string Syntax []string
// MaxTraceLength enables tracing when set to a positive integer.
MaxTraceLength int
} }
func formatSyntax(in io.Reader, out io.Writer) error { func formatSyntax(in io.Reader, out io.Writer, maxTraceLength int) error {
s := new(treerack.Syntax) s := treerack.Syntax{MaxTraceLength: maxTraceLength}
if err := s.ReadSyntax(in); err != nil { if err := s.ReadSyntax(in); err != nil {
if terr := treerack.Trace(os.Stderr, err); err != nil { if terr := treerack.Trace(os.Stderr, err); err != nil {
err = errors.Join(err, terr) err = errors.Join(err, terr)
@ -36,7 +46,7 @@ func formatSyntax(in io.Reader, out io.Writer) error {
return nil return nil
} }
func formatFile(name string, inPlace bool, out io.Writer) error { func formatFile(name string, inPlace bool, maxTraceLength int, out io.Writer) error {
var ( var (
inBytes []byte inBytes []byte
buf *bytes.Buffer buf *bytes.Buffer
@ -48,7 +58,7 @@ func formatFile(name string, inPlace bool, out io.Writer) error {
} }
buf = bytes.NewBuffer(inBytes) buf = bytes.NewBuffer(inBytes)
if err = formatSyntax(buf, buf); err != nil { if err = formatSyntax(buf, buf, maxTraceLength); err != nil {
return err return err
} }
@ -65,9 +75,9 @@ func formatFile(name string, inPlace bool, out io.Writer) error {
return os.WriteFile(name, buf.Bytes(), 0644) return os.WriteFile(name, buf.Bytes(), 0644)
} }
func formatFiles(files []string, inPlace bool, out io.Writer) error { func formatFiles(files []string, inPlace bool, maxTraceLength int, out io.Writer) error {
for _, f := range files { for _, f := range files {
if err := formatFile(f, inPlace, out); err != nil { if err := formatFile(f, inPlace, maxTraceLength, out); err != nil {
return err return err
} }
} }
@ -75,13 +85,13 @@ func formatFiles(files []string, inPlace bool, out io.Writer) error {
return nil return nil
} }
func formatInline(syntax string, out io.Writer) error { func formatInline(syntax string, out io.Writer, maxTraceLength int) error {
buf := bytes.NewBufferString(syntax) buf := bytes.NewBufferString(syntax)
return formatSyntax(buf, out) return formatSyntax(buf, out, maxTraceLength)
} }
func formatStdin(in io.Reader, out io.Writer) error { func formatStdin(in io.Reader, out io.Writer, maxTraceLength int) error {
return formatSyntax(in, out) return formatSyntax(in, out, maxTraceLength)
} }
// format input syntax. Accepts syntax from one or more files, inline syntax string or stdin. Use the --in-place // format input syntax. Accepts syntax from one or more files, inline syntax string or stdin. Use the --in-place
@ -109,12 +119,12 @@ func format(o formatOptions, stdin io.Reader, stdout io.Writer, syntax ...string
} }
if len(files) > 0 { if len(files) > 0 {
return formatFiles(files, o.InPlace, stdout) return formatFiles(files, o.InPlace, o.MaxTraceLength, stdout)
} }
if o.SyntaxString != nil { if o.SyntaxString != nil {
return formatInline(*o.SyntaxString, stdout) return formatInline(*o.SyntaxString, stdout, o.MaxTraceLength)
} }
return formatSyntax(stdin, stdout) return formatSyntax(stdin, stdout, o.MaxTraceLength)
} }

View File

@ -20,6 +20,9 @@ type generateOptions struct {
// Export determines whether the generated parse function is exported (visible outside its package). // Export determines whether the generated parse function is exported (visible outside its package).
Export bool Export bool
// MaxTraceLength enables tracing when set to a positive integer.
MaxTraceLength int
} }
// generate generates Go code that can parse arbitrary input with the provided syntax, and can be used embedded // generate generates Go code that can parse arbitrary input with the provided syntax, and can be used embedded
@ -34,7 +37,7 @@ func generate(o generateOptions, stdin io.Reader, stdout io.Writer, args ...stri
} }
defer finalizeSyntax() defer finalizeSyntax()
s := &treerack.Syntax{} s := &treerack.Syntax{MaxTraceLength: o.MaxTraceLength}
if err := s.ReadSyntax(syntax); err != nil { if err := s.ReadSyntax(syntax); err != nil {
if terr := treerack.Trace(os.Stderr, err); err != nil { if terr := treerack.Trace(os.Stderr, err); err != nil {
err = errors.Join(err, terr) err = errors.Join(err, terr)

View File

@ -32,6 +32,7 @@ argument), an inline string, or piped from standard input.
#### Options: #### Options:
- --max-trace-length int: enables tracing when set to a positive integer.
- --syntax string: specifies the filename of the syntax definition file. - --syntax string: specifies the filename of the syntax definition file.
- --syntax-string string: specifies the syntax as an inline string. - --syntax-string string: specifies the syntax as an inline string.
- --help: Show help. - --help: Show help.
@ -57,6 +58,7 @@ positional argument filename, an inline string option, or piped from standard in
- --input string: specifies the filename of the input content to be validated. - --input string: specifies the filename of the input content to be validated.
- --input-string string: specifies the input content as an inline string. - --input-string string: specifies the input content as an inline string.
- --max-trace-length int: enables tracing when set to a positive integer.
- --syntax string: specifies the filename of the syntax definition file. - --syntax string: specifies the filename of the syntax definition file.
- --syntax-string string: specifies the syntax as an inline string. - --syntax-string string: specifies the syntax as an inline string.
- --help: Show help. - --help: Show help.
@ -83,6 +85,7 @@ filename option, a positional argument filename, an inline string option, or pip
- --indent string: specifies a custom indentation string for the output. - --indent string: specifies a custom indentation string for the output.
- --input string: specifies the filename of the input content to be validated. - --input string: specifies the filename of the input content to be validated.
- --input-string string: specifies the input content as an inline string. - --input-string string: specifies the input content as an inline string.
- --max-trace-length int: enables tracing when set to a positive integer.
- --pretty bool: enables indented, human-readable output. - --pretty bool: enables indented, human-readable output.
- --syntax string: specifies the filename of the syntax definition file. - --syntax string: specifies the filename of the syntax definition file.
- --syntax-string string: specifies the syntax as an inline string. - --syntax-string string: specifies the syntax as an inline string.
@ -110,6 +113,7 @@ piped from standard input.
#### Options: #### Options:
- --export bool: determines whether the generated parse function is exported (visible outside its package). - --export bool: determines whether the generated parse function is exported (visible outside its package).
- --max-trace-length int: enables tracing when set to a positive integer.
- --package-name string: specifies the package name for the generated code. Defaults to main. - --package-name string: specifies the package name for the generated code. Defaults to main.
- --syntax string: specifies the filename of the syntax definition file. - --syntax string: specifies the filename of the syntax definition file.
- --syntax-string string: specifies the syntax as an inline string. - --syntax-string string: specifies the syntax as an inline string.
@ -131,9 +135,11 @@ when formatting files in place, or print the formatted syntax to stdout.
#### Options: #### Options:
- --in-place bool: - --in-place bool: specifies if an input file should be formatted in-place instead of printing the formatted
- --syntax string \[\*\]: results to the standard output.
- --syntax-string string: - --max-trace-length int: enables tracing when set to a positive integer.
- --syntax string \[\*\]: specifies the filename of the syntax definition file.
- --syntax-string string: specifies the syntax as an inline string.
- --help: Show help. - --help: Show help.
### treerack version ### treerack version

View File

@ -27,6 +27,9 @@ type showOptions struct {
// Indent specifies a custom indentation string for the output. // Indent specifies a custom indentation string for the output.
Indent string Indent string
// MaxTraceLength enables tracing when set to a positive integer.
MaxTraceLength int
} }
type node struct { type node struct {
@ -72,7 +75,7 @@ func show(o showOptions, stdin io.Reader, stdout io.Writer, args ...string) erro
} }
defer finalizeInput() defer finalizeInput()
s := &treerack.Syntax{} s := &treerack.Syntax{MaxTraceLength: o.MaxTraceLength}
if err := s.ReadSyntax(syntax); err != nil { if err := s.ReadSyntax(syntax); err != nil {
if terr := treerack.Trace(os.Stderr, err); err != nil { if terr := treerack.Trace(os.Stderr, err); err != nil {
err = errors.Join(err, terr) err = errors.Join(err, terr)

View File

@ -7,8 +7,6 @@ import (
"unicode" "unicode"
) )
const maxTraceEntries = 36
type context struct { type context struct {
reader io.RuneReader reader io.RuneReader
keywords []parser keywords []parser
@ -25,15 +23,17 @@ type context struct {
matchLast bool matchLast bool
level int level int
tr []TraceEntry tr []TraceEntry
maxTraceLength int
} }
func newContext(r io.RuneReader, keywords []parser) *context { func newContext(r io.RuneReader, keywords []parser, maxTraceLength int) *context {
return &context{ return &context{
reader: r, reader: r,
keywords: keywords, keywords: keywords,
results: &results{}, results: &results{},
offsetLimit: -1, offsetLimit: -1,
failOffset: -1, failOffset: -1,
maxTraceLength: maxTraceLength,
} }
} }
@ -199,11 +199,15 @@ func (c *context) finalizeParse(root parser) error {
} }
func (c *context) trace(p parser, from, to int, event TraceEvent, reason ...string) { func (c *context) trace(p parser, from, to int, event TraceEvent, reason ...string) {
if c.maxTraceLength <= 0 {
return
}
if p.commitType()&userDefined == 0 || p.commitType()&FailPass != 0 { if p.commitType()&userDefined == 0 || p.commitType()&FailPass != 0 {
return return
} }
if len(c.tr) == maxTraceEntries { if len(c.tr) == c.maxTraceLength {
c.tr = c.tr[1:] c.tr = c.tr[1:]
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -603,8 +603,6 @@ func (r *results) unmarkPending(offset, id int) {
} }
} }
const maxTraceEntries = 36
type context struct { type context struct {
reader io.RuneReader reader io.RuneReader
keywords []parser keywords []parser
@ -621,10 +619,11 @@ type context struct {
matchLast bool matchLast bool
level int level int
tr []TraceEntry tr []TraceEntry
maxTraceLength int
} }
func newContext(r io.RuneReader, keywords []parser) *context { func newContext(r io.RuneReader, keywords []parser, maxTraceLength int) *context {
return &context{reader: r, keywords: keywords, results: &results{}, offsetLimit: -1, failOffset: -1} return &context{reader: r, keywords: keywords, results: &results{}, offsetLimit: -1, failOffset: -1, maxTraceLength: maxTraceLength}
} }
func (c *context) read() bool { func (c *context) read() bool {
if c.eof || c.readErr != nil { if c.eof || c.readErr != nil {
@ -753,10 +752,13 @@ func (c *context) finalizeParse(root parser) error {
return c.parseError(root, false, root.nodeID()) return c.parseError(root, false, root.nodeID())
} }
func (c *context) trace(p parser, from, to int, event TraceEvent, reason ...string) { func (c *context) trace(p parser, from, to int, event TraceEvent, reason ...string) {
if c.maxTraceLength <= 0 {
return
}
if p.commitType()&userDefined == 0 || p.commitType()&FailPass != 0 { if p.commitType()&userDefined == 0 || p.commitType()&FailPass != 0 {
return return
} }
if len(c.tr) == maxTraceEntries { if len(c.tr) == c.maxTraceLength {
c.tr = c.tr[1:] c.tr = c.tr[1:]
} }
switch event { switch event {
@ -877,8 +879,8 @@ func (pe *ParseError) Error() string {
} }
return fmt.Sprintf("%s:%d:%d:parse failed, parsing: %s, at %d:%d", pe.Input, pe.Line+1, pe.Column+1, pe.Definition, pe.Line+1, pe.Column+1) return fmt.Sprintf("%s:%d:%d:parse failed, parsing: %s, at %d:%d", pe.Input, pe.Line+1, pe.Column+1, pe.Definition, pe.Line+1, pe.Column+1)
} }
func parseInput(r io.Reader, p parser, b builder, kw []parser) (Node, error) { func parseInput(r io.Reader, p parser, b builder, kw []parser, maxTraceLength int) (Node, error) {
c := newContext(bufio.NewReader(r), kw) c := newContext(bufio.NewReader(r), kw, maxTraceLength)
p.parse(c) p.parse(c)
if c.readErr != nil { if c.readErr != nil {
return Node{}, c.readErr return Node{}, c.readErr
@ -1468,5 +1470,5 @@ func Parse(r io.Reader) (Node, error) {
var keywords = []parser{} var keywords = []parser{}
return parseInput(r, &p183, &b183, keywords) return parseInput(r, &p183, &b183, keywords, 0)
} }

View File

@ -776,7 +776,7 @@ func TestCharBuildNoop(t *testing.T) {
c := newChar("foo", false, nil, nil) c := newChar("foo", false, nil, nil)
c.init(newRegistry()) c.init(newRegistry())
b := c.builder() b := c.builder()
ctx := newContext(bufio.NewReader(bytes.NewBuffer(nil)), nil) ctx := newContext(bufio.NewReader(bytes.NewBuffer(nil)), nil, 0)
if n, ok := b.build(ctx); len(n) != 0 || ok { if n, ok := b.build(ctx); len(n) != 0 || ok {
t.Error("char build not noop") t.Error("char build not noop")
} }

View File

@ -62,6 +62,10 @@ type Syntax struct {
explicitRoot bool explicitRoot bool
keywords []definition keywords []definition
root definition root definition
// MaxTraceLength can be used to enable tracing by setting a positive value. It should be set before
// parsing.
MaxTraceLength int
} }
// GeneratorOptions control the behavior of the Go code generator. // GeneratorOptions control the behavior of the Go code generator.
@ -570,7 +574,7 @@ func (s *Syntax) Generate(o GeneratorOptions, w io.Writer) error {
fprintln() fprintln()
fprintln() fprintln()
fprintf(`return parseInput(r, &p%d, &b%d, keywords)`, s.root.parser().nodeID(), s.root.builder().nodeID()) fprintf(`return parseInput(r, &p%d, &b%d, keywords, 0)`, s.root.parser().nodeID(), s.root.builder().nodeID())
fprintln() fprintln()
fprint(`}`) fprint(`}`)
fprintln() fprintln()
@ -584,7 +588,7 @@ func (s *Syntax) Parse(r io.Reader) (Node, error) {
return Node{}, err return Node{}, err
} }
return parseInput(r, s.root.parser(), s.root.builder(), s.keywordParsers()) return parseInput(r, s.root.parser(), s.root.builder(), s.keywordParsers(), s.MaxTraceLength)
} }
// Format prints the loaded syntax definition to the output in a formatted way. // Format prints the loaded syntax definition to the output in a formatted way.

View File

@ -199,8 +199,8 @@ func (pe *ParseError) Error() string {
) )
} }
func parseInput(r io.Reader, p parser, b builder, kw []parser) (Node, error) { func parseInput(r io.Reader, p parser, b builder, kw []parser, maxTraceLength int) (Node, error) {
c := newContext(bufio.NewReader(r), kw) c := newContext(bufio.NewReader(r), kw, maxTraceLength)
p.parse(c) p.parse(c)
if c.readErr != nil { if c.readErr != nil {
return Node{}, c.readErr return Node{}, c.readErr