136 lines
3.9 KiB
Go
136 lines
3.9 KiB
Go
package parsekit
|
|
|
|
// Handle is used to execute other ParseHandler functions from within your
|
|
// ParseHandler function.
|
|
func (p *ParseAPI) Handle(handlers ...ParseHandler) {
|
|
for _, handler := range handlers {
|
|
// When some previous parsing step yielded an error, skip this operation.
|
|
if p.err != nil || p.stopped {
|
|
break
|
|
}
|
|
handler(p)
|
|
}
|
|
}
|
|
|
|
// RouteTo tells the parser what ParseHandler function to invoke on
|
|
// the next parse cycle.
|
|
// Deprecated
|
|
func (p *ParseAPI) RouteTo(handler ParseHandler) *RouteFollowupAction {
|
|
p.nextState = handler
|
|
return &RouteFollowupAction{p}
|
|
}
|
|
|
|
// RouteRepeat tells the parser that on the next parsing cycle, the current
|
|
// ParseHandler must be reinvoked.
|
|
// Deprecated
|
|
func (p *ParseAPI) RouteRepeat() {
|
|
p.RouteTo(p.state)
|
|
}
|
|
|
|
// RouteReturn tells the parser that on the next cycle the last ParseHandler
|
|
// that was pushed on the route stack must be invoked.
|
|
//
|
|
// Using this method is optional. When implementating a ParseHandler that
|
|
// is used as a sort of subroutine (using constructions like
|
|
// p.RouteTo(subroutine).ThenReturnHere()), you can refrain from
|
|
// providing an explicit routing decision from that handler. The parser will
|
|
// automatically assume a RouteReturn() in that case.
|
|
// Deprecated
|
|
func (p *ParseAPI) RouteReturn() {
|
|
p.nextState = p.popRoute()
|
|
}
|
|
|
|
// RouteFollowupAction chains parsing routes.
|
|
// It allows for routing code like p.RouteTo(handlerA).ThenTo(handlerB).
|
|
// Deprecated
|
|
type RouteFollowupAction struct {
|
|
p *ParseAPI
|
|
}
|
|
|
|
// ThenTo schedules a ParseHandler that must be invoked after the RouteTo
|
|
// ParseHandler has been completed.
|
|
// For example:
|
|
//
|
|
// p.RouteTo(handlerA).ThenTo(handlerB)
|
|
// Deprecated
|
|
func (a *RouteFollowupAction) ThenTo(state ParseHandler) {
|
|
a.p.pushRoute(state)
|
|
}
|
|
|
|
// ThenReturnHere schedules the current ParseHandler to be invoked after
|
|
// the RouteTo ParseHandler has been completed.
|
|
// For example:
|
|
//
|
|
// p.RouteTo(handlerA).ThenReturnHere()
|
|
// Deprecated
|
|
func (a *RouteFollowupAction) ThenReturnHere() {
|
|
a.p.pushRoute(a.p.state)
|
|
}
|
|
|
|
// pushRoute adds the ParseHandler to the route stack.
|
|
// This is used for implementing nested parsing.
|
|
// Deprecated
|
|
func (p *ParseAPI) pushRoute(state ParseHandler) {
|
|
p.routeStack = append(p.routeStack, state)
|
|
}
|
|
|
|
// popRoute pops the last pushed ParseHandler from the route stack.
|
|
// Deprecated
|
|
func (p *ParseAPI) popRoute() ParseHandler {
|
|
last := len(p.routeStack) - 1
|
|
head, tail := p.routeStack[:last], p.routeStack[last]
|
|
p.routeStack = head
|
|
return tail
|
|
}
|
|
|
|
// ExpectEndOfFile can be used to check if the input is at end of file.
|
|
// Intended use:
|
|
//
|
|
// func yourParseHandler(p *parsekit.ParseAPI) {
|
|
// ...
|
|
// p.ExpectEndOfFile()
|
|
// }
|
|
//
|
|
// This will execute the end of file test right away. If you want to
|
|
// use the end of file check as a StateHandler instead, you can also
|
|
// make use of another form, for example:
|
|
//
|
|
// func yourParseHandler(p *parsekit.ParseAPI) {
|
|
// p.RouteTo(yourHandler).ThenTo(parsekit.ExpectEndOfFile)
|
|
// }
|
|
func (p *ParseAPI) ExpectEndOfFile() {
|
|
// When some previous parsing step yielded an error, skip this operation.
|
|
if p.err != nil || p.stopped {
|
|
return
|
|
}
|
|
if p.On(A.EndOfFile).Stay() {
|
|
p.Stop()
|
|
} else {
|
|
p.Expects("end of file")
|
|
p.UnexpectedInput()
|
|
}
|
|
}
|
|
|
|
// ExpectEndOfFile can be scheduled as a ParseHandler function.
|
|
// It makes sure that the input is at the end of file.
|
|
// Intended use:
|
|
//
|
|
// func yourParseHandler(p *parsekit.ParseAPI) {
|
|
// ...
|
|
// p.RouteTo(parsekit.ExpectEndOfFile)
|
|
// }
|
|
//
|
|
// It is not mandatory to use this ParseHandler. You can take care fo EOF
|
|
// yourself too. Simply emit an ItemEOF when the end of the input was reached
|
|
// to stop the parser loop:
|
|
//
|
|
// p.Stop()
|
|
// TODO meh, get rid of this one, once we don't use state scheduling anymore.
|
|
// Deprecated
|
|
func ExpectEndOfFile(p *ParseAPI) {
|
|
p.Expects("end of file")
|
|
if p.On(A.EndOfFile).Stay() {
|
|
p.Stop()
|
|
}
|
|
}
|