-
Notifications
You must be signed in to change notification settings - Fork 221
/
Copy patherrors.go.template
100 lines (88 loc) · 2.29 KB
/
errors.go.template
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// ================================================================
// During the Miller build, after GOCC codegen and Go compile, this is copied
// over the top of GOCC codegen so that we can customize handling of error
// messages.
//
// Source: internal/pkg/parsing/errors.go.template
// Destination: internal/pkg/parsing/errors/errors.go
// ================================================================
package errors
import (
"fmt"
"strings"
"github.com/johnkerl/miller/internal/pkg/parsing/token"
)
type ErrorSymbol interface {
}
type Error struct {
Err error
ErrorToken *token.Token
ErrorSymbols []ErrorSymbol
ExpectedTokens []string
StackTop int
}
func (e *Error) String() string {
w := new(strings.Builder)
fmt.Fprintf(w, "Error")
if e.Err != nil {
fmt.Fprintf(w, " %s\n", e.Err)
} else {
fmt.Fprintf(w, "\n")
}
fmt.Fprintf(w, "Token: type=%d, lit=%s\n", e.ErrorToken.Type, e.ErrorToken.Lit)
fmt.Fprintf(w, "Pos: offset=%d, line=%d, column=%d\n", e.ErrorToken.Pos.Offset, e.ErrorToken.Pos.Line, e.ErrorToken.Pos.Column)
fmt.Fprintf(w, "Expected one of: ")
for _, sym := range e.ExpectedTokens {
fmt.Fprintf(w, "%s ", sym)
}
fmt.Fprintf(w, "ErrorSymbol:\n")
for _, sym := range e.ErrorSymbols {
fmt.Fprintf(w, "%v\n", sym)
}
return w.String()
}
func (e *Error) Error() string {
w := new(strings.Builder)
fmt.Fprintf(
w,
"Parse error on token \"%s\" at line %d column %d.\n",
string(e.ErrorToken.Lit),
e.ErrorToken.Pos.Line,
e.ErrorToken.Pos.Column,
)
if e.Err != nil {
fmt.Fprintf(w, "%+v\n", e.Err)
} else {
suggestSemicolons := false
for _, expected := range e.ExpectedTokens {
if expected == ";" {
suggestSemicolons = true
break
}
}
if suggestSemicolons {
fmt.Fprintf(w, "Please check for missing semicolon.\n")
}
fmt.Fprintf(w, "Expected one of:\n")
//for _, expected := range e.ExpectedTokens {
// fmt.Fprintf(w, "%s ", expected)
//}
// Print a carriage return every so often, in case there are many possible
// next tokens.
line := ""
for _, expected := range e.ExpectedTokens {
if line != "" {
line += " "
}
line += expected
if len(line) > 70 {
fmt.Fprintf(w, " %s\n", line)
line = ""
}
}
if line != "" {
fmt.Fprintf(w, " %s\n", line)
}
}
return w.String()
}