summaryrefslogtreecommitdiff
path: root/state.go
diff options
context:
space:
mode:
authorAdam Scarr <adam@vektah.net>2017-08-09 21:18:14 +1000
committerAdam Scarr <adam@vektah.net>2017-08-09 21:19:41 +1000
commit47badae641b9cd8862f327864d2143a57b8e30af (patch)
tree930e6621051ec4da5e4fd028f98447e88978837d /state.go
parent8b2f10f2384c1efe4492f68b055415be6ead3f0e (diff)
Add godoc
Diffstat (limited to 'state.go')
-rw-r--r--state.go68
1 files changed, 44 insertions, 24 deletions
diff --git a/state.go b/state.go
index d153df8..1860bc4 100644
--- a/state.go
+++ b/state.go
@@ -4,29 +4,56 @@ import (
"fmt"
)
+// Error represents a parse error. These will often be set, the parser will back up a little and
+// find another viable path. In general when combining errors the longest error should be returned.
type Error struct {
pos int
- Expected string
+ expected string
}
-func (e Error) Pos() int { return e.pos }
-func (e Error) Error() string { return fmt.Sprintf("offset %d: Expected %s", e.pos, e.Expected) }
+// Pos is the offset into the document the error was found
+func (e Error) Pos() int { return e.pos }
+// Error satisfies the golang error interface
+func (e Error) Error() string { return fmt.Sprintf("offset %d: expected %s", e.pos, e.expected) }
+
+// WSFunc matches a byte and returns true if it is whitespace
type WSFunc func(c byte) bool
+// State is the current parse state. It is entirely public because parsers are expected to mutate it during the parse.
type State struct {
- Input string
- Pos int
- Error Error
+ // The full input string
+ Input string
+ // An offset into the string, pointing to the current tip
+ Pos int
+ // Error is a secondary return channel from parsers, but used so heavily
+ // in backtracking that it has been inlined to avoid allocations.
+ Error Error
+ // Called to determine what to ignore when WS is called, or when AutoWS fires
WSFunc WSFunc
NoAutoWS bool
}
+// NewState creates a new State from a string
+func NewState(input string) *State {
+ return &State{
+ Input: input,
+ WSFunc: func(b byte) bool {
+ switch b {
+ case '\t', '\n', '\v', '\f', '\r', ' ':
+ return true
+ }
+ return false
+ },
+ }
+}
+
+// Advance the Pos along by i bytes
func (s *State) Advance(i int) {
s.Pos += i
}
-// AutoWS consumes all whitespace
+// AutoWS consumes all whitespace and advances Pos but can be disabled by the NoAutWS() parser.
func (s *State) AutoWS() {
if s.NoAutoWS {
return
@@ -34,12 +61,14 @@ func (s *State) AutoWS() {
s.WS()
}
+// WS consumes all whitespace and advances Pos.
func (s *State) WS() {
for s.Pos < len(s.Input) && s.WSFunc(s.Input[s.Pos]) {
s.Pos++
}
}
+// Get the remaining input.
func (s *State) Get() string {
if s.Pos > len(s.Input) {
return ""
@@ -47,28 +76,19 @@ func (s *State) Get() string {
return s.Input[s.Pos:]
}
+// ErrorHere raises an error at the current position.
func (s *State) ErrorHere(expected string) {
s.Error.pos = s.Pos
- s.Error.Expected = expected
+ s.Error.expected = expected
}
-func (s *State) ClearError() {
- s.Error.Expected = ""
+// Recover from the current error. Often called by combinators that can match
+// when one of their children succeed, but others have failed.
+func (s *State) Recover() {
+ s.Error.expected = ""
}
+// Errored returns true if the current parser has failed.
func (s *State) Errored() bool {
- return s.Error.Expected != ""
-}
-
-func InputString(input string) *State {
- return &State{
- Input: input,
- WSFunc: func(b byte) bool {
- switch b {
- case '\t', '\n', '\v', '\f', '\r', ' ':
- return true
- }
- return false
- },
- }
+ return s.Error.expected != ""
}