package parsekit import "fmt" // Handle is used to execute other ParseHandler functions from within your // ParseHandler function. // // The boolean return value is true when the parser can still continue. // It will be false when either an error was set (using ParseAPI.Error()), // or the parser was stopped (using ParseAPI.Stop()). func (p *ParseAPI) Handle(parseHandler ParseHandler) bool { p.panicWhenStoppedOrInError() parseHandler(p) return !p.isStoppedOrInError() } // Expects is used to let a ParseHandler function describe what input it is // expecting. This expectation is used in error messages to provide some // context to them. // // When defining an expectation inside a ParseHandler, you do not need to // handle unexpected input yourself. When the end of the parser is reached // without stopping it using ParseAPI.Stop() or ParseAPI.ExpectEndOfFile(), // an automatic error will be emitted using ParseAPI.UnexpectedInput(). func (p *ParseAPI) Expects(description string) { p.panicWhenStoppedOrInError() p.expecting = description } // Stop is used by the parser impementation to tell the API that it has // completed the parsing process successfully. // // When the parser implementation returns without stopping first, the // Parser.Execute() will assume that something went wrong and calls // ParserAPI.UnexpectedInput() to report an error about this. // // The parser implementation can define what was being expected, by // providing a description to ParseAPI.Expecting(). func (p *ParseAPI) Stop() { p.stopped = true } // ExpectEndOfFile can be used to check if the input is at end of file. // Intended use: // // When it finds that the end of the file was indeed reached, then the // parser will be stopped through ParseAPI.Stop(). Otherwise unexpected // input is reported through ParseAPI.UnexpectedInput() with "end of file" // as the expectation. func (p *ParseAPI) ExpectEndOfFile() { p.panicWhenStoppedOrInError() if p.On(A.EndOfFile).Stay() { p.Stop() } else { p.Expects("end of file") p.UnexpectedInput() } } // UnexpectedInput is used to set an error that tells the user that some // unexpected input was encountered. // // It can automatically produce an error message for a couple of situations: // 1) input simply didn't match the expectation // 2) the end of the input was reached // 3) there was an invalid UTF8 character on the input. // // The parser implementation can provide some feedback for this error by // calling ParseAPI.Expects() to set the expectation. When set, the // expectation is included in the error message. func (p *ParseAPI) UnexpectedInput() { p.panicWhenStoppedOrInError() r, _, ok := p.peek(0) switch { case ok: p.Error("unexpected character %q%s", r, fmtExpects(p)) case r == eofRune: p.Error("unexpected end of file%s", fmtExpects(p)) case r == invalidRune: p.Error("invalid UTF8 character in input%s", fmtExpects(p)) } } func fmtExpects(p *ParseAPI) string { if p.expecting == "" { return "" } return fmt.Sprintf(" (expected %s)", p.expecting) }