Skip to content

Commit cce4c66

Browse files
committed
Reduce bloblang parser allocations
1 parent 0b25d04 commit cce4c66

12 files changed

+556
-664
lines changed

internal/bloblang/parser/combinators.go

Lines changed: 134 additions & 159 deletions
Large diffs are not rendered by default.

internal/bloblang/parser/combinators_test.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ func TestNotInSet(t *testing.T) {
184184
}
185185

186186
func TestEmptyLine(t *testing.T) {
187-
parser := EmptyLine()
187+
parser := EmptyLine
188188

189189
tests := map[string]struct {
190190
input string
@@ -439,7 +439,7 @@ func TestBestMatch(t *testing.T) {
439439
}
440440

441441
func TestSnakeCase(t *testing.T) {
442-
parser := SnakeCase()
442+
parser := SnakeCase
443443

444444
tests := map[string]struct {
445445
input string
@@ -724,7 +724,7 @@ func TestAllOf(t *testing.T) {
724724
}
725725

726726
func TestDelimited(t *testing.T) {
727-
parser := Delimited(Term("abc"), Char('#'))
727+
parser := Delimited(Term("abc"), charHash)
728728

729729
tests := map[string]struct {
730730
input string
@@ -779,7 +779,7 @@ func TestDelimited(t *testing.T) {
779779
}
780780

781781
func TestDelimitedPattern(t *testing.T) {
782-
parser := DelimitedPattern(Char('#'), Term("abc"), Char(','), Char('!'), false)
782+
parser := DelimitedPattern(charHash, Term("abc"), charComma, Char('!'), false)
783783

784784
tests := map[string]struct {
785785
input string
@@ -843,7 +843,7 @@ func TestDelimitedPattern(t *testing.T) {
843843
}
844844

845845
func TestDelimitedPatternAllowTrailing(t *testing.T) {
846-
parser := DelimitedPattern(Char('#'), Term("abc"), Char(','), Char('!'), true)
846+
parser := DelimitedPattern(charHash, Term("abc"), charComma, Char('!'), true)
847847

848848
tests := map[string]struct {
849849
input string
@@ -1245,7 +1245,7 @@ func TestOptional(t *testing.T) {
12451245
}
12461246

12471247
func TestNumber(t *testing.T) {
1248-
p := Number()
1248+
p := Number
12491249

12501250
tests := map[string]struct {
12511251
input string
@@ -1299,7 +1299,7 @@ func TestNumber(t *testing.T) {
12991299
}
13001300

13011301
func TestBoolean(t *testing.T) {
1302-
p := Boolean()
1302+
p := Boolean
13031303

13041304
tests := map[string]struct {
13051305
input string
@@ -1348,7 +1348,7 @@ func TestBoolean(t *testing.T) {
13481348
}
13491349

13501350
func TestQuotedString(t *testing.T) {
1351-
str := QuotedString()
1351+
str := QuotedString
13521352

13531353
tests := map[string]struct {
13541354
input string
@@ -1402,7 +1402,7 @@ func TestQuotedString(t *testing.T) {
14021402
}
14031403

14041404
func TestQuotedMultilineString(t *testing.T) {
1405-
str := TripleQuoteString()
1405+
str := TripleQuoteString
14061406

14071407
tests := map[string]struct {
14081408
input string
@@ -1657,7 +1657,7 @@ func TestObject(t *testing.T) {
16571657
}
16581658

16591659
func TestSpacesAndTabs(t *testing.T) {
1660-
inSet := SpacesAndTabs()
1660+
inSet := SpacesAndTabs
16611661

16621662
tests := map[string]struct {
16631663
input string
@@ -1706,7 +1706,7 @@ func TestSpacesAndTabs(t *testing.T) {
17061706
}
17071707

17081708
func TestNewline(t *testing.T) {
1709-
inSet := Newline()
1709+
inSet := Newline
17101710

17111711
tests := map[string]struct {
17121712
input string

internal/bloblang/parser/dot_env_parser.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,28 @@ import (
44
"fmt"
55
)
66

7-
func dotEnvParser() Func {
7+
var dotEnvParser = func() Func {
88
assignmentParser := Sequence(
99
NotInSet('=', ' ', '\n', '#'),
10-
Optional(SpacesAndTabs()),
11-
Char('='),
12-
Optional(SpacesAndTabs()),
13-
Optional(OneOf(TripleQuoteString(), QuotedString(), NotInSet('#', ' ', '\n'))),
14-
Optional(SpacesAndTabs()),
10+
Optional(SpacesAndTabs),
11+
charEquals,
12+
Optional(SpacesAndTabs),
13+
Optional(OneOf(TripleQuoteString, QuotedString, NotInSet('#', ' ', '\n'))),
14+
Optional(SpacesAndTabs),
1515
)
1616

1717
envFileParser := Delimited(
1818
Expect(OneOf(
1919
assignmentParser,
20-
SpacesAndTabs(),
21-
EmptyLine(),
22-
EndOfInput(),
20+
SpacesAndTabs,
21+
EmptyLine,
22+
EndOfInput,
2323
Sequence(
24-
Char('#'),
24+
charHash,
2525
Optional(UntilFail(NotChar('\n'))),
2626
),
2727
), "Environment variable assignment"),
28-
NewlineAllowComment(),
28+
NewlineAllowComment,
2929
)
3030

3131
return func(input []rune) Result {
@@ -45,13 +45,13 @@ func dotEnvParser() Func {
4545
res.Payload = vars
4646
return res
4747
}
48-
}
48+
}()
4949

5050
// ParseDotEnvFile attempts to parse a .env file containing environment variable
5151
// assignments, and returns either a map of key/value assignments or an error.
5252
func ParseDotEnvFile(envFileBytes []byte) (map[string]string, error) {
5353
input := string(envFileBytes)
54-
res := dotEnvParser()([]rune(input))
54+
res := dotEnvParser([]rune(input))
5555
if res.Err != nil {
5656
line, _ := LineAndColOf([]rune(input), res.Err.Input)
5757
return nil, fmt.Errorf("%v: %v", line, res.Err.ErrorAtPositionStructured("", []rune(input)))

internal/bloblang/parser/dot_env_parser_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
)
99

1010
func TestParseDotEnv(t *testing.T) {
11-
parser := dotEnvParser()
11+
parser := dotEnvParser
1212

1313
tests := map[string]struct {
1414
input string

internal/bloblang/parser/field_parser.go

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,18 @@ func intoStaticResolver(p Func) Func {
1515
}
1616
}
1717

18+
var interpStart = Term("${!")
19+
1820
func aFunction(pCtx Context) Func {
21+
pattern := Sequence(
22+
interpStart,
23+
Optional(SpacesAndTabs),
24+
MustBe(queryParser(pCtx)),
25+
Optional(SpacesAndTabs),
26+
MustBe(Expect(charSquigClose, "end of expression")),
27+
)
1928
return func(input []rune) Result {
20-
res := Sequence(
21-
Term("${!"),
22-
Optional(SpacesAndTabs()),
23-
MustBe(queryParser(pCtx)),
24-
Optional(SpacesAndTabs()),
25-
MustBe(Expect(Char('}'), "end of expression")),
26-
)(input)
27-
29+
res := pattern(input)
2830
if res.Err != nil {
2931
return res
3032
}
@@ -33,18 +35,25 @@ func aFunction(pCtx Context) Func {
3335
}
3436
}
3537

36-
func escapedBlock(input []rune) Result {
37-
res := Sequence(
38-
Term("${{!"),
39-
MustBe(Expect(UntilTerm("}}"), "end of escaped expression")),
40-
Term("}}"),
41-
)(input)
42-
if res.Err != nil {
38+
var interpEscapedStart = Term("${{!")
39+
var interpEscapedEnd = Term("}}")
40+
var untilInterpEscapedEnd = UntilTerm("}}")
41+
42+
var escapedBlock = func() Func {
43+
pattern := Sequence(
44+
interpEscapedStart,
45+
MustBe(Expect(untilInterpEscapedEnd, "end of escaped expression")),
46+
interpEscapedEnd,
47+
)
48+
return func(input []rune) Result {
49+
res := pattern(input)
50+
if res.Err != nil {
51+
return res
52+
}
53+
res.Payload = field.StaticResolver("${!" + res.Payload.([]any)[1].(string) + "}")
4354
return res
4455
}
45-
res.Payload = field.StaticResolver("${!" + res.Payload.([]any)[1].(string) + "}")
46-
return res
47-
}
56+
}()
4857

4958
//------------------------------------------------------------------------------
5059

@@ -54,7 +63,7 @@ func parseFieldResolvers(pCtx Context, expr string) ([]field.Resolver, *Error) {
5463
p := OneOf(
5564
escapedBlock,
5665
aFunction(pCtx),
57-
intoStaticResolver(Char('$')),
66+
intoStaticResolver(charDollar),
5867
intoStaticResolver(NotChar('$')),
5968
)
6069

0 commit comments

Comments
 (0)