Skip to content

Commit

Permalink
Added some missing parser symbols to the execution
Browse files Browse the repository at this point in the history
logic.  Do not parse HTML files if it does not contain
a doctype declaration.  Made the error messages slightly
more readable.
  • Loading branch information
ChrisTrenkamp committed Aug 21, 2023
1 parent 826e2e1 commit 3106fa5
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 25 deletions.
3 changes: 3 additions & 0 deletions exec/contextfn_paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ func init() {
contextFunctions[symbols.NT_NameTestQNameLocalOnly] = execNameTestQNameLocalOnly
contextFunctions[symbols.NT_NameTestQNameLocalOnlyReservedNameConflict] = execNameTestQNameLocalOnly
contextFunctions[symbols.NT_StepWithAxisAndNodeTest] = leftRightDependentResult
contextFunctions[symbols.NT_StepWithAxisAndNodeTestAndPredicate] = leftRightDependentResult
contextFunctions[symbols.NT_StepWithPredicateWithAnotherPredicate] = leftRightDependentResult
contextFunctions[symbols.NT_FilterExprWithPredicate] = leftRightDependentResult
contextFunctions[symbols.NT_AxisName] = execAxisName
contextFunctions[symbols.NT_AbbreviatedStepParent] = execAbbreviatedStepParent
contextFunctions[symbols.NT_AbbreviatedAxisSpecifier] = execAbbreviatedAxisSpecifier
Expand Down
54 changes: 29 additions & 25 deletions grammar/grammar.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package grammar
import (
"bytes"
"fmt"
"strings"

"github.com/ChrisTrenkamp/xsel/grammar/lexer"
"github.com/ChrisTrenkamp/xsel/grammar/parser"
Expand All @@ -30,16 +29,42 @@ func (g *Grammar) GetStringExtents(left, right int) string {
return g.lex.GetString(left, right-1)
}

type errPos struct {
line, col int
}

// Creates an XPath query.
func Build(xpath string) (Grammar, error) {
lex := lexer.New([]rune(xpath))
parse, err := parser.Parse(lex)

if err != nil {
errBuf := bytes.Buffer{}
if len(err) > 0 {
errorPositions := make(map[errPos][]parser.Error)

for _, e := range err {
printError(&errBuf, e)
pos := errPos{line: e.Line, col: e.Column}
errorPositions[pos] = append(errorPositions[pos], *e)
}

errBuf := bytes.Buffer{}

for k, v := range errorPositions {
errBuf.WriteString(fmt.Sprintf("Error on line %d, column %d. ", k.line, k.col))
errBuf.WriteString("Expected one of: ")
expected := make(map[string]bool)

for _, e := range v {
for _, i := range e.Expected {
expected[i] = true
}
}

for i := range expected {
errBuf.WriteString(i)
errBuf.WriteString(" ")
}

errBuf.WriteString("\n")
}

return Grammar{}, fmt.Errorf(errBuf.String())
Expand All @@ -64,24 +89,3 @@ func MustBuild(xpath string) Grammar {

return grammar
}

func printError(buf *bytes.Buffer, err *parser.Error) {
if strings.HasPrefix(err.Token.Type().String(), "T_") {
// This error message isn't useful
return
}

buf.WriteString(fmt.Sprintf("Error on column %d, ", err.Column))
buf.WriteString(fmt.Sprintf("on token type '%s' - ", err.Slot.Index().NT))
buf.WriteString(fmt.Sprintf("received %s - ", err.Token.Type()))
buf.WriteString("Expected: ")

expected := make([]string, 0, len(err.Expected))

for _, i := range err.Expected {
expected = append(expected, i)
}

buf.WriteString(strings.Join(expected, ", "))
buf.WriteString("\n")
}
5 changes: 5 additions & 0 deletions parser/html.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ func (x *htmlParser) Pull() (node.Node, bool, error) {
return nil, false, fmt.Errorf("encountered raw node")
case html.DocumentNode:
x.node = x.node.FirstChild

if x.node.Type != html.DoctypeNode {
return nil, false, fmt.Errorf("doctype declaration not found")
}

return x.Pull()
case html.DoctypeNode:
x.node = x.node.NextSibling
Expand Down

0 comments on commit 3106fa5

Please sign in to comment.