From 7628271e5d363a9a7283efb6f7d8b1b52e392e45 Mon Sep 17 00:00:00 2001 From: Ting-Wei Lan Date: Thu, 21 Feb 2019 18:28:32 +0800 Subject: core: vm: sqlvm: fill source code position in AST nodes Now all AST nodes should have position information recorded during parsing. These fields are intended to be used to report errors and make debugging easier. However, precise location of each token is currently unavailable. It can be done in the future if it becomes necessary. To make it easier to traverse an AST, GetChildren is modified to skip nil nodes in the output. This means callers of GetChildren don't have to check for nil in returned slices. AST printer is modified to print the position and the corresponding source code token. A few special handling for interfaces are removed because reflection works better for structs. --- core/vm/sqlvm/cmd/ast-printer/main.go | 5 +++-- core/vm/sqlvm/cmd/pigeon-gofmt/main.go | 12 +++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'core/vm/sqlvm/cmd') diff --git a/core/vm/sqlvm/cmd/ast-printer/main.go b/core/vm/sqlvm/cmd/ast-printer/main.go index 86a742909..33710f2b0 100644 --- a/core/vm/sqlvm/cmd/ast-printer/main.go +++ b/core/vm/sqlvm/cmd/ast-printer/main.go @@ -15,11 +15,12 @@ func main() { flag.Parse() - n, err := parser.Parse([]byte(flag.Arg(0))) + s := []byte(flag.Arg(0)) + n, err := parser.Parse(s) fmt.Printf("detail: %t\n", detail) if err != nil { fmt.Fprintf(os.Stderr, "err:\n%+v\n", err) os.Exit(1) } - ast.PrintAST(os.Stdout, n, " ", detail) + ast.PrintAST(os.Stdout, n, s, " ", detail) } diff --git a/core/vm/sqlvm/cmd/pigeon-gofmt/main.go b/core/vm/sqlvm/cmd/pigeon-gofmt/main.go index 08623d5f8..141bf132c 100644 --- a/core/vm/sqlvm/cmd/pigeon-gofmt/main.go +++ b/core/vm/sqlvm/cmd/pigeon-gofmt/main.go @@ -124,6 +124,7 @@ func (b *buffer) skipSection(opening, closing, escape rune, func pegFormat(src []byte) ([]byte, error) { b := newBuffer(src) + indent := 0 for { r, err := b.nextRune() @@ -139,6 +140,10 @@ func pegFormat(src []byte) ([]byte, error) { } switch r { + case '\n': + indent = 0 + case '\t': + indent++ case '/': r, err = b.nextRune() if err != nil { @@ -211,7 +216,12 @@ func pegFormat(src []byte) ([]byte, error) { return nil, err } } else { - _, err = b.out.Write(formatted[1:]) + formatted = formatted[1:] + pattern := []byte{'\n'} + replacement := append([]byte{'\n'}, + bytes.Repeat([]byte{'\t'}, indent)...) + formatted = bytes.Replace(formatted, pattern, replacement, -1) + _, err = b.out.Write(formatted) if err != nil { return nil, err } -- cgit v1.2.3