diff --git a/combinator.go b/combinator.go index ae4d31c..f5c06e3 100644 --- a/combinator.go +++ b/combinator.go @@ -18,6 +18,8 @@ func Seq(parsers ...Parserish) Parser { return } } + node.Start = startpos + node.End = ps.Pos }) } @@ -27,7 +29,10 @@ func NoAutoWS(parser Parserish) Parser { return func(ps *State, node *Result) { oldWS := ps.WS ps.WS = NoWhitespace + startpos := ps.Pos parserfied(ps, node) + node.Start = startpos + node.End = ps.Pos ps.WS = oldWS } } @@ -57,6 +62,8 @@ func Any(parsers ...Parserish) Parser { ps.Recover() continue } + node.Start = startpos + node.End = ps.Pos return } @@ -110,6 +117,8 @@ func manyImpl(min int, op Parserish, sep ...Parserish) Parser { } } } + node.Start = startpos + node.End = ps.Pos } } @@ -123,6 +132,8 @@ func Maybe(parser Parserish) Parser { if ps.Errored() && ps.Cut <= startpos { ps.Recover() } + node.Start = startpos + node.End = ps.Pos }) } @@ -133,11 +144,14 @@ func Bind(parser Parserish, val interface{}) Parser { p := Parsify(parser) return func(ps *State, node *Result) { + startpos := ps.Pos p(ps, node) if ps.Errored() { return } node.Result = val + node.Start = startpos + node.End = ps.Pos } } @@ -147,10 +161,13 @@ func Map(parser Parserish, f func(n *Result)) Parser { p := Parsify(parser) return func(ps *State, node *Result) { + startpos := ps.Pos p(ps, node) if ps.Errored() { return } + node.Start = startpos + node.End = ps.Pos f(node) } } diff --git a/literals.go b/literals.go index 260a26e..0e3e89f 100644 --- a/literals.go +++ b/literals.go @@ -59,12 +59,16 @@ func StringLit(allowedQuotes string) Parser { } case quote: if buf == nil { + node.Start = ps.Pos + 1 + node.End = end node.Token = ps.Input[ps.Pos+1 : end] ps.Pos = end + 1 return } - ps.Pos = end + 1 node.Token = buf.String() + node.Start = ps.Pos + node.End = ps.Pos + len(node.Token) + ps.Pos = end + 1 return default: if buf == nil { @@ -139,6 +143,8 @@ func NumberLit() Parser { ps.ErrorHere("number") return } + node.Start = ps.Pos + node.End = end ps.Pos = end }) } diff --git a/parser.go b/parser.go index f008d33..c2fbb3e 100644 --- a/parser.go +++ b/parser.go @@ -109,6 +109,8 @@ func Regex(pattern string) Parser { return NewParser(pattern, func(ps *State, node *Result) { ps.WS(ps) if match := re.FindString(ps.Get()); match != "" { + node.Start = ps.Pos + node.End = ps.Pos + len(match) ps.Advance(len(match)) node.Token = match return @@ -128,6 +130,8 @@ func Exact(match string) Parser { return } + node.Start = ps.Pos + node.End = ps.Pos + 1 ps.Advance(1) node.Token = match @@ -141,6 +145,9 @@ func Exact(match string) Parser { return } + node.Start = ps.Pos + node.End = ps.Pos + len(match) + ps.Advance(len(match)) node.Token = match @@ -241,6 +248,8 @@ func charsImpl(matcher string, stopOn bool, repetition ...int) Parser { return } + node.Start = ps.Pos + node.End = ps.Pos + matched node.Token = ps.Input[ps.Pos : ps.Pos+matched] ps.Advance(matched) } @@ -265,6 +274,8 @@ func Until(terminators ...string) Parser { if ps.Pos == startPos { ps.ErrorHere("something") } + node.Start = startPos + node.End = ps.Pos node.Token = ps.Input[startPos:ps.Pos] }) } diff --git a/result.go b/result.go index 21440eb..6f0f819 100644 --- a/result.go +++ b/result.go @@ -15,6 +15,8 @@ type Result struct { Token string Child []Result Result interface{} + Start int + End int } // String stringifies a node. This is only called from debug code.