Some changes to see how they reflect in godoc.

This commit is contained in:
Maurice Makaay 2019-05-21 13:23:30 +00:00
parent 9c0b889499
commit a3947feea7
6 changed files with 87 additions and 98 deletions

View File

@ -75,7 +75,7 @@ func (m *MatchDialog) NextRune() (rune, bool) {
} }
// Clear empties out the accumulated runes that are stored // Clear empties out the accumulated runes that are stored
// in the MatchDialog. // in the MatchDialog. The offset is kept as-is.
func (m *MatchDialog) Clear() { func (m *MatchDialog) Clear() {
m.runes = []rune{} m.runes = []rune{}
m.widths = []int{} m.widths = []int{}
@ -90,7 +90,7 @@ type Matcher interface {
Match(*MatchDialog) bool Match(*MatchDialog) bool
} }
type matcherConstructors struct { type MatcherConstructors struct {
EndOfFile func() MatchEndOfFile EndOfFile func() MatchEndOfFile
AnyRune func() MatchAny AnyRune func() MatchAny
Rune func(rune) MatchRune Rune func(rune) MatchRune
@ -117,7 +117,7 @@ type matcherConstructors struct {
// When using C in your own parser, then it is advised to create // When using C in your own parser, then it is advised to create
// an alias in your own package for easy reference: // an alias in your own package for easy reference:
// var c = parsekit.C // var c = parsekit.C
var C = matcherConstructors{ var C = MatcherConstructors{
EndOfFile: func() MatchEndOfFile { EndOfFile: func() MatchEndOfFile {
return MatchEndOfFile{} return MatchEndOfFile{}
}, },
@ -153,41 +153,41 @@ var C = matcherConstructors{
} }
return MatchSequence{m} return MatchSequence{m}
}, },
Optional: func(matcher Matcher) MatchOptional { Optional: func(Matcher Matcher) MatchOptional {
return MatchOptional{matcher} return MatchOptional{Matcher}
}, },
Not: func(matcher Matcher) MatchNot { Not: func(Matcher Matcher) MatchNot {
return MatchNot{matcher} return MatchNot{Matcher}
}, },
AnyOf: func(matchers ...Matcher) MatchAnyOf { AnyOf: func(Matchers ...Matcher) MatchAnyOf {
return MatchAnyOf{matchers} return MatchAnyOf{Matchers}
}, },
Sequence: func(matchers ...Matcher) MatchSequence { Sequence: func(Matchers ...Matcher) MatchSequence {
return MatchSequence{matchers} return MatchSequence{Matchers}
}, },
Repeat: func(count int, matcher Matcher) MatchRepeat { Repeat: func(count int, Matcher Matcher) MatchRepeat {
return MatchRepeat{count, count, matcher} return MatchRepeat{count, count, Matcher}
}, },
Min: func(min int, matcher Matcher) MatchRepeat { Min: func(min int, Matcher Matcher) MatchRepeat {
return MatchRepeat{min, -1, matcher} return MatchRepeat{min, -1, Matcher}
}, },
Max: func(max int, matcher Matcher) MatchRepeat { Max: func(max int, Matcher Matcher) MatchRepeat {
return MatchRepeat{-1, max, matcher} return MatchRepeat{-1, max, Matcher}
}, },
Bounded: func(min int, max int, matcher Matcher) MatchRepeat { Bounded: func(min int, max int, Matcher Matcher) MatchRepeat {
return MatchRepeat{min, max, matcher} return MatchRepeat{min, max, Matcher}
}, },
OneOrMore: func(matcher Matcher) MatchRepeat { OneOrMore: func(Matcher Matcher) MatchRepeat {
return MatchRepeat{1, -1, matcher} return MatchRepeat{1, -1, Matcher}
}, },
ZeroOrMore: func(matcher Matcher) MatchRepeat { ZeroOrMore: func(Matcher Matcher) MatchRepeat {
return MatchRepeat{0, -1, matcher} return MatchRepeat{0, -1, Matcher}
}, },
Separated: func(separator Matcher, matcher Matcher) MatchSeparated { Separated: func(separator Matcher, Matcher Matcher) MatchSeparated {
return MatchSeparated{separator, matcher} return MatchSeparated{separator, Matcher}
}, },
Drop: func(matcher Matcher) MatchDrop { Drop: func(Matcher Matcher) MatchDrop {
return MatchDrop{matcher} return MatchDrop{Matcher}
}, },
} }
@ -206,12 +206,12 @@ func (c MatchAny) Match(m *MatchDialog) bool {
} }
type MatchNot struct { type MatchNot struct {
matcher Matcher Matcher Matcher
} }
func (c MatchNot) Match(m *MatchDialog) bool { func (c MatchNot) Match(m *MatchDialog) bool {
child := m.Fork() child := m.Fork()
if !c.matcher.Match(child) { if !c.Matcher.Match(child) {
child.Merge() child.Merge()
return true return true
} }
@ -219,12 +219,12 @@ func (c MatchNot) Match(m *MatchDialog) bool {
} }
type MatchOptional struct { type MatchOptional struct {
matcher Matcher Matcher Matcher
} }
func (c MatchOptional) Match(m *MatchDialog) bool { func (c MatchOptional) Match(m *MatchDialog) bool {
child := m.Fork() child := m.Fork()
if c.matcher.Match(child) { if c.Matcher.Match(child) {
child.Merge() child.Merge()
} }
return true return true
@ -250,13 +250,13 @@ func (c MatchRuneRange) Match(m *MatchDialog) bool {
} }
type MatchAnyOf struct { type MatchAnyOf struct {
matcher []Matcher Matcher []Matcher
} }
func (c MatchAnyOf) Match(m *MatchDialog) bool { func (c MatchAnyOf) Match(m *MatchDialog) bool {
for _, matcher := range c.matcher { for _, Matcher := range c.Matcher {
child := m.Fork() child := m.Fork()
if matcher.Match(child) { if Matcher.Match(child) {
return child.Merge() return child.Merge()
} }
} }
@ -266,7 +266,7 @@ func (c MatchAnyOf) Match(m *MatchDialog) bool {
type MatchRepeat struct { type MatchRepeat struct {
min int min int
max int max int
matcher Matcher Matcher Matcher
} }
func (c MatchRepeat) Match(m *MatchDialog) bool { func (c MatchRepeat) Match(m *MatchDialog) bool {
@ -278,14 +278,14 @@ func (c MatchRepeat) Match(m *MatchDialog) bool {
// Specified min: check for the minimal required amount of matches. // Specified min: check for the minimal required amount of matches.
for total < c.min { for total < c.min {
total++ total++
if !c.matcher.Match(child) { if !c.Matcher.Match(child) {
return false return false
} }
} }
// No specified max: include the rest of the available matches. // No specified max: include the rest of the available matches.
if c.max < 0 { if c.max < 0 {
child.Merge() child.Merge()
for c.matcher.Match(child) { for c.Matcher.Match(child) {
child.Merge() child.Merge()
} }
return true return true
@ -294,7 +294,7 @@ func (c MatchRepeat) Match(m *MatchDialog) bool {
child.Merge() child.Merge()
for total < c.max { for total < c.max {
total++ total++
if !c.matcher.Match(child) { if !c.Matcher.Match(child) {
break break
} }
child.Merge() child.Merge()
@ -303,13 +303,13 @@ func (c MatchRepeat) Match(m *MatchDialog) bool {
} }
type MatchSequence struct { type MatchSequence struct {
matchers []Matcher Matchers []Matcher
} }
func (c MatchSequence) Match(m *MatchDialog) bool { func (c MatchSequence) Match(m *MatchDialog) bool {
child := m.Fork() child := m.Fork()
for _, matcher := range c.matchers { for _, Matcher := range c.Matchers {
if !matcher.Match(child) { if !Matcher.Match(child) {
return false return false
} }
} }
@ -319,21 +319,21 @@ func (c MatchSequence) Match(m *MatchDialog) bool {
type MatchSeparated struct { type MatchSeparated struct {
separator Matcher separator Matcher
matcher Matcher Matcher Matcher
} }
func (c MatchSeparated) Match(m *MatchDialog) bool { func (c MatchSeparated) Match(m *MatchDialog) bool {
seq := C.Sequence(c.matcher, C.ZeroOrMore(C.Sequence(c.separator, c.matcher))) seq := C.Sequence(c.Matcher, C.ZeroOrMore(C.Sequence(c.separator, c.Matcher)))
return seq.Match(m) return seq.Match(m)
} }
type MatchDrop struct { type MatchDrop struct {
matcher Matcher Matcher Matcher
} }
func (c MatchDrop) Match(m *MatchDialog) bool { func (c MatchDrop) Match(m *MatchDialog) bool {
child := m.Fork() child := m.Fork()
if c.matcher.Match(child) { if c.Matcher.Match(child) {
child.Clear() child.Clear()
child.Merge() child.Merge()
return true return true

View File

@ -10,10 +10,10 @@ var c = p.C
const TestItem p.ItemType = 1 const TestItem p.ItemType = 1
func newParser(input string, matcher p.Matcher) *p.P { func newParser(input string, Matcher p.Matcher) *p.P {
stateFn := func(p *p.P) { stateFn := func(p *p.P) {
p.Expects("MATCH") p.Expects("MATCH")
if p.On(matcher).Accept().End() { if p.On(Matcher).Accept().End() {
p.EmitLiteral(TestItem) p.EmitLiteral(TestItem)
p.RouteRepeat() p.RouteRepeat()
} }

View File

@ -27,9 +27,9 @@ package parsekit
// //
// Here's a complete example chain: // Here's a complete example chain:
// p.On(something).Accept().RouteTo(stateB).ThenTo(stateC).End() // p.On(something).Accept().RouteTo(stateB).ThenTo(stateC).End()
func (p *P) On(matcher Matcher) *MatchAction { func (p *P) On(Matcher Matcher) *matchAction {
m := &MatchDialog{p: p} m := &MatchDialog{p: p}
ok := matcher.Match(m) ok := Matcher.Match(m)
// Keep track of the last match, to allow parser implementations // Keep track of the last match, to allow parser implementations
// to access it in an easy way. Typical use would be something like: // to access it in an easy way. Typical use would be something like:
@ -38,21 +38,21 @@ func (p *P) On(matcher Matcher) *MatchAction {
// } // }
p.LastMatch = string(m.runes) p.LastMatch = string(m.runes)
return &MatchAction{ return &matchAction{
ChainAction: ChainAction{p, ok}, routeAction: routeAction{chainAction{p, ok}},
runes: m.runes, runes: m.runes,
widths: m.widths, widths: m.widths,
} }
} }
// ChainAction is used for building method chains for the On() method. // chainAction is used for building method chains for the On() method.
type ChainAction struct { type chainAction struct {
p *P p *P
ok bool ok bool
} }
// End ends the method chain and returns a boolean indicating whether // End ends the method chain and returns a boolean indicating whether
// or not a match was found in the input. // or not a match was found in the input.
func (a *ChainAction) End() bool { func (a *chainAction) End() bool {
return a.ok return a.ok
} }

View File

@ -1,13 +1,12 @@
package parsekit package parsekit
// MatchAction is a struct that is used for building On()-method chains. // matchAction is a struct that is used for building On()-method chains.
// //
// It embeds the RouteAction struct, to make it possible to go right into // It embeds the routeAction struct, to make it possible to go right into
// a route action, which is basically a simple way of aliasing a chain // a route action, which is basically a simple way of aliasing a chain
// like p.On(...).Stay().RouteTo(...) into p.On(...).RouteTo(...). // like p.On(...).Stay().RouteTo(...) into p.On(...).RouteTo(...).
type MatchAction struct { type matchAction struct {
RouteAction routeAction
ChainAction
runes []rune runes []rune
widths []int widths []int
} }
@ -15,23 +14,23 @@ type MatchAction struct {
// Accept tells the parser to move the cursor past a match that was found, // Accept tells the parser to move the cursor past a match that was found,
// and to store the input that matched in the string buffer. // and to store the input that matched in the string buffer.
// When no match was found, then no action is taken. // When no match was found, then no action is taken.
// It returns a RouteAction struct, which provides methods that can be used // It returns a routeAction struct, which provides methods that can be used
// to tell the parser what state to go to next. // to tell the parser what state to go to next.
func (a *MatchAction) Accept() *RouteAction { func (a *matchAction) Accept() *routeAction {
if a.ok { if a.ok {
for i, r := range a.runes { for i, r := range a.runes {
a.p.buffer.writeRune(r) a.p.buffer.writeRune(r)
a.p.advanceCursor(r, a.widths[i]) a.p.advanceCursor(r, a.widths[i])
} }
} }
return &RouteAction{ChainAction: ChainAction{a.p, a.ok}} return &routeAction{chainAction: chainAction{a.p, a.ok}}
} }
// Skip tells the parser to move the cursor past a match that was found, // Skip tells the parser to move the cursor past a match that was found,
// without storing the actual match in the string buffer. // without storing the actual match in the string buffer.
// Returns true in case a match was found. // Returns true in case a match was found.
// When no match was found, then no action is taken and false is returned. // When no match was found, then no action is taken and false is returned.
func (a *MatchAction) Skip() *RouteAction { func (a *matchAction) Skip() *routeAction {
if a.ok { if a.ok {
for i, r := range a.runes { for i, r := range a.runes {
type C struct { type C struct {
@ -41,23 +40,13 @@ func (a *MatchAction) Skip() *RouteAction {
a.p.advanceCursor(r, a.widths[i]) a.p.advanceCursor(r, a.widths[i])
} }
} }
return &RouteAction{ChainAction: ChainAction{a.p, a.ok}} return &routeAction{chainAction: chainAction{a.p, a.ok}}
} }
// Stay tells the parser to not move the cursor after finding a match. // Stay tells the parser to not move the cursor after finding a match.
// Returns true in case a match was found, false otherwise. // Returns true in case a match was found, false otherwise.
func (a *MatchAction) Stay() *RouteAction { func (a *matchAction) Stay() *routeAction {
return &RouteAction{ChainAction: ChainAction{a.p, a.ok}} return &routeAction{chainAction: chainAction{a.p, a.ok}}
}
// RouteTo is a shortcut for p.On(...).Stay() + p.RouteTo(...).
func (a *MatchAction) RouteTo(state StateHandler) *RouteFollowupAction {
return a.Stay().RouteTo(state)
}
// RouteReturn is a shortcut for p.On(...).Stay() + p.RouteReturn(...).
func (a *MatchAction) RouteReturn() *ChainAction {
return a.Stay().RouteReturn()
} }
// advanceCursor advances the rune cursor one position in the input data. // advanceCursor advances the rune cursor one position in the input data.

View File

@ -1,59 +1,59 @@
package parsekit package parsekit
// RouteAction is a struct that is used for building On() method chains. // routeAction is a struct that is used for building On() method chains.
type RouteAction struct { type routeAction struct {
ChainAction chainAction
} }
// RouteRepeat indicates that on the next parsing cycle, // RouteRepeat indicates that on the next parsing cycle,
// the current StateHandler must be reinvoked. // the current StateHandler must be reinvoked.
func (a *RouteAction) RouteRepeat() *ChainAction { func (a *routeAction) RouteRepeat() *chainAction {
if a.ok { if a.ok {
return a.p.RouteRepeat() return a.p.RouteRepeat()
} }
return &ChainAction{nil, false} return &chainAction{nil, false}
} }
// RouteTo tells the parser what StateHandler function to invoke // RouteTo tells the parser what StateHandler function to invoke
// in the next parsing cycle. // in the next parsing cycle.
func (a *RouteAction) RouteTo(state StateHandler) *RouteFollowupAction { func (a *routeAction) RouteTo(state StateHandler) *routeFollowupAction {
if a.ok { if a.ok {
return a.p.RouteTo(state) return a.p.RouteTo(state)
} }
return &RouteFollowupAction{ChainAction: ChainAction{nil, false}} return &routeFollowupAction{chainAction: chainAction{nil, false}}
} }
// RouteReturn tells the parser that on the next cycle the next scheduled // RouteReturn tells the parser that on the next cycle the next scheduled
// route must be invoked. // route must be invoked.
func (a *RouteAction) RouteReturn() *ChainAction { func (a *routeAction) RouteReturn() *chainAction {
if a.ok { if a.ok {
return a.p.RouteReturn() return a.p.RouteReturn()
} }
return &ChainAction{nil, false} return &chainAction{nil, false}
} }
// RouteFollowupAction chains parsing routes. // routeFollowupAction chains parsing routes.
// It allows for routing code like p.RouteTo(handlerA).ThenTo(handlerB). // It allows for routing code like p.RouteTo(handlerA).ThenTo(handlerB).
type RouteFollowupAction struct { type routeFollowupAction struct {
ChainAction chainAction
} }
// ThenTo schedules a StateHandler that must be invoked after the RouteTo // ThenTo schedules a StateHandler that must be invoked after the RouteTo
// StateHandler has been completed. // StateHandler has been completed.
// For example: p.RouteTo(handlerA).ThenTo(handlerB) // For example: p.RouteTo(handlerA).ThenTo(handlerB)
func (a *RouteFollowupAction) ThenTo(state StateHandler) *ChainAction { func (a *routeFollowupAction) ThenTo(state StateHandler) *chainAction {
if a.ok { if a.ok {
a.p.pushRoute(state) a.p.pushRoute(state)
} }
return &ChainAction{nil, a.ok} return &chainAction{nil, a.ok}
} }
// ThenReturnHere schedules the current StateHandler to be invoked after // ThenReturnHere schedules the current StateHandler to be invoked after
// the RouteTo StateHandler has been completed. // the RouteTo StateHandler has been completed.
// For example: p.RouteTo(handlerA).ThenReturnHere() // For example: p.RouteTo(handlerA).ThenReturnHere()
func (a *RouteFollowupAction) ThenReturnHere() *ChainAction { func (a *routeFollowupAction) ThenReturnHere() *chainAction {
if a.ok { if a.ok {
a.p.pushRoute(a.p.state) a.p.pushRoute(a.p.state)
} }
return &ChainAction{nil, a.ok} return &chainAction{nil, a.ok}
} }

View File

@ -2,16 +2,16 @@ package parsekit
// RouteTo tells the parser what StateHandler function to invoke // RouteTo tells the parser what StateHandler function to invoke
// in the next parsing cycle. // in the next parsing cycle.
func (p *P) RouteTo(state StateHandler) *RouteFollowupAction { func (p *P) RouteTo(state StateHandler) *routeFollowupAction {
p.nextState = state p.nextState = state
return &RouteFollowupAction{ChainAction: ChainAction{p, true}} return &routeFollowupAction{chainAction: chainAction{p, true}}
} }
// RouteRepeat indicates that on the next parsing cycle, the current // RouteRepeat indicates that on the next parsing cycle, the current
// StateHandler must be reinvoked. // StateHandler must be reinvoked.
func (p *P) RouteRepeat() *ChainAction { func (p *P) RouteRepeat() *chainAction {
p.RouteTo(p.state) p.RouteTo(p.state)
return &ChainAction{nil, true} return &chainAction{nil, true}
} }
// RouteReturn tells the parser that on the next cycle the last // RouteReturn tells the parser that on the next cycle the last
@ -22,9 +22,9 @@ func (p *P) RouteRepeat() *ChainAction {
// p.RouteTo(subroutine).ThenReturnHere()), you can refrain from // p.RouteTo(subroutine).ThenReturnHere()), you can refrain from
// providing an explicit routing decision from that handler. The parser will // providing an explicit routing decision from that handler. The parser will
// automatically assume a RouteReturn() in that case. // automatically assume a RouteReturn() in that case.
func (p *P) RouteReturn() *ChainAction { func (p *P) RouteReturn() *chainAction {
p.nextState = p.popRoute() p.nextState = p.popRoute()
return &ChainAction{nil, true} return &chainAction{nil, true}
} }
// pushRoute adds the StateHandler to the route stack. // pushRoute adds the StateHandler to the route stack.