Help us shape the future of Go! Take the 2026 Go Developer Survey

scanner

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 25, 2019 License: MIT Imports: 9 Imported by: 0

README

scanner

A tool for writing simple DSL parsers.

GoDoc

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

Examples

Constants

This section is empty.

Variables

View Source
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

type Error struct {
	Message  string
	Line     string
	LineNum  int
	Position int
}

Error is an error type that contains a reference to a specific position in a scanners input.

func (*Error) Error

func (e *Error) Error() string

Error returns the errors message.

func (*Error) PositionIndicator

func (e *Error) PositionIndicator() string

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

func (q GoEscaper) EscapeIndex(s string) int

EscapeIndex implements the Escaper interface

func (GoEscaper) Unescape

func (q GoEscaper) Unescape(s string) (string, int, error)

Unescape 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

func FromString(s string) *Scanner

FromString creates a scanner that will read from a string.

func New

func New(in io.Reader) *Scanner

New creates a scanner that will read from an io.Reader

func (*Scanner) Char

func (s *Scanner) Char() rune

Char parses a single rune enclosed in signle quotes.

func (*Scanner) Demand

func (s *Scanner) Demand(str string)

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

func (s *Scanner) Eat(str string) bool

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

func (s *Scanner) End() bool

End returns true if the scanner has reached the end of the input or encountered an error.

func (*Scanner) Err

func (s *Scanner) Err() error

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

func (s *Scanner) Fail(msg string)

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

func (s *Scanner) Failf(format string, a ...interface{})

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

func (s *Scanner) Float() float64

Float returns the next token as a float, or causes an error if the next token is not a float.

func (*Scanner) Ident

func (s *Scanner) Ident() string

Ident returns the next token, or causes an error if the next token is not an identifier.

func (*Scanner) Int

func (s *Scanner) Int() int

Int returns the next token as an int, or causes an error if the next token is not an int.

func (*Scanner) Is

func (s *Scanner) Is(str string) bool

Is returns true if the scanner's input starts with str, but does not advance the scanner. str should not contain whitespace.

func (*Scanner) IsFloat

func (s *Scanner) IsFloat() bool

IsFloat returns true if the next token is a float.

func (*Scanner) IsIdent

func (s *Scanner) IsIdent() bool

IsIdent returns true if the next token is an identifier.

func (*Scanner) IsInt

func (s *Scanner) IsInt() bool

IsInt returns true if the next token is an int.

func (*Scanner) Peek

func (s *Scanner) Peek() rune

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

func (s *Scanner) PeekFloat() (float64, bool)

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

func (s *Scanner) PeekIdent() string

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

func (s *Scanner) PeekInt() (int, bool)

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

func (s *Scanner) Quote(start, end string, esc Escaper) string

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

func (s *Scanner) QuoteMultiline(start, end string, esc Escaper) string

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.

func (*Scanner) Rune

func (s *Scanner) Rune() rune

Rune returns the next rune and advances the scanner. Rune will never return a whitespace character. If the scanner has encountered an error or EOF, Rune returns 0.

func (*Scanner) String

func (s *Scanner) String() string

String parses a string enclosed in double quotes.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL