-
Notifications
You must be signed in to change notification settings - Fork 1
/
parser.go
82 lines (67 loc) · 1.31 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
78
79
80
81
82
package gorillang
var codePointMap = map[TokenType]CodePoint{
X0: "0",
X1: "1",
X2: "2",
X3: "3",
X4: "4",
X5: "5",
X6: "6",
X7: "7",
X8: "8",
X9: "9",
XA: "A",
XB: "B",
XC: "C",
XD: "D",
XE: "E",
XF: "F",
}
type Parser struct {
l *Lexer
curToken Token
peekToken Token
}
func NewParser(l *Lexer) *Parser {
p := &Parser{l: l}
// 2つトークンを読み込む。curToken と peekToken の両方がセットされる。
p.nextToken()
p.nextToken()
return p
}
func (p *Parser) nextToken() {
p.curToken = p.peekToken
p.peekToken = p.l.NextToken()
}
func (p *Parser) ParseSentence() *Sentence {
sentence := &Sentence{}
sentence.CodePoints = []CodePoint{}
for p.curToken.Type != EOF {
cp := p.parseSentence()
if cp != "" {
sentence.CodePoints = append(sentence.CodePoints, cp)
}
p.nextToken()
}
return sentence
}
func (p *Parser) parseSentence() CodePoint {
var codePoint CodePoint
if p.curToken.Type != PREFIX {
return "" // TODO: error
}
p.nextToken()
return p.recursiveFn(codePoint)
}
func (p *Parser) recursiveFn(codePoint CodePoint) CodePoint {
switch tType := p.curToken.Type; tType {
case ILLEGAL:
return codePoint // TODO: error
case EOF, WHITESPACE:
return codePoint
default:
codePoint += codePointMap[tType]
p.nextToken()
return p.recursiveFn(codePoint)
}
}