Skip to content

Commit

Permalink
Add support for hex concats.
Browse files Browse the repository at this point in the history
  • Loading branch information
q-uint committed Feb 21, 2024
1 parent 4ab1d18 commit 4e56783
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 6 deletions.
23 changes: 17 additions & 6 deletions abnf/gen/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,13 +282,24 @@ func (g *Generator) toGo(v any, references []string) string {
case *ir.NumVal:
switch []rune(*v)[0] {
case 'x':
s := strings.Split(strings.TrimPrefix(string(*v), "x"), "-")
switch len(s) {
case 1:
return fmt.Sprintf("rune(0x%s)", s[0])
case 2:
return fmt.Sprintf("op.RuneRange{Min: 0x%s, Max: 0x%s}", s[0], s[1])
x := strings.TrimPrefix(string(*v), "x")
if strings.Contains(x, "-") {
s := strings.Split(x, "-")
switch len(s) {
case 2:
return fmt.Sprintf("op.RuneRange{Min: 0x%s, Max: 0x%s}", s[0], s[1])
default:
panic(fmt.Errorf("invalid range %s", *v))
}
}
if strings.Contains(x, ".") {
var xs []string
for _, x := range strings.Split(x, ".") {
xs = append(xs, fmt.Sprintf("rune(0x%s)", x))
}
return fmt.Sprintf("op.And{%s}", strings.Join(xs, ", "))
}
return fmt.Sprintf("rune(0x%s)", x)
}
panic(fmt.Errorf("invalid range %s", *v))
case *ir.CharVal:
Expand Down
19 changes: 19 additions & 0 deletions abnf/gen/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,22 @@ func Example_externalDependencies() {
// Grammar = op.Capture{Name: "Grammar", Value: op.And{a.Alpha, an.AlphaNum, hd.HEXDIG}}
// )
}

func ExampleGenerator_hexConcat() {
g := gen.Generator{
PackageName: "hexc",
}
raw, _ := g.GenerateOperators([]rune("grammar = %x74.72.75.65\n"))
fmt.Println(raw)
// Output:
// // Package hexc is autogenerated by https://github.com/0x51-dev/upeg. DO NOT EDIT.
// package hexc
//
// import (
// "github.com/0x51-dev/upeg/parser/op"
// )
//
// var (
// Grammar = op.Capture{Name: "Grammar", Value: op.And{rune(0x74), rune(0x72), rune(0x75), rune(0x65)}}
// )
}
37 changes: 37 additions & 0 deletions benchmarks_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package upeg

import (
"github.com/0x51-dev/upeg/parser"
"github.com/0x51-dev/upeg/parser/op"
"strings"
"testing"
)

func BenchmarkRepeat(b *testing.B) {
in := strings.Repeat("a;", 1000)
p, err := parser.New([]rune(in[:len(in)-1]))
if err != nil {
b.Fatal(err)
}
b.Run("ZeroOrMore", func(b *testing.B) {
for i := 0; i < b.N; i++ {
if _, err := p.Parse(op.And{'a', op.ZeroOrMore{Value: op.And{';', 'a'}}, op.EOF{}}); err != nil {
b.Fatal(err)
}
p.Reset()
}
})
b.Run("Or", func(b *testing.B) {
as := op.Or{
op.And{'a', ';', op.Reference{Name: "as"}},
'a',
}
p.Rules["as"] = as
for i := 0; i < b.N; i++ {
if _, err := p.Parse(op.And{as, op.EOF{}}); err != nil {
b.Fatal(err)
}
p.Reset()
}
})
}

0 comments on commit 4e56783

Please sign in to comment.