scanner: do not panic if there is nothing to unread
This commit is contained in:
parent
38490ad4dc
commit
72f3456c0f
36
parser/walk.go
Normal file
36
parser/walk.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package parser
|
||||||
|
|
||||||
|
// Walk traverses an AST in depth-first order: It starts by calling fn(node);
|
||||||
|
// node must not be nil. If f returns true, Walk invokes f recursively for
|
||||||
|
// each of the non-nil children of node, followed by a call of f(nil).
|
||||||
|
func Walk(node Node, fn func(Node) bool) {
|
||||||
|
if !fn(node) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch n := node.(type) {
|
||||||
|
case *ObjectList:
|
||||||
|
for _, item := range n.items {
|
||||||
|
Walk(item, fn)
|
||||||
|
}
|
||||||
|
case *ObjectKey:
|
||||||
|
// nothing to do
|
||||||
|
case *ObjectItem:
|
||||||
|
for _, k := range n.keys {
|
||||||
|
Walk(k, fn)
|
||||||
|
}
|
||||||
|
Walk(n.val, fn)
|
||||||
|
case *LiteralType:
|
||||||
|
// nothing to do
|
||||||
|
case *ListType:
|
||||||
|
for _, l := range n.list {
|
||||||
|
Walk(l, fn)
|
||||||
|
}
|
||||||
|
case *ObjectType:
|
||||||
|
for _, l := range n.list {
|
||||||
|
Walk(l, fn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn(nil)
|
||||||
|
}
|
@ -414,7 +414,7 @@ func (s *Scanner) scanEscape() rune {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// scanDigits scans a rune with the given base for n times. For example an
|
// scanDigits scans a rune with the given base for n times. For example an
|
||||||
// octan notation \184 would yield in scanDigits(ch, 8, 3)
|
// octal notation \184 would yield in scanDigits(ch, 8, 3)
|
||||||
func (s *Scanner) scanDigits(ch rune, base, n int) rune {
|
func (s *Scanner) scanDigits(ch rune, base, n int) rune {
|
||||||
for n > 0 && digitVal(ch) < base {
|
for n > 0 && digitVal(ch) < base {
|
||||||
ch = s.next()
|
ch = s.next()
|
||||||
@ -436,7 +436,10 @@ func (s *Scanner) scanIdentifier() string {
|
|||||||
for isLetter(ch) || isDigit(ch) {
|
for isLetter(ch) || isDigit(ch) {
|
||||||
ch = s.next()
|
ch = s.next()
|
||||||
}
|
}
|
||||||
s.unread() // we got identifier, put back latest char
|
|
||||||
|
if ch != eof {
|
||||||
|
s.unread() // we got identifier, put back latest char
|
||||||
|
}
|
||||||
|
|
||||||
return string(s.src[offs:s.srcPos.Offset])
|
return string(s.src[offs:s.srcPos.Offset])
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user