2017-11-20 06:10:04 +01:00
|
|
|
package parse
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
|
|
|
|
"github.com/tdewolff/parse/buffer"
|
|
|
|
)
|
|
|
|
|
2017-12-16 20:25:18 +01:00
|
|
|
// Error is a parsing error returned by parser. It contains a message and an offset at which the error occurred.
|
2017-11-20 06:10:04 +01:00
|
|
|
type Error struct {
|
|
|
|
Message string
|
2017-12-16 20:25:18 +01:00
|
|
|
r io.Reader
|
|
|
|
Offset int
|
|
|
|
line int
|
|
|
|
column int
|
|
|
|
context string
|
2017-11-20 06:10:04 +01:00
|
|
|
}
|
|
|
|
|
2017-12-16 20:25:18 +01:00
|
|
|
// NewError creates a new error
|
2017-11-20 06:10:04 +01:00
|
|
|
func NewError(msg string, r io.Reader, offset int) *Error {
|
|
|
|
return &Error{
|
2017-12-16 20:25:18 +01:00
|
|
|
Message: msg,
|
|
|
|
r: r,
|
|
|
|
Offset: offset,
|
2017-11-20 06:10:04 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-16 20:25:18 +01:00
|
|
|
// NewErrorLexer creates a new error from a *buffer.Lexer
|
2017-11-20 06:10:04 +01:00
|
|
|
func NewErrorLexer(msg string, l *buffer.Lexer) *Error {
|
|
|
|
r := buffer.NewReader(l.Bytes())
|
|
|
|
offset := l.Offset()
|
|
|
|
return NewError(msg, r, offset)
|
|
|
|
}
|
|
|
|
|
2017-12-16 20:25:18 +01:00
|
|
|
// Positions re-parses the file to determine the line, column, and context of the error.
|
|
|
|
// Context is the entire line at which the error occurred.
|
|
|
|
func (e *Error) Position() (int, int, string) {
|
|
|
|
if e.line == 0 {
|
|
|
|
e.line, e.column, e.context, _ = Position(e.r, e.Offset)
|
|
|
|
}
|
|
|
|
return e.line, e.column, e.context
|
|
|
|
}
|
|
|
|
|
|
|
|
// Error returns the error string, containing the context and line + column number.
|
2017-11-20 06:10:04 +01:00
|
|
|
func (e *Error) Error() string {
|
2017-12-16 20:25:18 +01:00
|
|
|
line, column, context := e.Position()
|
|
|
|
return fmt.Sprintf("parse error:%d:%d: %s\n%s", line, column, e.Message, context)
|
2017-11-20 06:10:04 +01:00
|
|
|
}
|