-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlexer.go
54 lines (48 loc) · 1.67 KB
/
lexer.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
package main
import (
"fmt"
lexical "github.com/Mellywins/GoLexThatJava/lexical"
"github.com/timtadh/lexmachine"
)
type golex struct {
*lexmachine.Scanner
stmts []*Node
}
func newGoLex(lexer *lexmachine.Lexer, text []byte) (*golex, error) {
scan, err := lexer.Scanner(text)
if err != nil {
return nil, err
}
return &golex{Scanner: scan}, nil
}
// Lex implements yyLexer's interface for getting the next token. It returns the
// token type as an integer. The tokens should be defined in the $parser.y file.
// The actual number returned will be >= yyPrivate - 1 which is the range for
// custom token names.
func (g *golex) Lex(lval *yySymType) (tokenType int) {
s := g.Scanner
tok, err, eof := s.Next()
if err != nil {
g.Error(fmt.Sprintf("%s at (%d,%d)",
err.Error(), tok.(*lexmachine.Token).StartLine,
tok.(*lexmachine.Token).StartColumn))
} else if eof {
return -1 // signals EOF to goyacc's yyParse
}
lval.token = tok.(*lexmachine.Token)
// To return the correct number for goyacc you must add yyPrivate - 1 to
// put the value into the correct range.
return lval.token.Type + yyPrivate + 2
}
// Error implements the error handling for if there is a parse error of any
// kind. This implementation panics. There may be no better way to hand errors
// from goyacc. I recommend you use defer ... recover() to handle this where
// you call into the parser.
func (l *golex) Error(message string) {
// is there a better way to handle this in the context of goyacc?
panic(fmt.Errorf(fmt.Sprintf("error occured at,(%d) with message %s \n", l.Scanner.TC, message)))
panic(fmt.Errorf("error occured at "))
}
func newLexer() *lexmachine.Lexer {
return lexical.NewLexer()
}