Skip to content

Commit a13ee0e

Browse files
committed
allow reusing the parser
1 parent 2f4437c commit a13ee0e

File tree

1 file changed

+57
-48
lines changed

1 file changed

+57
-48
lines changed

parser/parser.go

Lines changed: 57 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ var predicates = map[string]struct {
4747
"reduce": {[]arg{expr, predicate, expr | optional}},
4848
}
4949

50-
type parser struct {
50+
// Parser is a reusable parser. The zero value is ready for use.
51+
type Parser struct {
5152
lexer *lexer.Lexer
5253
current, stashed Token
5354
hasStash bool
@@ -57,7 +58,38 @@ type parser struct {
5758
nodeCount uint // tracks number of AST nodes created
5859
}
5960

60-
func (p *parser) checkNodeLimit() error {
61+
func (p *Parser) Parse(input string, config *conf.Config) (*Tree, error) {
62+
if p.lexer == nil {
63+
p.lexer = lexer.New()
64+
}
65+
p.config = config
66+
source := file.NewSource(input)
67+
p.lexer.Reset(source)
68+
p.next()
69+
node := p.parseSequenceExpression()
70+
71+
if !p.current.Is(EOF) {
72+
p.error("unexpected token %v", p.current)
73+
}
74+
75+
tree := &Tree{
76+
Node: node,
77+
Source: source,
78+
}
79+
err := p.err
80+
81+
// cleanup non-reusable pointer values
82+
p.err = nil
83+
p.config = nil
84+
85+
if err != nil {
86+
return tree, err.Bind(source)
87+
}
88+
89+
return tree, nil
90+
}
91+
92+
func (p *Parser) checkNodeLimit() error {
6193
p.nodeCount++
6294
if p.config == nil {
6395
if p.nodeCount > conf.DefaultMaxNodes {
@@ -73,7 +105,7 @@ func (p *parser) checkNodeLimit() error {
73105
return nil
74106
}
75107

76-
func (p *parser) createNode(n Node, loc file.Location) Node {
108+
func (p *Parser) createNode(n Node, loc file.Location) Node {
77109
if err := p.checkNodeLimit(); err != nil {
78110
return nil
79111
}
@@ -84,7 +116,7 @@ func (p *parser) createNode(n Node, loc file.Location) Node {
84116
return n
85117
}
86118

87-
func (p *parser) createMemberNode(n *MemberNode, loc file.Location) *MemberNode {
119+
func (p *Parser) createMemberNode(n *MemberNode, loc file.Location) *MemberNode {
88120
if err := p.checkNodeLimit(); err != nil {
89121
return nil
90122
}
@@ -105,37 +137,14 @@ func Parse(input string) (*Tree, error) {
105137
}
106138

107139
func ParseWithConfig(input string, config *conf.Config) (*Tree, error) {
108-
p := &parser{
109-
lexer: lexer.New(),
110-
config: config,
111-
}
112-
113-
source := file.NewSource(input)
114-
p.lexer.Reset(source)
115-
p.next()
116-
node := p.parseSequenceExpression()
117-
118-
if !p.current.Is(EOF) {
119-
p.error("unexpected token %v", p.current)
120-
}
121-
122-
tree := &Tree{
123-
Node: node,
124-
Source: source,
125-
}
126-
127-
if p.err != nil {
128-
return tree, p.err.Bind(source)
129-
}
130-
131-
return tree, nil
140+
return new(Parser).Parse(input, config)
132141
}
133142

134-
func (p *parser) error(format string, args ...any) {
143+
func (p *Parser) error(format string, args ...any) {
135144
p.errorAt(p.current, format, args...)
136145
}
137146

138-
func (p *parser) errorAt(token Token, format string, args ...any) {
147+
func (p *Parser) errorAt(token Token, format string, args ...any) {
139148
if p.err == nil { // show first error
140149
p.err = &file.Error{
141150
Location: token.Location,
@@ -144,7 +153,7 @@ func (p *parser) errorAt(token Token, format string, args ...any) {
144153
}
145154
}
146155

147-
func (p *parser) next() {
156+
func (p *Parser) next() {
148157
if p.hasStash {
149158
p.current = p.stashed
150159
p.hasStash = false
@@ -169,7 +178,7 @@ func (p *parser) next() {
169178
}
170179
}
171180

172-
func (p *parser) expect(kind Kind, values ...string) {
181+
func (p *Parser) expect(kind Kind, values ...string) {
173182
if p.current.Is(kind, values...) {
174183
p.next()
175184
return
@@ -179,7 +188,7 @@ func (p *parser) expect(kind Kind, values ...string) {
179188

180189
// parse functions
181190

182-
func (p *parser) parseSequenceExpression() Node {
191+
func (p *Parser) parseSequenceExpression() Node {
183192
nodes := []Node{p.parseExpression(0)}
184193

185194
for p.current.Is(Operator, ";") && p.err == nil {
@@ -200,7 +209,7 @@ func (p *parser) parseSequenceExpression() Node {
200209
}, nodes[0].Location())
201210
}
202211

203-
func (p *parser) parseExpression(precedence int) Node {
212+
func (p *Parser) parseExpression(precedence int) Node {
204213
if p.err != nil {
205214
return nil
206215
}
@@ -303,7 +312,7 @@ func (p *parser) parseExpression(precedence int) Node {
303312
return nodeLeft
304313
}
305314

306-
func (p *parser) parseVariableDeclaration() Node {
315+
func (p *Parser) parseVariableDeclaration() Node {
307316
p.expect(Operator, "let")
308317
variableName := p.current
309318
p.expect(Identifier)
@@ -318,7 +327,7 @@ func (p *parser) parseVariableDeclaration() Node {
318327
}, variableName.Location)
319328
}
320329

321-
func (p *parser) parseConditionalIf() Node {
330+
func (p *Parser) parseConditionalIf() Node {
322331
p.next()
323332
nodeCondition := p.parseExpression(0)
324333
p.expect(Bracket, "{")
@@ -337,7 +346,7 @@ func (p *parser) parseConditionalIf() Node {
337346

338347
}
339348

340-
func (p *parser) parseConditional(node Node) Node {
349+
func (p *Parser) parseConditional(node Node) Node {
341350
var expr1, expr2 Node
342351
for p.current.Is(Operator, "?") && p.err == nil {
343352
p.next()
@@ -364,7 +373,7 @@ func (p *parser) parseConditional(node Node) Node {
364373
return node
365374
}
366375

367-
func (p *parser) parsePrimary() Node {
376+
func (p *Parser) parsePrimary() Node {
368377
token := p.current
369378

370379
if token.Is(Operator) {
@@ -417,7 +426,7 @@ func (p *parser) parsePrimary() Node {
417426
return p.parseSecondary()
418427
}
419428

420-
func (p *parser) parseSecondary() Node {
429+
func (p *Parser) parseSecondary() Node {
421430
var node Node
422431
token := p.current
423432

@@ -516,23 +525,23 @@ func (p *parser) parseSecondary() Node {
516525
return p.parsePostfixExpression(node)
517526
}
518527

519-
func (p *parser) toIntegerNode(number int64) Node {
528+
func (p *Parser) toIntegerNode(number int64) Node {
520529
if number > math.MaxInt {
521530
p.error("integer literal is too large")
522531
return nil
523532
}
524533
return p.createNode(&IntegerNode{Value: int(number)}, p.current.Location)
525534
}
526535

527-
func (p *parser) toFloatNode(number float64) Node {
536+
func (p *Parser) toFloatNode(number float64) Node {
528537
if number > math.MaxFloat64 {
529538
p.error("float literal is too large")
530539
return nil
531540
}
532541
return p.createNode(&FloatNode{Value: number}, p.current.Location)
533542
}
534543

535-
func (p *parser) parseCall(token Token, arguments []Node, checkOverrides bool) Node {
544+
func (p *Parser) parseCall(token Token, arguments []Node, checkOverrides bool) Node {
536545
var node Node
537546

538547
isOverridden := false
@@ -610,7 +619,7 @@ func (p *parser) parseCall(token Token, arguments []Node, checkOverrides bool) N
610619
return node
611620
}
612621

613-
func (p *parser) parseArguments(arguments []Node) []Node {
622+
func (p *Parser) parseArguments(arguments []Node) []Node {
614623
// If pipe operator is used, the first argument is the left-hand side
615624
// of the operator, so we do not parse it as an argument inside brackets.
616625
offset := len(arguments)
@@ -631,7 +640,7 @@ func (p *parser) parseArguments(arguments []Node) []Node {
631640
return arguments
632641
}
633642

634-
func (p *parser) parsePredicate() Node {
643+
func (p *Parser) parsePredicate() Node {
635644
startToken := p.current
636645
withBrackets := false
637646
if p.current.Is(Bracket, "{") {
@@ -663,7 +672,7 @@ func (p *parser) parsePredicate() Node {
663672
return predicateNode
664673
}
665674

666-
func (p *parser) parseArrayExpression(token Token) Node {
675+
func (p *Parser) parseArrayExpression(token Token) Node {
667676
nodes := make([]Node, 0)
668677

669678
p.expect(Bracket, "[")
@@ -687,7 +696,7 @@ end:
687696
return node
688697
}
689698

690-
func (p *parser) parseMapExpression(token Token) Node {
699+
func (p *Parser) parseMapExpression(token Token) Node {
691700
p.expect(Bracket, "{")
692701

693702
nodes := make([]Node, 0)
@@ -740,7 +749,7 @@ end:
740749
return node
741750
}
742751

743-
func (p *parser) parsePostfixExpression(node Node) Node {
752+
func (p *Parser) parsePostfixExpression(node Node) Node {
744753
postfixToken := p.current
745754
for (postfixToken.Is(Operator) || postfixToken.Is(Bracket)) && p.err == nil {
746755
optional := postfixToken.Value == "?."
@@ -870,7 +879,7 @@ func (p *parser) parsePostfixExpression(node Node) Node {
870879
}
871880
return node
872881
}
873-
func (p *parser) parseComparison(left Node, token Token, precedence int) Node {
882+
func (p *Parser) parseComparison(left Node, token Token, precedence int) Node {
874883
var rootNode Node
875884
for {
876885
comparator := p.parseExpression(precedence + 1)

0 commit comments

Comments
 (0)