-
Notifications
You must be signed in to change notification settings - Fork 0
/
parserrs.go
132 lines (113 loc) · 3.44 KB
/
parserrs.go
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package expressions
import "strconv"
// OperatorError is an error indicating an operator token that is not
// understood by the parser. It implements InputError.
type OperatorError struct {
// Col is the position of the operator.
Col int
// Operator is the token that was not understood.
Operator string
// Unary is whether the parser expected a unary operator at the time.
Unary bool
}
func (err *OperatorError) Error() string {
s := "binary"
if err.Unary {
s = "unary"
}
return errpos(err.Col, "unknown "+s+" operator "+strconv.Quote(err.Operator))
}
func (err *OperatorError) Pos() int {
return err.Col
}
// BracketError is an error indicating mismatched brackets in the
// input. It implements InputError.
type BracketError struct {
// Col is the position of the operator.
Col int
// Left is the opening bracket.
Left string
// Right is the mismatched closing bracket.
Right string
}
func (err *BracketError) Error() string {
if err.Left == "" {
return errpos(err.Col, "close bracket "+err.Right+" with no open bracket")
}
if err.Right == "" {
return errpos(err.Col, "open bracket "+err.Left+" with no close bracket")
}
return errpos(err.Col, "mismatched bracket: "+err.Left+"expr"+err.Right)
}
func (err *BracketError) Pos() int {
return err.Col
}
// SeparatorError is an error indicating an illegal use of a comma or semicolon
// separator. It implements InputError.
type SeparatorError struct {
// Col is the position of the separator.
Col int
// Sep is the separator.
Sep string
}
func (err *SeparatorError) Error() string {
return errpos(err.Col, "invalid occurrence of separator "+strconv.Quote(err.Sep))
}
func (err *SeparatorError) Pos() int {
return err.Col
}
// CallError is an error indicating a function call with the wrong number of
// arguments. It implements InputError.
type CallError struct {
// Col is the position of the end of the call expression.
Col int
// Func is the function name that was called.
Func string
// Len is the number of arguments the function call tried to imply.
Len int
}
func (err *CallError) Error() string {
return errpos(err.Col, "cannot call "+err.Func+" with "+strconv.Itoa(err.Len)+" arguments")
}
func (err *CallError) Pos() int {
return err.Col
}
// EmptyExpressionError is an error indicating an empty subexpression.
type EmptyExpressionError struct {
// Col is the position of the token that ended the subexpression.
Col int
// End is the token that ended the subexpression.
End string
}
func (err *EmptyExpressionError) Error() string {
if err.End == "" {
if err.Col <= 1 {
return errpos(err.Col, "no expression")
}
return errpos(err.Col, "no expression at end")
}
return errpos(err.Col, "no expression up to "+strconv.Quote(err.End))
}
func (err *EmptyExpressionError) Pos() int {
return err.Col
}
// errpos is a shortcut to create an error message with a position.
func errpos(pos int, msg string) string {
return strconv.Itoa(pos) + ": " + msg
}
// InputError is an error with position information. Every error resulting from
// invalid input implements InputError.
type InputError interface {
error
// Pos returns the position of the error as the number of runes up to and
// including the start of the token that caused the error.
Pos() int
}
var (
_ InputError = (*OperatorError)(nil)
_ InputError = (*BracketError)(nil)
_ InputError = (*SeparatorError)(nil)
_ InputError = (*CallError)(nil)
_ InputError = (*EmptyExpressionError)(nil)
_ InputError = (*LexError)(nil)
)