76 lines
2.3 KiB
Go
76 lines
2.3 KiB
Go
package parsekit
|
|
|
|
// 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
|
|
// a route action, which is basically a simple way of aliasing a chain
|
|
// like p.On(...).Stay().RouteTo(...) into p.On(...).RouteTo(...).
|
|
type MatchAction struct {
|
|
RouteAction
|
|
ChainAction
|
|
runes []rune
|
|
widths []int
|
|
}
|
|
|
|
// 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.
|
|
// When no match was found, then no action is taken.
|
|
// It returns a RouteAction struct, which provides methods that can be used
|
|
// to tell the parser what state to go to next.
|
|
func (a *MatchAction) Accept() *RouteAction {
|
|
if a.ok {
|
|
for i, r := range a.runes {
|
|
a.p.buffer.writeRune(r)
|
|
a.p.advanceCursor(r, a.widths[i])
|
|
}
|
|
}
|
|
return &RouteAction{ChainAction: ChainAction{a.p, a.ok}}
|
|
}
|
|
|
|
// Skip tells the parser to move the cursor past a match that was found,
|
|
// without storing the actual match in the string buffer.
|
|
// Returns true in case a match was found.
|
|
// When no match was found, then no action is taken and false is returned.
|
|
func (a *MatchAction) Skip() *RouteAction {
|
|
if a.ok {
|
|
for i, r := range a.runes {
|
|
type C struct {
|
|
Rune MatchRune
|
|
}
|
|
|
|
a.p.advanceCursor(r, a.widths[i])
|
|
}
|
|
}
|
|
return &RouteAction{ChainAction: ChainAction{a.p, a.ok}}
|
|
}
|
|
|
|
// Stay tells the parser to not move the cursor after finding a match.
|
|
// Returns true in case a match was found, false otherwise.
|
|
func (a *MatchAction) Stay() *RouteAction {
|
|
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.
|
|
// While doing so, it keeps tracks of newlines, so we can report on
|
|
// row + column positions on error.
|
|
func (p *P) advanceCursor(r rune, w int) {
|
|
p.pos += w
|
|
if p.newline {
|
|
p.cursorLine++
|
|
p.cursorColumn = 1
|
|
} else {
|
|
p.cursorColumn++
|
|
}
|
|
p.newline = r == '\n'
|
|
}
|