Skip to content

Commit

Permalink
feat: support additional repetition options (#60)
Browse files Browse the repository at this point in the history
support additional repetition options
  • Loading branch information
ryzheboka authored Dec 8, 2022
1 parent fcd5dc5 commit b80fbe5
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 2 deletions.
5 changes: 5 additions & 0 deletions _docs/library.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,15 @@ Helpers that specify how to repeat characters. They can be called on character c

```golang
RepetableClassToken.Repeat().OneOrMore() // `+`
RepetableClassToken.Repeat().OneOrMorePreferFewer() // `+?`
RepetableClassToken.ZeroOrMore() // `*`
RepetableClassToken.ZeroOrMorePreferFewer() // `*?`
RepetableClassToken.ZeroOrOne() // `?`
RepetableClassToken.ZeroOrOnePreferZero() // `??`
RepetableClassToken.EqualOrMoreThan(n int) // `{n,}`
RepetableClassToken.EqualOrMoreThanPreferFewer(n int) // `{n,}?`
RepetableClassToken.Between(n, m int) // `{n,m}`
RepetableClassToken.BetweenPreferFewer(n, m int) // `{n,m}?`

// Example:
rex.Chars.Digits().Repeat().OneOrMore() // [0-9]+
Expand Down
39 changes: 38 additions & 1 deletion pkg/dialect/base/repetitions.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,41 @@ func (r Repetition) OneOrMore() dialect.Token {
return r.withSuffix("+")
}

// OneOrMorePreferFewer repeats one or more, prefer fewer chars.
//
// Regex: `+?`.
func (r Repetition) OneOrMorePreferFewer() dialect.Token {
return r.withSuffix("+?")
}

// ZeroOrMore repeats zero or more, prefer more chars.
//
// Regex: `*`.
func (r Repetition) ZeroOrMore() dialect.Token {
return r.withSuffix("*")
}

// ZeroOrMore repeats zero or one x, prefer one.
// ZeroOrMorePreferFewer repeats zero or more, prefer fewer chars.
//
// Regex: `*?`.
func (r Repetition) ZeroOrMorePreferFewer() dialect.Token {
return r.withSuffix("*?")
}

// ZeroOrOne repeats zero or one x, prefer one.
//
// Regex: `?`.
func (r Repetition) ZeroOrOne() dialect.Token {
return r.withSuffix("?")
}

// ZeroOrOnePreferZero repeats zero or one x, prefer zero.
//
// Regex: `??`.
func (r Repetition) ZeroOrOnePreferZero() dialect.Token {
return r.withSuffix("??")
}

// Exactly n times. It doesn't validate an input.
//
// Regex: `{n}`.
Expand All @@ -77,10 +98,26 @@ func (r Repetition) EqualOrMoreThan(n int) dialect.Token {
return r.withSuffix(fmt.Sprintf("{%d,}", n))
}

// EqualOrMoreThanPreferFewer repeats i or i+1 or ... or n, prefer fewer.
// It doesn't validate an input.
//
// Regex: `{n,}?`.
func (r Repetition) EqualOrMoreThanPreferFewer(n int) dialect.Token {
return r.withSuffix(fmt.Sprintf("{%d,}?", n))
}

// Between repeats i=from or i+1 or ... or to, prefer more.
// It doesn't validate an input.
//
// Regex: `{from,to}`.
func (r Repetition) Between(from, to int) dialect.Token {
return r.withSuffix(fmt.Sprintf("{%d,%d}", from, to))
}

// BetweenPreferFewer repeats i=from or i+1 or ... or to, prefer fewer.
// It doesn't validate an input.
//
// Regex: `{from,to}?`.
func (r Repetition) BetweenPreferFewer(from, to int) dialect.Token {
return r.withSuffix(fmt.Sprintf("{%d,%d}?", from, to))
}
27 changes: 26 additions & 1 deletion pkg/dialect/base/repetitions_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// nolint: funlen // Unit tests.
package base_test

import (
Expand All @@ -20,22 +21,42 @@ func TestRexClassRepetitions(t *testing.T) {
Name: "Between",
Chain: []dialect.Token{getABClass().Between(0, 1)},
Expected: `[ab]{0,1}`,
}, {
Name: "BetweenPreferFewer",
Chain: []dialect.Token{getABClass().BetweenPreferFewer(0, 1)},
Expected: `[ab]{0,1}?`,
}, {
Name: "EqualOrMoreThan",
Chain: []dialect.Token{getABClass().EqualOrMoreThan(5)},
Expected: `[ab]{5,}`,
}, {
Name: "EqualOrMoreThanPreferFewer",
Chain: []dialect.Token{getABClass().EqualOrMoreThanPreferFewer(5)},
Expected: `[ab]{5,}?`,
}, {
Name: "OneOrMore",
Chain: []dialect.Token{getABClass().OneOrMore()},
Expected: `[ab]+`,
}, {
Name: "OneOrMore",
Name: "OneOrMorePreferFewer",
Chain: []dialect.Token{getABClass().OneOrMorePreferFewer()},
Expected: `[ab]+?`,
}, {
Name: "ZeroOrMore",
Chain: []dialect.Token{getABClass().ZeroOrMore()},
Expected: `[ab]*`,
}, {
Name: "ZeroOrMorePreferFewer",
Chain: []dialect.Token{getABClass().ZeroOrMorePreferFewer()},
Expected: `[ab]*?`,
}, {
Name: "ZeroOrOne",
Chain: []dialect.Token{getABClass().ZeroOrOne()},
Expected: `[ab]?`,
}, {
Name: "ZeroOrOnePreferZero",
Chain: []dialect.Token{getABClass().ZeroOrOnePreferZero()},
Expected: `[ab]??`,
}, {
Name: "AnyOneOrMore",
Chain: []dialect.Token{base.Chars.Any().Repeat().OneOrMore()},
Expand All @@ -44,6 +65,10 @@ func TestRexClassRepetitions(t *testing.T) {
Name: "RangeOneOrMore",
Chain: []dialect.Token{base.Chars.Range('0', '9').Repeat().OneOrMore()},
Expected: `[0-9]+`,
}, {
Name: "RangeOneOrMorePreferFewer",
Chain: []dialect.Token{base.Chars.Range('0', '9').Repeat().OneOrMorePreferFewer()},
Expected: `[0-9]+?`,
}, {
Name: "Exactly",
Chain: []dialect.Token{base.Chars.Range('0', '9').Repeat().Exactly(2)},
Expand Down

0 comments on commit b80fbe5

Please sign in to comment.