error message

This commit is contained in:
Arpad Ryszka 2017-11-26 02:34:34 +01:00
parent a25d7523b5
commit 0ebf532a30
3 changed files with 73 additions and 2 deletions

View File

@ -103,7 +103,7 @@ func (c *context) recordFailure(p parser) {
}
c.failOffset = c.offset
if p.commitType()&userDefined != 0 {
if p.commitType()&userDefined != 0 && p.commitType()&Whitespace == 0 {
c.failingParser = p
}
}

View File

@ -93,6 +93,11 @@ func TestError(t *testing.T) {
return
}
if perr.Input != "<input>" {
t.Error("invalid default input name")
return
}
if perr.Offset != test.offset {
t.Error("invalid error offset", perr.Offset, test.offset)
return
@ -113,3 +118,48 @@ func TestError(t *testing.T) {
})
}
}
func TestErrorMessage(t *testing.T) {
const expected = "foo:4:10:failed to parse definition: bar"
perr := &ParseError{
Input: "foo",
Offset: 42,
Line: 3,
Column: 9,
Definition: "bar",
}
message := perr.Error()
if message != expected {
t.Error("failed to return the right error message")
t.Log("got: ", message)
t.Log("expected:", expected)
}
}
func TestErrorVerbose(t *testing.T) {
const expected = `
`
const doc = `{
"a": 1,
"b": 2,
"c": 3,
}`
s, err := openSyntaxFile("examples/json.treerack")
if err != nil {
t.Error(err)
return
}
_, err = s.Parse(bytes.NewBufferString(doc))
perr, ok := err.(*ParseError)
if !ok {
t.Error("failed to return parse error")
return
}
t.Log(perr.Error())
}

View File

@ -38,6 +38,10 @@ type SequenceItem struct {
// the used syntax during parsing.
type ParseError struct {
// Input is the name of the input file or <input> if not
// available.
Input string
// Offset is the index of the right-most failing
// token in the input text.
Offset int
@ -55,6 +59,8 @@ type ParseError struct {
// Definition tells the right-most unmatched parser definition.
Definition string
registry *registry
}
type Syntax struct {
@ -152,7 +158,17 @@ func intsContain(is []int, i int) bool {
}
func (pe *ParseError) Error() string {
return "parse error"
return fmt.Sprintf(
"%s:%d:%d:failed to parse definition: %s",
pe.Input,
pe.Line+1,
pe.Column+1,
pe.Definition,
)
}
func (pe *ParseError) Verbose() string {
return ""
}
func (s *Syntax) applyRoot(d definition) error {
@ -354,6 +370,11 @@ func (s *Syntax) Parse(r io.Reader) (*Node, error) {
}
if err := c.finalizeParse(s.parser); err != nil {
if perr, ok := err.(*ParseError); ok {
perr.Input = "<input>"
perr.registry = s.registry
}
return nil, err
}