-
Notifications
You must be signed in to change notification settings - Fork 2
/
parser.go
77 lines (66 loc) · 1.47 KB
/
parser.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
package spiker
import (
"fmt"
)
// Parser Lexer parser
type Parser struct {
Lexer *Lexer
}
func (psr *Parser) expression(rbp int) *Token {
var left *Token
t := psr.Lexer.next()
if t.nud != nil {
left = t.nud(t, psr)
} else {
panic(fmt.Sprint("syntax error: NOT PREFIX ", t.Format()))
}
for rbp < psr.Lexer.peek().bindingPower {
t := psr.Lexer.next()
if t.led != nil {
left = t.led(t, psr, left)
} else {
panic(fmt.Sprint("syntax error: NOT INFIX ", t.Format()))
}
}
return left
}
// Statements parse statements
func (psr *Parser) Statements() (stmts []*Token, err error) {
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("%v", e)
}
}()
next := psr.Lexer.peek()
for next.sym != SymbolEOF && next.sym != SymbolRbrace {
stmts = append(stmts, psr.statement())
next = psr.Lexer.peek()
}
return
}
func (psr *Parser) block() *Token {
t := psr.Lexer.next()
if t.sym != SymbolLbrace {
panic(fmt.Sprint("syntax error: was looking for block start ", t.Format()))
}
return t.std(t, psr)
}
func (psr *Parser) statement() *Token {
t := psr.Lexer.peek()
if t.std != nil {
t = psr.Lexer.next()
return t.std(t, psr)
}
res := psr.expression(0)
psr.advance(SymbolSemicolon)
return res
}
func (psr *Parser) advance(sym Symbol) *Token {
line := psr.Lexer.line
col := psr.Lexer.col
t := psr.Lexer.next()
if t.sym != sym {
panic(fmt.Sprintf(`syntax error: expected "%s", but got "%s", on line %d:%d`, sym, t.sym, line, col))
}
return t
}