Documentation
¶
Overview ¶
Package scanner provides an easy-to-use scanner for writing simple DSL parsers.
Example ¶
package main
import (
"fmt"
"github.com/jfreymuth/scanner"
)
func main() {
const input = `
// single line comment
/*
multi line
comment
*/
exampleString = "This is an example \u263a"
exampleNumber = 12.5
exampleList = ["test", 2]
`
sc := scanner.FromString(input)
for !sc.End() {
name := sc.Ident()
sc.Demand("=")
value := parseValue(sc)
fmt.Printf("%s: %v\n", name, value)
}
if sc.Err() != nil {
fmt.Println("An error occurred:")
if err, ok := sc.Err().(*scanner.Error); ok {
fmt.Println(err.PositionIndicator())
} else {
fmt.Println(sc.Err())
}
}
}
func parseValue(sc *scanner.Scanner) interface{} {
switch {
case sc.Is("\""):
return sc.String()
case sc.Eat("["):
var list []interface{}
for !sc.Eat("]") {
list = append(list, parseValue(sc))
if !sc.Eat(",") {
sc.Demand("]")
break
}
}
return list
case sc.IsInt():
return sc.Int()
case sc.IsFloat():
return sc.Float()
default:
sc.Fail("invalid value")
return nil
}
}
Output: exampleString: This is an example ☺ exampleNumber: 12.5 exampleList: [test 2]
Index ¶
- Variables
- type Error
- type Escaper
- type GoEscaper
- type Scanner
- func (s *Scanner) Char() rune
- func (s *Scanner) Demand(str string)
- func (s *Scanner) Eat(str string) bool
- func (s *Scanner) End() bool
- func (s *Scanner) Err() error
- func (s *Scanner) Fail(msg string)
- func (s *Scanner) Failf(format string, a ...interface{})
- func (s *Scanner) Float() float64
- func (s *Scanner) Ident() string
- func (s *Scanner) Int() int
- func (s *Scanner) Is(str string) bool
- func (s *Scanner) IsFloat() bool
- func (s *Scanner) IsIdent() bool
- func (s *Scanner) IsInt() bool
- func (s *Scanner) Peek() rune
- func (s *Scanner) PeekFloat() (float64, bool)
- func (s *Scanner) PeekIdent() string
- func (s *Scanner) PeekInt() (int, bool)
- func (s *Scanner) Quote(start, end string, esc Escaper) string
- func (s *Scanner) QuoteMultiline(start, end string, esc Escaper) string
- func (s *Scanner) Rune() rune
- func (s *Scanner) String() string
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrEscape = errors.New("invalid escape sequence")
ErrEscape is a convenient error that can be returned by an implementation of Escaper
Functions ¶
This section is empty.
Types ¶
type Error ¶
Error is an error type that contains a reference to a specific position in a scanners input.
func (*Error) PositionIndicator ¶
PositionIndicator returns a user-friendly multi-line-string containing the message, line and position of the error.
type Escaper ¶
type Escaper interface {
// EscapeIndex returns the index of the first escape sequence in the string, or -1
EscapeIndex(string) int
// Unescape parses the escape sequence at the start of the string.
// It returns:
// a string the escape sequence should be replaced with,
// the length of the escape sequence,
// and an error, if the escape sequence is invalid.
Unescape(string) (string, int, error)
}
An Escaper can detect and replace escape sequences.
type GoEscaper ¶
type GoEscaper byte
A GoEscaper supports escape sequences exactly as defined by the go specification.
func (GoEscaper) EscapeIndex ¶
EscapeIndex implements the Escaper interface
type Scanner ¶
type Scanner struct {
// contains filtered or unexported fields
}
A Scanner wraps an io.Reader and provides convenient methods for parsing simple languages. The scanner will ignore whitespace and go-style comments, except to seperate tokens. Once the scanner encounters any error, most of it's methods will return the zero value.
func FromString ¶
FromString creates a scanner that will read from a string.
func (*Scanner) Demand ¶
Demand consumes a string, or causes an error if the scanner's input does not start with str. str should not contain whitespace.
func (*Scanner) Eat ¶
Eat returns true and consumes the string if the scanner's input starts with str. The scanner will not be advanced if Eat returns false. str should not contain whitespace.
func (*Scanner) End ¶
End returns true if the scanner has reached the end of the input or encountered an error.
func (*Scanner) Err ¶
Err returns the first error encountered by the scanner, or nil if there was no error. The returned error will either be of the type *Error, or an error returned by the underlying io.Reader.
func (*Scanner) Fail ¶
Fail sets the scanner's error, unless it has already encountered another error. The error will contain the current line and position of the scanner.
func (*Scanner) Failf ¶
Failf sets the scanner's error, unless it has already encountered another error. The error will contain the current line and position of the scanner.
func (*Scanner) Float ¶
Float returns the next token as a float, or causes an error if the next token is not a float.
func (*Scanner) Ident ¶
Ident returns the next token, or causes an error if the next token is not an identifier.
func (*Scanner) Int ¶
Int returns the next token as an int, or causes an error if the next token is not an int.
func (*Scanner) Is ¶
Is returns true if the scanner's input starts with str, but does not advance the scanner. str should not contain whitespace.
func (*Scanner) Peek ¶
Peek returns the next rune, without advancing the scanner. Peek will never return a whitespace character. If the scanner has encountered an error or EOF, Peek returns 0.
func (*Scanner) PeekFloat ¶
PeekFloat returns the next token as a float, or (0, false) if the next token is not a float. PeekFloat does not advance the scanner.
func (*Scanner) PeekIdent ¶
PeekIdent returns the next token, or an empty string if the next token is not an identifier. PeekIdent will not advance the scanner.
func (*Scanner) PeekInt ¶
PeekInt returns the next token as an int, or (0, false) if the next token is not an int. PeekInt does not advance the scanner.
func (*Scanner) Quote ¶
Quote returns all text, including whitespace and comments, between the start and end tokens. Quote causes an error if the current token is not start or if the current line does not contain end.
func (*Scanner) QuoteMultiline ¶
QuoteMultiline returns all text, including whitespace, line breaks, and comments, between the start and end tokens. QuoteMultiline causes an error if the current token is not start or if the input does not contain end.