package treerack import ( "bufio" "errors" "fmt" "io" ) // CommitType controls how the output of a named parser is handled and represented in the resulting AST. type CommitType int const ( // None indicates the default behavior: parsed segments are represented as named nodes in the AST. // Whitespace handling inherits the syntax's global settings. None CommitType = 0 // Alias treats the parser as a pass-through. Validated segments are included in the AST node of the // enclosing parser rather than creating a distinct node. Alias CommitType = 1 << iota // Whitespace designates a parser (typically a character sequence) to be treated as ignored whitespace // throughout the input. Whitespace // NoWhitespace prevents the automatic skipping of defined whitespace characters within specific sequences. NoWhitespace // Keyword marks a sequence as a reserved keyword. This allows specific sequences to be protected or // restricted in certain contexts via the NoKeyword flag. Keyword // NoKeyword prevents the parser from matching sequences marked as Keywords. NoKeyword // FailPass configures the parser to propagate failure up to the enclosing parser rather than handling it // locally. FailPass // Root explicitly marks the parser as the root of the syntax. By default, the last defined parser is // considered the root. Root userDefined ) type formatFlags int const ( formatNone formatFlags = 0 formatPretty formatFlags = 1 << iota formatIncludeComments ) // ParseError reports a failure to match the input text against the defined syntax. type ParseError struct { // Input denotes the name of the input source (e.g., filename), or "" if unavailable. Input string // Offset is the index of the right-most token where the parse failed. Offset int // Line is the zero-based line number of the failure position. // // For display purposes, increment by one. Line int // Column is the zero-based column index of the failure position. Column int // Definition identifies the name of the specific parser definition where the match failed. Definition string } type parser interface { nodeName() string nodeID() int commitType() CommitType parse(*context) } type builder interface { nodeName() string nodeID() int build(*context) ([]*Node, bool) } // ErrInvalidUnicodeCharacter indicates that the input content contains invalid UTF-8 sequences. var ErrInvalidUnicodeCharacter = errors.New("invalid unicode character") // Error returns the formatted failure message. func (pe *ParseError) Error() string { return fmt.Sprintf( "%s:%d:%d:parse failed, parsing: %s", pe.Input, pe.Line+1, pe.Column+1, pe.Definition, ) } func parseInput(r io.Reader, p parser, b builder, kw []parser) (*Node, error) { c := newContext(bufio.NewReader(r), kw) p.parse(c) if c.readErr != nil { return nil, c.readErr } if err := c.finalizeParse(p); err != nil { if perr, ok := err.(*ParseError); ok { perr.Input = "" } return nil, err } c.offset = 0 c.results.resetPending() n, _ := b.build(c) return n[0], nil }