Skip to content

Commit

Permalink
Merge pull request #16 from nickng/nickng-scan-error-not-fatal
Browse files Browse the repository at this point in the history
Return scan error as error not log.Fatal
  • Loading branch information
nickng authored May 21, 2022
2 parents 61c36c5 + 81c4e64 commit c84f200
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 71 deletions.
4 changes: 3 additions & 1 deletion bibtex.y
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ func Parse(r io.Reader) (*BibTex, error) {
l := newLexer(r)
bibtexParse(l)
select {
case err := <-l.Errors:
case err := <-l.Errors: // Non-yacc errors
return nil, err
case err := <-l.ParseErrors:
return nil, err
default:
return bib, nil
Expand Down
83 changes: 42 additions & 41 deletions bibtex.y.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions bibtex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package bibtex

import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"path/filepath"
Expand Down Expand Up @@ -145,6 +146,21 @@ func TestPrettyStringRoundTrip(t *testing.T) {
}
}

func TestUnexpectedAtSign(t *testing.T) {
// Tests correct syntax but scanning error
b, err := ioutil.ReadFile("example/unexpected-at-sign.badbib")
if err != nil {
t.Fatal(err)
}
_, err = Parse(bytes.NewReader(b))
if err == nil {
t.Fatal("Expected error but got none")
}
if !errors.Is(err, ErrUnexpectedAtsign) {
t.Fatalf("expected error %+v but got %+v", ErrUnexpectedAtsign, err)
}
}

func AssertEntryListsEqual(t *testing.T, a, b []*BibEntry) {
t.Helper()

Expand Down
6 changes: 3 additions & 3 deletions error.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import (

var (
// ErrUnexpectedAtsign is an error for unexpected @ in {}.
ErrUnexpectedAtsign = errors.New("Unexpected @ sign")
ErrUnexpectedAtsign = errors.New("unexpected @ sign")
// ErrUnknownStringVar is an error for looking up undefined string var.
ErrUnknownStringVar = errors.New("Unknown string variable")
ErrUnknownStringVar = errors.New("unknown string variable")
)

// ErrParse is a parse error.
Expand All @@ -19,5 +19,5 @@ type ErrParse struct {
}

func (e *ErrParse) Error() string {
return fmt.Sprintf("Parse failed at %s: %s", e.Pos, e.Err)
return fmt.Sprintf("parse failed at %s: %s", e.Pos, e.Err)
}
3 changes: 3 additions & 0 deletions example/unexpected-at-sign.badbib
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@misc{web,
y = {ab@cd},
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module github.com/nickng/bibtex

go 1.13
go 1.18

require github.com/BurntSushi/toml v0.3.1
24 changes: 18 additions & 6 deletions lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,39 @@

package bibtex

import "io"
import (
"fmt"
"io"
)

// lexer for bibtex.
type lexer struct {
scanner *scanner
Errors chan error
scanner *scanner
ParseErrors chan error // Parse errors from yacc
Errors chan error // Other errors
}

// newLexer returns a new yacc-compatible lexer.
func newLexer(r io.Reader) *lexer {
return &lexer{scanner: newScanner(r), Errors: make(chan error, 1)}
return &lexer{
scanner: newScanner(r),
ParseErrors: make(chan error, 1),
Errors: make(chan error, 1),
}
}

// Lex is provided for yacc-compatible parser.
func (l *lexer) Lex(yylval *bibtexSymType) int {
token, strval := l.scanner.Scan()
token, strval, err := l.scanner.Scan()
if err != nil {
l.Errors <- fmt.Errorf("%w at %s", err, l.scanner.pos)
return int(0)
}
yylval.strval = strval
return int(token)
}

// Error handles error.
func (l *lexer) Error(err string) {
l.Errors <- &ErrParse{Err: err, Pos: l.scanner.pos}
l.ParseErrors <- &ErrParse{Err: err, Pos: l.scanner.pos}
}
Loading

0 comments on commit c84f200

Please sign in to comment.