65 lines
1.9 KiB
Go
65 lines
1.9 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
|
|
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}}
|
|
}
|
|
|
|
// 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'
|
|
}
|