Browse Source

scanner.Scanner: initial struct and methods for the low level text scanner

Signed-off-by: Alejandro Mery <amery@geeks.cl>
v0.2.x
Alejandro Mery 10 years ago
parent
commit
d4dbc28aee
  1. 72
      scanner/scanner.go

72
scanner/scanner.go

@ -1 +1,73 @@
package scanner
import (
"unicode/utf8"
)
const (
EOF = -1
)
type Position struct {
Offset uint
Line, Column uint
}
type Scanner struct {
name string
input string
base Position
cursor Position
runes uint
}
// Creates new Scanner to parse a given string, or nil if empty
func NewScannerFromString(name, input string) *Scanner {
if len(input) == 0 {
return nil
}
return &Scanner{
name: name,
input: input,
base: Position{0, 1, 1},
cursor: Position{0, 1, 1},
runes: 0,
}
}
// Current length of the upcomming Terminal
func (l *Scanner) Length() (uint, uint) {
return l.cursor.Offset - l.base.Offset, l.runes
}
// Is the upcoming Terminal stil empty?
func (l *Scanner) Empty() bool {
return l.runes == 0
}
// Move cursor forward
func (l *Scanner) StepForth(runes, bytes uint) {
l.cursor.Offset += bytes
l.cursor.Column += runes
l.runes += runes
}
// Return the next rune but not moving the cursor
func (l *Scanner) Peek() (rune, uint) {
if l.cursor.Offset == uint(len(l.input)) {
return EOF, 0
}
r, bytes := utf8.DecodeRuneInString(l.input[l.cursor.Offset:])
return r, uint(bytes)
}
// Return the next rune but moving the cursor
func (l *Scanner) Next() (rune, uint) {
r, bytes := l.Peek()
if bytes > 0 {
l.StepForth(1, bytes)
}
return r, bytes
}

Loading…
Cancel
Save