vendor/github.com/magiconair/properties/lex.go
author Mikael Berthe <mikael@lilotux.net>
Sat, 29 Sep 2018 18:09:54 +0200
changeset 242 2a9ec03fe5a1
child 260 445e01aede7e
permissions -rw-r--r--
Use vendoring for backward compatibility The switch of the Madon library to Go modules breaks builds with Go version < 1.11 since the import path now contains "v2". This patch adds vendoring so that it can still build with those versions. Let's try to re-enable Travis builds with Go v1.8-1.11...
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
242
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     1
// Copyright 2018 Frank Schroeder. All rights reserved.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     2
// Use of this source code is governed by a BSD-style
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     3
// license that can be found in the LICENSE file.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     4
//
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     5
// Parts of the lexer are from the template/text/parser package
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     6
// For these parts the following applies:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     7
//
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     8
// Copyright 2011 The Go Authors. All rights reserved.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     9
// Use of this source code is governed by a BSD-style
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    10
// license that can be found in the LICENSE file of the go 1.2
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    11
// distribution.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    12
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    13
package properties
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    14
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    15
import (
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    16
	"fmt"
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    17
	"strconv"
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    18
	"strings"
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    19
	"unicode/utf8"
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    20
)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    21
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    22
// item represents a token or text string returned from the scanner.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    23
type item struct {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    24
	typ itemType // The type of this item.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    25
	pos int      // The starting position, in bytes, of this item in the input string.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    26
	val string   // The value of this item.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    27
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    28
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    29
func (i item) String() string {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    30
	switch {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    31
	case i.typ == itemEOF:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    32
		return "EOF"
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    33
	case i.typ == itemError:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    34
		return i.val
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    35
	case len(i.val) > 10:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    36
		return fmt.Sprintf("%.10q...", i.val)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    37
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    38
	return fmt.Sprintf("%q", i.val)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    39
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    40
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    41
// itemType identifies the type of lex items.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    42
type itemType int
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    43
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    44
const (
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    45
	itemError itemType = iota // error occurred; value is text of error
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    46
	itemEOF
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    47
	itemKey     // a key
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    48
	itemValue   // a value
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    49
	itemComment // a comment
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    50
)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    51
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    52
// defines a constant for EOF
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    53
const eof = -1
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    54
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    55
// permitted whitespace characters space, FF and TAB
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    56
const whitespace = " \f\t"
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    57
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    58
// stateFn represents the state of the scanner as a function that returns the next state.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    59
type stateFn func(*lexer) stateFn
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    60
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    61
// lexer holds the state of the scanner.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    62
type lexer struct {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    63
	input   string    // the string being scanned
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    64
	state   stateFn   // the next lexing function to enter
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    65
	pos     int       // current position in the input
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    66
	start   int       // start position of this item
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    67
	width   int       // width of last rune read from input
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    68
	lastPos int       // position of most recent item returned by nextItem
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    69
	runes   []rune    // scanned runes for this item
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    70
	items   chan item // channel of scanned items
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    71
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    72
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    73
// next returns the next rune in the input.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    74
func (l *lexer) next() rune {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    75
	if l.pos >= len(l.input) {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    76
		l.width = 0
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    77
		return eof
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    78
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    79
	r, w := utf8.DecodeRuneInString(l.input[l.pos:])
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    80
	l.width = w
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    81
	l.pos += l.width
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    82
	return r
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    83
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    84
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    85
// peek returns but does not consume the next rune in the input.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    86
func (l *lexer) peek() rune {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    87
	r := l.next()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    88
	l.backup()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    89
	return r
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    90
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    91
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    92
// backup steps back one rune. Can only be called once per call of next.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    93
func (l *lexer) backup() {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    94
	l.pos -= l.width
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    95
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    96
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    97
// emit passes an item back to the client.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    98
func (l *lexer) emit(t itemType) {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    99
	i := item{t, l.start, string(l.runes)}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   100
	l.items <- i
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   101
	l.start = l.pos
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   102
	l.runes = l.runes[:0]
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   103
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   104
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   105
// ignore skips over the pending input before this point.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   106
func (l *lexer) ignore() {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   107
	l.start = l.pos
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   108
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   109
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   110
// appends the rune to the current value
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   111
func (l *lexer) appendRune(r rune) {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   112
	l.runes = append(l.runes, r)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   113
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   114
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   115
// accept consumes the next rune if it's from the valid set.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   116
func (l *lexer) accept(valid string) bool {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   117
	if strings.ContainsRune(valid, l.next()) {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   118
		return true
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   119
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   120
	l.backup()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   121
	return false
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   122
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   123
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   124
// acceptRun consumes a run of runes from the valid set.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   125
func (l *lexer) acceptRun(valid string) {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   126
	for strings.ContainsRune(valid, l.next()) {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   127
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   128
	l.backup()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   129
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   130
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   131
// acceptRunUntil consumes a run of runes up to a terminator.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   132
func (l *lexer) acceptRunUntil(term rune) {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   133
	for term != l.next() {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   134
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   135
	l.backup()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   136
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   137
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   138
// hasText returns true if the current parsed text is not empty.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   139
func (l *lexer) isNotEmpty() bool {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   140
	return l.pos > l.start
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   141
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   142
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   143
// lineNumber reports which line we're on, based on the position of
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   144
// the previous item returned by nextItem. Doing it this way
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   145
// means we don't have to worry about peek double counting.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   146
func (l *lexer) lineNumber() int {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   147
	return 1 + strings.Count(l.input[:l.lastPos], "\n")
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   148
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   149
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   150
// errorf returns an error token and terminates the scan by passing
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   151
// back a nil pointer that will be the next state, terminating l.nextItem.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   152
func (l *lexer) errorf(format string, args ...interface{}) stateFn {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   153
	l.items <- item{itemError, l.start, fmt.Sprintf(format, args...)}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   154
	return nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   155
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   156
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   157
// nextItem returns the next item from the input.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   158
func (l *lexer) nextItem() item {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   159
	i := <-l.items
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   160
	l.lastPos = i.pos
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   161
	return i
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   162
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   163
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   164
// lex creates a new scanner for the input string.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   165
func lex(input string) *lexer {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   166
	l := &lexer{
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   167
		input: input,
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   168
		items: make(chan item),
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   169
		runes: make([]rune, 0, 32),
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   170
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   171
	go l.run()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   172
	return l
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   173
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   174
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   175
// run runs the state machine for the lexer.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   176
func (l *lexer) run() {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   177
	for l.state = lexBeforeKey(l); l.state != nil; {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   178
		l.state = l.state(l)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   179
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   180
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   181
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   182
// state functions
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   183
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   184
// lexBeforeKey scans until a key begins.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   185
func lexBeforeKey(l *lexer) stateFn {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   186
	switch r := l.next(); {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   187
	case isEOF(r):
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   188
		l.emit(itemEOF)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   189
		return nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   190
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   191
	case isEOL(r):
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   192
		l.ignore()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   193
		return lexBeforeKey
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   194
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   195
	case isComment(r):
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   196
		return lexComment
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   197
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   198
	case isWhitespace(r):
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   199
		l.ignore()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   200
		return lexBeforeKey
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   201
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   202
	default:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   203
		l.backup()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   204
		return lexKey
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   205
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   206
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   207
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   208
// lexComment scans a comment line. The comment character has already been scanned.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   209
func lexComment(l *lexer) stateFn {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   210
	l.acceptRun(whitespace)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   211
	l.ignore()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   212
	for {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   213
		switch r := l.next(); {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   214
		case isEOF(r):
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   215
			l.ignore()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   216
			l.emit(itemEOF)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   217
			return nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   218
		case isEOL(r):
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   219
			l.emit(itemComment)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   220
			return lexBeforeKey
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   221
		default:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   222
			l.appendRune(r)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   223
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   224
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   225
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   226
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   227
// lexKey scans the key up to a delimiter
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   228
func lexKey(l *lexer) stateFn {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   229
	var r rune
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   230
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   231
Loop:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   232
	for {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   233
		switch r = l.next(); {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   234
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   235
		case isEscape(r):
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   236
			err := l.scanEscapeSequence()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   237
			if err != nil {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   238
				return l.errorf(err.Error())
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   239
			}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   240
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   241
		case isEndOfKey(r):
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   242
			l.backup()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   243
			break Loop
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   244
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   245
		case isEOF(r):
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   246
			break Loop
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   247
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   248
		default:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   249
			l.appendRune(r)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   250
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   251
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   252
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   253
	if len(l.runes) > 0 {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   254
		l.emit(itemKey)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   255
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   256
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   257
	if isEOF(r) {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   258
		l.emit(itemEOF)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   259
		return nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   260
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   261
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   262
	return lexBeforeValue
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   263
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   264
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   265
// lexBeforeValue scans the delimiter between key and value.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   266
// Leading and trailing whitespace is ignored.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   267
// We expect to be just after the key.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   268
func lexBeforeValue(l *lexer) stateFn {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   269
	l.acceptRun(whitespace)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   270
	l.accept(":=")
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   271
	l.acceptRun(whitespace)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   272
	l.ignore()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   273
	return lexValue
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   274
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   275
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   276
// lexValue scans text until the end of the line. We expect to be just after the delimiter.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   277
func lexValue(l *lexer) stateFn {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   278
	for {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   279
		switch r := l.next(); {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   280
		case isEscape(r):
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   281
			if isEOL(l.peek()) {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   282
				l.next()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   283
				l.acceptRun(whitespace)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   284
			} else {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   285
				err := l.scanEscapeSequence()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   286
				if err != nil {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   287
					return l.errorf(err.Error())
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   288
				}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   289
			}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   290
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   291
		case isEOL(r):
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   292
			l.emit(itemValue)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   293
			l.ignore()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   294
			return lexBeforeKey
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   295
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   296
		case isEOF(r):
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   297
			l.emit(itemValue)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   298
			l.emit(itemEOF)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   299
			return nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   300
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   301
		default:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   302
			l.appendRune(r)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   303
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   304
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   305
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   306
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   307
// scanEscapeSequence scans either one of the escaped characters
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   308
// or a unicode literal. We expect to be after the escape character.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   309
func (l *lexer) scanEscapeSequence() error {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   310
	switch r := l.next(); {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   311
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   312
	case isEscapedCharacter(r):
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   313
		l.appendRune(decodeEscapedCharacter(r))
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   314
		return nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   315
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   316
	case atUnicodeLiteral(r):
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   317
		return l.scanUnicodeLiteral()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   318
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   319
	case isEOF(r):
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   320
		return fmt.Errorf("premature EOF")
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   321
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   322
	// silently drop the escape character and append the rune as is
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   323
	default:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   324
		l.appendRune(r)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   325
		return nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   326
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   327
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   328
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   329
// scans a unicode literal in the form \uXXXX. We expect to be after the \u.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   330
func (l *lexer) scanUnicodeLiteral() error {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   331
	// scan the digits
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   332
	d := make([]rune, 4)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   333
	for i := 0; i < 4; i++ {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   334
		d[i] = l.next()
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   335
		if d[i] == eof || !strings.ContainsRune("0123456789abcdefABCDEF", d[i]) {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   336
			return fmt.Errorf("invalid unicode literal")
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   337
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   338
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   339
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   340
	// decode the digits into a rune
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   341
	r, err := strconv.ParseInt(string(d), 16, 0)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   342
	if err != nil {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   343
		return err
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   344
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   345
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   346
	l.appendRune(rune(r))
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   347
	return nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   348
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   349
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   350
// decodeEscapedCharacter returns the unescaped rune. We expect to be after the escape character.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   351
func decodeEscapedCharacter(r rune) rune {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   352
	switch r {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   353
	case 'f':
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   354
		return '\f'
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   355
	case 'n':
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   356
		return '\n'
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   357
	case 'r':
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   358
		return '\r'
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   359
	case 't':
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   360
		return '\t'
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   361
	default:
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   362
		return r
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   363
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   364
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   365
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   366
// atUnicodeLiteral reports whether we are at a unicode literal.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   367
// The escape character has already been consumed.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   368
func atUnicodeLiteral(r rune) bool {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   369
	return r == 'u'
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   370
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   371
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   372
// isComment reports whether we are at the start of a comment.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   373
func isComment(r rune) bool {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   374
	return r == '#' || r == '!'
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   375
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   376
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   377
// isEndOfKey reports whether the rune terminates the current key.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   378
func isEndOfKey(r rune) bool {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   379
	return strings.ContainsRune(" \f\t\r\n:=", r)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   380
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   381
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   382
// isEOF reports whether we are at EOF.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   383
func isEOF(r rune) bool {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   384
	return r == eof
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   385
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   386
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   387
// isEOL reports whether we are at a new line character.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   388
func isEOL(r rune) bool {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   389
	return r == '\n' || r == '\r'
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   390
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   391
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   392
// isEscape reports whether the rune is the escape character which
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   393
// prefixes unicode literals and other escaped characters.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   394
func isEscape(r rune) bool {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   395
	return r == '\\'
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   396
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   397
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   398
// isEscapedCharacter reports whether we are at one of the characters that need escaping.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   399
// The escape character has already been consumed.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   400
func isEscapedCharacter(r rune) bool {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   401
	return strings.ContainsRune(" :=fnrt", r)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   402
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   403
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   404
// isWhitespace reports whether the rune is a whitespace character.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   405
func isWhitespace(r rune) bool {
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   406
	return strings.ContainsRune(whitespace, r)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   407
}