go-parsekit/parser.go

53 lines
2.1 KiB
Go

package parsekit
// Parser is the top-level struct that holds the configuration for a parser.
// The Parser can be instantiated using the parsekit.NewParser() method.
type Parser struct {
startHandler ParseHandler // the function that handles the very first state
}
// ParseHandler defines the type of function that must be implemented to handle
// a parsing state in a Parser state machine.
//
// A ParseHandler function gets a ParseAPI struct as its input. This struct holds
// all the internal state for the parsing state machine and provides the
// interface that the ParseHandler uses to interact with the parser.
type ParseHandler func(*ParseAPI)
// NewParser instantiates a new Parser.
//
// The Parser is a state machine-style recursive descent parser, in which
// ParseHandler functions are used to move the state machine forward during
// parsing. This style of parser is typically used for parsing programming
// languages and structured data formats (like json, xml, toml, etc.)
//
// The startHandler argument points the Parser to the ParseHandler function
// that must be executed at the start of the parsing process.
//
// To parse input data, use the method Parser.Execute().
func NewParser(startHandler ParseHandler) *Parser {
if startHandler == nil {
callerPanic(1, "parsekit.NewParser(): NewParser() called with nil input at {caller}")
}
return &Parser{startHandler: startHandler}
}
// Execute starts the parser for the provided input.
// For an overview of allowed inputs, take a look at the documentation for parsekit.reader.New().
//
// When an error occurs during parsing, then this error is returned, nil otherwise.
func (p *Parser) Execute(input interface{}) *Error {
api := &ParseAPI{
tokenAPI: NewTokenAPI(input),
loopCheck: map[string]bool{},
}
if api.Handle(p.startHandler) {
// Handle returned true, indicating that parsing could still continue.
// There was no error and that the parsing has not actively been Stop()-ed.
// Let's assume that we actually reached the end of the parsing successfully
// and try to make the best of it.
api.ExpectEndOfFile()
}
return api.err
}