예제 #1
0
파일: edit.go 프로젝트: chai2010/T
// ParseNumber parses and returns a positive integer.
// Leading spaces are ignored.
// If EOF is reached before any digits are encountered, 1 is returned.
func parseNumber(rs io.RuneScanner) (int, error) {
	if err := skipSpace(rs); err != nil {
		return 0, err
	}
	var s string
	for {
		switch r, _, err := rs.ReadRune(); {
		case err == io.EOF:
			break
		case err != nil:
			return 0, err
		case unicode.IsDigit(r):
			s += string(r)
			continue
		default:
			if err := rs.UnreadRune(); err != nil {
				return 0, err
			}
		}

		if len(s) == 0 {
			return 1, nil
		}
		return strconv.Atoi(s)
	}
}
예제 #2
0
파일: addr.go 프로젝트: chai2010/T
func parseCompoundAddr(rs io.RuneScanner) (Address, error) {
	var a1 Address
	for {
		switch r, _, err := rs.ReadRune(); {
		case err == io.EOF:
			return a1, nil
		case err != nil:
			return nil, err
		case strings.ContainsRune(simpleFirst, r):
			if err := rs.UnreadRune(); err != nil {
				return nil, err
			}
			switch a2, err := parseSimpleAddr(rs); {
			case err != nil:
				return nil, err
			case a1 != nil:
				a1 = a1.Plus(a2)
			default:
				a1 = a2
			}
		case r == '+' || r == '-':
			if a1 == nil {
				a1 = Dot
			}
			a2, err := parseSimpleAddr(rs)
			if a2 == nil {
				a2 = Line(1)
			}
			switch {
			case err != nil:
				return nil, err
			case r == '+':
				a1 = a1.Plus(a2)
			default:
				a1 = a1.Minus(a2)
			}
		case r == ',' || r == ';':
			if a1 == nil {
				a1 = Line(0)
			}
			a2, err := parseCompoundAddr(rs)
			if a2 == nil {
				a2 = End
			}
			switch {
			case err != nil:
				return nil, err
			case r == ',':
				a1 = a1.To(a2)
			default:
				a1 = a1.Then(a2)
			}
		case unicode.IsSpace(r) && r != '\n':
			continue
		default:
			return a1, rs.UnreadRune()
		}
	}
}
예제 #3
0
파일: page.go 프로젝트: CowPanda/hugo
func chompBOM(r io.RuneScanner) (err error) {
	for {
		c, _, err := r.ReadRune()
		if err != nil {
			return err
		}
		if c != BOM {
			r.UnreadRune()
			return nil
		}
	}
}
예제 #4
0
파일: page.go 프로젝트: CowPanda/hugo
func chompWhitespace(r io.RuneScanner) (err error) {
	for {
		c, _, err := r.ReadRune()
		if err != nil {
			return err
		}
		if !unicode.IsSpace(c) {
			r.UnreadRune()
			return nil
		}
	}
}
예제 #5
0
파일: edit.go 프로젝트: chai2010/T
func skipSingleNewline(rs io.RuneScanner) error {
	// Eat a single trailing newline.
	switch r, _, err := rs.ReadRune(); {
	case err == io.EOF:
		return nil
	case err != nil:
		return err
	case r == '\n':
		return nil
	default:
		return rs.UnreadRune()
	}
}
예제 #6
0
func readNumber(b int, r io.RuneScanner) string {
	s := string(b)
	rune, _, err := r.ReadRune()
	for err == nil && string(rune) != " " && string(rune) != "(" && string(rune) != ")" {
		s = s + string(rune)
		rune, _, err = r.ReadRune()
	}
	if err == nil {
		r.UnreadRune()
	}

	return s
}
예제 #7
0
파일: edit.go 프로젝트: chai2010/T
// SkipSpace consumes and ignores non-newline whitespace.
// Terminates if a newline is encountered.
// The terminating newline remains consumed.
func skipSpace(rs io.RuneScanner) error {
	for {
		switch r, _, err := rs.ReadRune(); {
		case err == io.EOF:
			return nil
		case err != nil:
			return err
		case r != '\n' && unicode.IsSpace(r):
			continue
		default:
			return rs.UnreadRune()
		}
	}
}
예제 #8
0
// readSdParam reads a PARAM-NAME as defined by RFC-5424
// SD-PARAM        = PARAM-NAME "=" %d34 PARAM-VALUE %d34
// PARAM-NAME      = SD-NAME
// SD-NAME         = 1*32PRINTUSASCII except '=', SP, ']', %d34 (")
func readSdParamName(r io.RuneScanner) (string, error) {
	rv := &bytes.Buffer{}
	for {
		ch, _, err := r.ReadRune()
		if err != nil {
			return "", err
		}
		if ch == '=' {
			r.UnreadRune()
			return string(rv.Bytes()), nil
		}
		rv.WriteRune(ch)
	}
}
예제 #9
0
파일: glob.go 프로젝트: hailocab/ohmyglob
func parseNegation(r io.RuneScanner, glob *globImpl) error {
	for {
		char, _, err := r.ReadRune()

		if err != nil {
			return err
		} else if char == '!' {
			glob.negated = !glob.negated
		} else {
			r.UnreadRune()
			return nil
		}
	}
}
예제 #10
0
func readword(f *Xfile, isnum bool) string {
	var (
		barr [512]rune
		sp   int
		c    rune
		err  error
		sc   io.RuneScanner
	)
	if f.isgraphic() {
		sc = f.graph
	} else {
		sc = f.b
	}
	buf := barr[0:0]
	sp = 0
	for {
		c, _, err = sc.ReadRune()
		if err!=nil || !unicode.IsSpace(c) {
			break
		}
	}
	for {
		if err!=nil && sp==0 {
			panic("read: eof met")
		}
		buf = append(buf, c)
		sp++
		c, _, err = sc.ReadRune()
		if err!=nil || (isnum && !strings.ContainsRune("0123456789+-eE.", c)) {
			break
		}
		if err!=nil || unicode.IsSpace(c) {
			break
		}
	}
	if err != nil {
		if iseof(c, err) {
			f.eof = true
		}
	} else {
		f.eol = (c == rune(paminstr.EOL[0]))
		if !f.eol {
			sc.UnreadRune()
		}
	}
	if len(buf) == 0 {
		panic("read: eof met")
	}
	return string(buf)
}
예제 #11
0
파일: read.go 프로젝트: shxiao/clogure
func readNumber(b int, r io.RuneScanner) interface{} {
	s := string(b)

	for {
		rune := readRune(r)
		if rune == -1 || isWhiteSpace(rune) || rune == ')' {
			r.UnreadRune()
			return s
		}
		s = s + string(rune)
	}

	return matchNumer(s)
}
예제 #12
0
파일: addr.go 프로젝트: chai2010/T
func scanDigits(rs io.RuneScanner) (string, error) {
	var s string
	for {
		switch r, _, err := rs.ReadRune(); {
		case err == io.EOF:
			return s, nil
		case err != nil:
			return "", err
		case !unicode.IsDigit(r):
			return s, rs.UnreadRune()
		default:
			s += string(r)
		}
	}
}
예제 #13
0
파일: utils.go 프로젝트: subsilent/kappa
func ScanDelimited(r io.RuneScanner, start, end rune, escapes map[rune]rune, escapesPassThru bool) ([]byte, error) {

	// Scan start delimiter.
	if ch, _, err := r.ReadRune(); err != nil {
		return nil, err
	} else if ch != start {
		return nil, fmt.Errorf("expected %s; found %s", string(start), string(ch))
	}

	var buf bytes.Buffer
	for {
		ch0, _, err := r.ReadRune()
		if ch0 == end {
			return buf.Bytes(), nil
		} else if err != nil {
			return buf.Bytes(), err
		} else if ch0 == '\n' {
			return nil, errors.New("delimited text contains new line")
		} else if ch0 == '\\' {
			// If the next character is an escape then write the escaped char.
			// If it's not a valid escape then return an error.
			ch1, _, err := r.ReadRune()
			if err != nil {
				return nil, err
			}

			c, ok := escapes[ch1]
			if !ok {
				if escapesPassThru {
					// Unread ch1 (char after the \)
					_ = r.UnreadRune()
					// Write ch0 (\) to the output buffer.
					_, _ = buf.WriteRune(ch0)
					continue
				} else {
					buf.Reset()
					_, _ = buf.WriteRune(ch0)
					_, _ = buf.WriteRune(ch1)
					return buf.Bytes(), errBadEscape
				}
			}

			_, _ = buf.WriteRune(c)
		} else {
			_, _ = buf.WriteRune(ch0)
		}
	}
}
예제 #14
0
파일: read.go 프로젝트: shxiao/clogure
func seqReader(rune int, r io.RuneScanner) interface{} {
	seq := make([]interface{}, 0)
	for {
		nrune, _, err := r.ReadRune()
		for isWhiteSpace(nrune) {
			nrune, _, err = r.ReadRune()
		}
		if err != nil || string(nrune) == ")" {
			return seq
		}
		r.UnreadRune()
		fmt.Println(seq)
		seq = append(seq, read(r))
	}
	return seq
}
예제 #15
0
// ScanBareIdent reads bare identifier from a rune reader.
func ScanBareIdent(r io.RuneScanner) string {
	// Read every ident character into the buffer.
	// Non-ident characters and EOF will cause the loop to exit.
	var buf bytes.Buffer
	for {
		ch, _, err := r.ReadRune()
		if err != nil {
			break
		} else if !isIdentChar(ch) {
			r.UnreadRune()
			break
		} else {
			_, _ = buf.WriteRune(ch)
		}
	}
	return buf.String()
}
예제 #16
0
// readWord reads `r` until it encounters a space (0x20)
func readWord(r io.RuneScanner) (string, error) {
	rv := &bytes.Buffer{}
	for {
		ch, _, err := r.ReadRune()
		if err != nil {
			return "", err
		} else if ch != ' ' {
			rv.WriteRune(ch)
		} else {
			r.UnreadRune()
			rvString := string(rv.Bytes())
			if rvString == "-" {
				rvString = ""
			}
			return rvString, nil
		}
	}
}
예제 #17
0
func ReadList(in io.RuneScanner) Sexper {
	ch, _, _ := ReadChar(in)
	chstr := string(ch)

	switch chstr {
	case ")":
		return NIL
	case ".":
		list := ReadList(in)
		if list == NIL || fn_cdr(list) != NIL {
			panic(ERROR_DOT)
		}
		return fn_car(list)
	default:
		in.UnreadRune()
		scar := ReadSexp(in)
		scdr := ReadList(in)
		return List{scar, scdr}
	}
}
예제 #18
0
파일: scanner.go 프로젝트: jaguilar/vt100
// Decode decodes one ANSI terminal command from s.
//
// s should be connected to a client program that expects an
// ANSI terminal on the other end. It will push bytes to us that we are meant
// to intepret as terminal control codes, or text to place onto the terminal.
//
// This Command alone does not actually update the terminal. You need to pass
// it to VT100.Process().
//
// You should not share s with any other reader, because it could leave
// the stream in an invalid state.
func Decode(s io.RuneScanner) (Command, error) {
	r, size, err := s.ReadRune()
	if err != nil {
		return nil, err
	}

	if r == unicode.ReplacementChar && size == 1 {
		return nil, fmt.Errorf("non-utf8 data from reader")
	}

	if r == escape || r == monogramCsi { // At beginning of escape sequence.
		s.UnreadRune()
		return scanEscapeCommand(s)
	}

	if unicode.IsControl(r) {
		return controlCommand(r), nil
	}

	return runeCommand(r), nil
}
예제 #19
0
func ReadSexp(in io.RuneScanner) Sexper {
	ch, _, _ := ReadChar(in)

	switch string(ch) {
	case "\"":
		return ReadString(in)
	case "(":
		return ReadList(in)
	case "'":
		return fn_cons(Atom{"quote"}, fn_cons(ReadSexp(in), NIL))
	case ")":
		panic("unexcepted ')' found")
	default:
		in.UnreadRune()
		if unicode.IsDigit(ch) {
			return ReadNumber(in)
		} else {
			return ReadAtom(in)
		}
	}
}
예제 #20
0
// readStructuredData reads a STRUCTURED-DATA (as defined in RFC-5424)
// from `r` and assigns the StructuredData member.
//
// STRUCTURED-DATA = NILVALUE / 1*SD-ELEMENT
// SD-ELEMENT      = "[" SD-ID *(SP SD-PARAM) "]"
// SD-PARAM        = PARAM-NAME "=" %d34 PARAM-VALUE %d34
// SD-ID           = SD-NAME
// PARAM-NAME      = SD-NAME
// PARAM-VALUE     = UTF-8-STRING ; characters '"', '\' and ']' MUST be escaped.
// SD-NAME         = 1*32PRINTUSASCII except '=', SP, ']', %d34 (")
func (m *Message) readStructuredData(r io.RuneScanner) (err error) {
	m.StructuredData = []StructuredData{}

	ch, _, err := r.ReadRune()
	if err != nil {
		return err
	}
	if ch == '-' {
		return nil
	}
	r.UnreadRune()

	for {
		ch, _, err := r.ReadRune()
		if err == io.EOF {
			return nil
		} else if err != nil {
			return err // hard to reach without underlying IO error
		} else if ch == ' ' {
			r.UnreadRune()
			return nil
		} else if ch == '[' {
			r.UnreadRune()
			sde, err := readSDElement(r)
			if err != nil {
				return err
			}
			m.StructuredData = append(m.StructuredData, sde)
		} else {
			return BadFormat("StructuredData")
		}
	}
}
예제 #21
0
func ReadNumber(in io.RuneScanner) Sexper {
	ch, _, err := ReadChar(in)
	chstr := string(ch)
	if err != nil {
		panic(err)
	}

	result := 0
	for unicode.IsDigit(ch) && err == nil && chstr != "(" && chstr != ")" {
		number, _ := strconv.Atoi(string(ch))
		result = result*10 + number
		ch, _, err = in.ReadRune()
		chstr = string(ch)
	}
	if err != nil && err != io.EOF {
		panic(err)
	}
	if chstr == "(" || chstr == ")" {
		in.UnreadRune()
	}
	return Number{result}
}
예제 #22
0
// sexp reader
func ReadAtom(in io.RuneScanner) Sexper {
	ch, _, err := ReadChar(in)
	chstr := string(ch)
	if err == io.EOF {
		panic(ERROR_EOF)
	}

	buffer := make([]rune, 128)
	var i int
	for i = 0; !unicode.IsSpace(ch) && err == nil && chstr != "(" && chstr != ")"; i++ {
		buffer[i] = ch
		ch, _, err = in.ReadRune()
		chstr = string(ch)
	}
	if err != nil && err != io.EOF {
		panic(err)
	}
	if chstr == "(" || chstr == ")" {
		in.UnreadRune()
	}
	return Atom{string(buffer[0:i])}
}
예제 #23
0
파일: addr.go 프로젝트: chai2010/T
func parseSimpleAddr(rs io.RuneScanner) (SimpleAddress, error) {
	for {
		var r rune
		var err error
		var a SimpleAddress
		switch r, _, err = rs.ReadRune(); {
		case err == io.EOF:
			return a, nil
		case err != nil:
			return nil, err
		case r == '\'':
			a, err = parseMarkAddr(rs)
		case r == '#':
			a, err = parseRuneAddr(rs)
		case strings.ContainsRune(digits, r):
			a, err = parseLineAddr(r, rs)
		case r == '/' || r == '?':
			if err := rs.UnreadRune(); err != nil {
				return nil, err
			}
			exp, err := parseRegexp2(rs)
			if err != nil {
				return nil, err
			}
			return Regexp(string(exp)), nil
		case r == '$':
			a = End
		case r == '.':
			a = Dot
		case unicode.IsSpace(r) && r != '\n':
			break // nothing to do
		default:
			return nil, rs.UnreadRune()
		}
		if a != nil || err != nil {
			return a, err
		}
	}
}
예제 #24
0
파일: int.go 프로젝트: Sunmonds/gcc
// scan sets z to the integer value corresponding to the longest possible prefix
// read from r representing a signed integer number in a given conversion base.
// It returns z, the actual conversion base used, and an error, if any. In the
// error case, the value of z is undefined but the returned value is nil. The
// syntax follows the syntax of integer literals in Go.
//
// The base argument must be 0 or a value from 2 through MaxBase. If the base
// is 0, the string prefix determines the actual conversion base. A prefix of
// ``0x'' or ``0X'' selects base 16; the ``0'' prefix selects base 8, and a
// ``0b'' or ``0B'' prefix selects base 2. Otherwise the selected base is 10.
//
func (z *Int) scan(r io.RuneScanner, base int) (*Int, int, os.Error) {
	// determine sign
	ch, _, err := r.ReadRune()
	if err != nil {
		return nil, 0, err
	}
	neg := false
	switch ch {
	case '-':
		neg = true
	case '+': // nothing to do
	default:
		r.UnreadRune()
	}

	// determine mantissa
	z.abs, base, err = z.abs.scan(r, base)
	if err != nil {
		return nil, base, err
	}
	z.neg = len(z.abs) > 0 && neg // 0 has no sign

	return z, base, nil
}
예제 #25
0
파일: dec.go 프로젝트: jmptrader/decimal-1
func (d *Dec) scan(r io.RuneScanner) error {
	d.coef.hi = 0
	d.coef.lo = 0
	d.scale = 0
	ch, _, err := r.ReadRune()
	if err != nil {
		return err
	}
	var neg bool
	switch ch {
	case '-':
		neg = true
	case '+':
	default:
		r.UnreadRune()
	}
	var dec bool
	for {
		ch, _, err = r.ReadRune()
		if err == io.EOF {
			goto ExitLoop
		}
		if err != nil {
			return err
		}
		switch {
		case ch == '.':
			if dec {
				r.UnreadRune()
				goto ExitLoop
			}
			dec = true
		case ch >= '0' && ch <= '9':
			d.coef.Mul(&d.coef, intTen)
			var z Int128
			z.SetInt64(int64(ch - '0'))
			d.coef.Add(&d.coef, &z)
			if dec {
				d.scale++
			}
		default:
			r.UnreadRune()
			goto ExitLoop
		}
	}
ExitLoop:
	if neg {
		d.Neg(d)
	}
	return nil
}
예제 #26
0
파일: dec.go 프로젝트: 40a/bootkube
func (z *Dec) scan(r io.RuneScanner) (*Dec, error) {
	unscaled := make([]byte, 0, 256) // collects chars of unscaled as bytes
	dp, dg := -1, -1                 // indexes of decimal point, first digit
loop:
	for {
		ch, _, err := r.ReadRune()
		if err == io.EOF {
			break loop
		}
		if err != nil {
			return nil, err
		}
		switch {
		case ch == '+' || ch == '-':
			if len(unscaled) > 0 || dp >= 0 { // must be first character
				r.UnreadRune()
				break loop
			}
		case ch == '.':
			if dp >= 0 {
				r.UnreadRune()
				break loop
			}
			dp = len(unscaled)
			continue // don't add to unscaled
		case ch >= '0' && ch <= '9':
			if dg == -1 {
				dg = len(unscaled)
			}
		default:
			r.UnreadRune()
			break loop
		}
		unscaled = append(unscaled, byte(ch))
	}
	if dg == -1 {
		return nil, fmt.Errorf("no digits read")
	}
	if dp >= 0 {
		z.SetScale(Scale(len(unscaled) - dp))
	} else {
		z.SetScale(0)
	}
	_, ok := z.UnscaledBig().SetString(string(unscaled), 10)
	if !ok {
		return nil, fmt.Errorf("invalid decimal: %s", string(unscaled))
	}
	return z, nil
}
예제 #27
0
// scan sets z to the natural number corresponding to the longest possible prefix
// read from r representing an unsigned integer in a given conversion base.
// It returns z, the actual conversion base used, and an error, if any. In the
// error case, the value of z is undefined. The syntax follows the syntax of
// unsigned integer literals in Go.
//
// The base argument must be 0 or a value from 2 through MaxBase. If the base
// is 0, the string prefix determines the actual conversion base. A prefix of
// ``0x'' or ``0X'' selects base 16; the ``0'' prefix selects base 8, and a
// ``0b'' or ``0B'' prefix selects base 2. Otherwise the selected base is 10.
//
func (z nat) scan(r io.RuneScanner, base int) (nat, int, error) {
	// reject illegal bases
	if base < 0 || base == 1 || MaxBase < base {
		return z, 0, errors.New("illegal number base")
	}

	// one char look-ahead
	ch, _, err := r.ReadRune()
	if err != nil {
		return z, 0, err
	}

	// determine base if necessary
	b := Word(base)
	if base == 0 {
		b = 10
		if ch == '0' {
			switch ch, _, err = r.ReadRune(); err {
			case nil:
				b = 8
				switch ch {
				case 'x', 'X':
					b = 16
				case 'b', 'B':
					b = 2
				}
				if b == 2 || b == 16 {
					if ch, _, err = r.ReadRune(); err != nil {
						return z, 0, err
					}
				}
			case io.EOF:
				return z.make(0), 10, nil
			default:
				return z, 10, err
			}
		}
	}

	// convert string
	// - group as many digits d as possible together into a "super-digit" dd with "super-base" bb
	// - only when bb does not fit into a word anymore, do a full number mulAddWW using bb and dd
	z = z.make(0)
	bb := Word(1)
	dd := Word(0)
	for max := _M / b; ; {
		d := hexValue(ch)
		if d >= b {
			r.UnreadRune() // ch does not belong to number anymore
			break
		}

		if bb <= max {
			bb *= b
			dd = dd*b + d
		} else {
			// bb * b would overflow
			z = z.mulAddWW(z, bb, dd)
			bb = b
			dd = d
		}

		if ch, _, err = r.ReadRune(); err != nil {
			if err != io.EOF {
				return z, int(b), err
			}
			break
		}
	}

	switch {
	case bb > 1:
		// there was at least one mantissa digit
		z = z.mulAddWW(z, bb, dd)
	case base == 0 && b == 8:
		// there was only the octal prefix 0 (possibly followed by digits > 7);
		// return base 10, not 8
		return z, 10, nil
	case base != 0 || b != 8:
		// there was neither a mantissa digit nor the octal prefix 0
		return z, int(b), errors.New("syntax error scanning number")
	}

	return z.norm(), int(b), nil
}
예제 #28
0
// Compile will "compile" a string literal, which it pulls from the io.RunScanner, into
// the value the string literal represents.
//
// It returns both the value of the string literal and the original string literal code.
//
// If there is a syntax error in the string literal, it will return an error of type
// strlit.SyntaxErrorComplainer.
//
// If your string literal is in a Go string, and you want to pass it to strlit.Compile(),
// then wrap it in a strings.NewReader(). For example:
//
//	compiled, code, err := strlit.Compile( strings.NewReader("‘apple banana cherry’") )
func Compile(runeScanner io.RuneScanner) (valueOfStringLiteral Parcel, stringLiteralCode Parcel, err error) {

	code := newParcel()

	var r rune

	// Make sure there is at least one rune.
	r, _, err = runeScanner.ReadRune()
	if io.EOF == err {
		runeScanner.UnreadRune()
		return nil, nil, newSyntaxErrorComplainer("", "Hit the EOF before getting any data.")
	}
	if nil != err {
		return nil, nil, err
	}

	// Make sure the first rune is a valid begin quote rune.
	var endRune rune
	switch r {
	case '\'':
		endRune = r
	case '"':
		endRune = r
	case '‘':
		endRune = '’'
	case '“':
		endRune = '”'
	case '‹':
		endRune = '›'
	case '«':
		endRune = '»'
	default:
		runeScanner.UnreadRune()
		return nil, nil, newSyntaxErrorComplainer(code.String(), "Not a string literal. Beginning rune for string literal is not valid.")
	}
	code.buffer.WriteRune(r)

	// Make sure there are more runes in the string literal code (so that we can next check it ENDS with a quote (')).
	if _, _, err := runeScanner.ReadRune(); nil != err {
		return nil, nil, newSyntaxErrorComplainer(code.String(), "Missing ending quote (') at the end of the string literal.")
	}
	runeScanner.UnreadRune()

	compiled := newParcel()
	for {
		r, _, err = runeScanner.ReadRune()
		if io.EOF == err {
			return nil, nil, newSyntaxErrorComplainer(code.String(), "Hit the EOF before being able to get to end of string literal.")
		}
		if nil != err {
			return nil, nil, err
		}
		code.buffer.WriteRune(r)

		if endRune == r {

			r2, _, err := runeScanner.ReadRune()
			if io.EOF == err {
				return compiled, code, nil
			}
			if nil != err {
				return nil, nil, newSyntaxErrorComplainer(code.String(), "Something bad happened.")
			}

			if endRune != r2 {
				runeScanner.UnreadRune()
				return compiled, code, nil
			} else {
				code.buffer.WriteRune(r2)
			}
		} else if '\\' == r {

			r2, _, err := runeScanner.ReadRune()
			if nil != err {
				return nil, nil, newSyntaxErrorComplainer(code.String(), "Backslash (\\), by itself, in the middle of a string literal.")
			}
			code.buffer.WriteRune(r2)

			switch r2 {
			case '0':
				r = '\x00'
				//@TODO: Support octal escape notation.
			case 'U':
				r3, _, err := runeScanner.ReadRune()
				if nil != err {
					msg := "Problem after reading universal character escape sequence “\\x”."
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}
				code.buffer.WriteRune(r3)

				r4, _, err := runeScanner.ReadRune()
				if nil != err {
					msg := fmt.Sprintf("Problem after reading universal character escape sequence “\\x%s”.", string(r3))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}
				code.buffer.WriteRune(r4)

				r5, _, err := runeScanner.ReadRune()
				if nil != err {
					msg := fmt.Sprintf("Problem after reading universal character escape sequence “\\x%s%s”.", string(r3), string(r4))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}
				code.buffer.WriteRune(r5)

				r6, _, err := runeScanner.ReadRune()
				if nil != err {
					msg := fmt.Sprintf("Problem after reading universal character escape sequence “\\x%s%s%s”.", string(r3), string(r4), string(r5))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}
				code.buffer.WriteRune(r6)

				r7, _, err := runeScanner.ReadRune()
				if nil != err {
					msg := fmt.Sprintf("Problem after reading universal character escape sequence “\\x%s%s%s%s”.", string(r3), string(r4), string(r5), string(r6))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}
				code.buffer.WriteRune(r7)

				r8, _, err := runeScanner.ReadRune()
				if nil != err {
					msg := fmt.Sprintf("Problem after reading universal character escape sequence “\\x%s%s%s%s%s”.", string(r3), string(r4), string(r5), string(r6), string(r7))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}
				code.buffer.WriteRune(r8)

				r9, _, err := runeScanner.ReadRune()
				if nil != err {
					msg := fmt.Sprintf("Problem after reading universal character escape sequence “\\x%s%s%s%s%s%s”.", string(r3), string(r4), string(r5), string(r6), string(r7), string(r8))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}
				code.buffer.WriteRune(r9)

				r10, _, err := runeScanner.ReadRune()
				if nil != err {
					msg := fmt.Sprintf("Problem after reading universal character escape sequence “\\x%s%s%s%s%s%s%s”.", string(r3), string(r4), string(r5), string(r6), string(r7), string(r8), string(r9))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}
				code.buffer.WriteRune(r10)

				if !(('0' <= r3 && r3 <= '9') || ('A' <= r3 && r3 <= 'F') || ('a' <= r3 && r3 <= 'f')) {
					msg := fmt.Sprintf("Invalid universal character escape sequence: “\\U%s%s%s%s%s%s%s%s”.", string(r3), string(r4), string(r5), string(r6), string(r7), string(r8), string(r9), string(r10))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}

				if !(('0' <= r4 && r4 <= '9') || ('A' <= r4 && r4 <= 'F') || ('a' <= r4 && r4 <= 'f')) {
					msg := fmt.Sprintf("Invalid universal character escape sequence: “\\U%s%s%s%s%s%s%s%s”.", string(r3), string(r4), string(r5), string(r6), string(r7), string(r8), string(r9), string(r10))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}

				if !(('0' <= r5 && r5 <= '9') || ('A' <= r5 && r5 <= 'F') || ('a' <= r5 && r5 <= 'f')) {
					msg := fmt.Sprintf("Invalid universal character escape sequence: “\\U%s%s%s%s%s%s%s%s”.", string(r3), string(r4), string(r5), string(r6), string(r7), string(r8), string(r9), string(r10))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}

				if !(('0' <= r6 && r6 <= '9') || ('A' <= r6 && r6 <= 'F') || ('a' <= r6 && r6 <= 'f')) {
					msg := fmt.Sprintf("Invalid universal character escape sequence: “\\U%s%s%s%s%s%s%s%s”.", string(r3), string(r4), string(r5), string(r6), string(r7), string(r8), string(r9), string(r10))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}

				if !(('0' <= r7 && r7 <= '9') || ('A' <= r7 && r7 <= 'F') || ('a' <= r7 && r7 <= 'f')) {
					msg := fmt.Sprintf("Invalid universal character escape sequence: “\\U%s%s%s%s%s%s%s%s”.", string(r3), string(r4), string(r5), string(r6), string(r7), string(r8), string(r9), string(r10))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}

				if !(('0' <= r8 && r8 <= '9') || ('A' <= r8 && r8 <= 'F') || ('a' <= r8 && r8 <= 'f')) {
					msg := fmt.Sprintf("Invalid universal character escape sequence: “\\U%s%s%s%s%s%s%s%s”.", string(r3), string(r4), string(r5), string(r6), string(r7), string(r8), string(r9), string(r10))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}

				if !(('0' <= r9 && r9 <= '9') || ('A' <= r9 && r9 <= 'F') || ('a' <= r9 && r9 <= 'f')) {
					msg := fmt.Sprintf("Invalid universal character escape sequence: “\\U%s%s%s%s%s%s%s%s”.", string(r3), string(r4), string(r5), string(r6), string(r7), string(r8), string(r9), string(r10))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}

				if !(('0' <= r10 && r10 <= '9') || ('A' <= r10 && r10 <= 'F') || ('a' <= r10 && r10 <= 'f')) {
					msg := fmt.Sprintf("Invalid universal character escape sequence: “\\U%s%s%s%s%s%s%s%s”.", string(r3), string(r4), string(r5), string(r6), string(r7), string(r8), string(r9), string(r10))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}

				r = 0

				if '0' <= r3 && r3 <= '9' {
					r += (r3 - '0') * 16 * 16 * 16 * 16 * 16 * 16 * 16
				} else if 'A' <= r3 && r3 <= 'F' {
					r += (r3 - 'A' + 10) * 16 * 16 * 16 * 16 * 16 * 16 * 16
				} else if 'a' <= r3 && r3 <= 'f' {
					r += (r3 - 'a' + 10) * 16 * 16 * 16 * 16 * 16 * 16 * 16
				} else {
					return nil, nil, newSyntaxErrorComplainer(code.String(), "THIS SHOULD NEVER HAPPEN!")
				}

				if '0' <= r4 && r4 <= '9' {
					r += (r4 - '0') * 16 * 16 * 16 * 16 * 16 * 16
				} else if 'A' <= r4 && r4 <= 'F' {
					r += (r4 - 'A' + 10) * 16 * 16 * 16 * 16 * 16 * 16
				} else if 'a' <= r4 && r4 <= 'f' {
					r += (r4 - 'a' + 10) * 16 * 16 * 16 * 16 * 16 * 16
				} else {
					return nil, nil, newSyntaxErrorComplainer(code.String(), "THIS SHOULD NEVER HAPPEN!")
				}

				if '0' <= r5 && r5 <= '9' {
					r += (r5 - '0') * 16 * 16 * 16 * 16 * 16
				} else if 'A' <= r5 && r5 <= 'F' {
					r += (r5 - 'A' + 10) * 16 * 16 * 16 * 16 * 16
				} else if 'a' <= r5 && r5 <= 'f' {
					r += (r5 - 'a' + 10) * 16 * 16 * 16 * 16 * 16
				} else {
					return nil, nil, newSyntaxErrorComplainer(code.String(), "THIS SHOULD NEVER HAPPEN!")
				}

				if '0' <= r6 && r6 <= '9' {
					r += (r6 - '0') * 16 * 16 * 16 * 16
				} else if 'A' <= r6 && r6 <= 'F' {
					r += (r6 - 'A' + 10) * 16 * 16 * 16 * 16
				} else if 'a' <= r6 && r6 <= 'f' {
					r += (r6 - 'a' + 10) * 16 * 16 * 16 * 16
				} else {
					return nil, nil, newSyntaxErrorComplainer(code.String(), "THIS SHOULD NEVER HAPPEN!")
				}

				if '0' <= r7 && r7 <= '9' {
					r += (r7 - '0') * 16 * 16 * 16
				} else if 'A' <= r7 && r7 <= 'F' {
					r += (r7 - 'A' + 10) * 16 * 16 * 16
				} else if 'a' <= r7 && r7 <= 'f' {
					r += (r7 - 'a' + 10) * 16 * 16 * 16
				} else {
					return nil, nil, newSyntaxErrorComplainer(code.String(), "THIS SHOULD NEVER HAPPEN!")
				}

				if '0' <= r8 && r8 <= '9' {
					r += (r8 - '0') * 16 * 16
				} else if 'A' <= r8 && r8 <= 'F' {
					r += (r8 - 'A' + 10) * 16 * 16
				} else if 'a' <= r8 && r8 <= 'f' {
					r += (r8 - 'a' + 10) * 16 * 16
				} else {
					return nil, nil, newSyntaxErrorComplainer(code.String(), "THIS SHOULD NEVER HAPPEN!")
				}

				if '0' <= r9 && r9 <= '9' {
					r += (r9 - '0') * 16
				} else if 'A' <= r9 && r9 <= 'F' {
					r += (r9 - 'A' + 10) * 16
				} else if 'a' <= r9 && r9 <= 'f' {
					r += (r9 - 'a' + 10) * 16
				} else {
					return nil, nil, newSyntaxErrorComplainer(code.String(), "THIS SHOULD NEVER HAPPEN!")
				}

				if '0' <= r10 && r10 <= '9' {
					r += (r10 - '0')
				} else if 'A' <= r10 && r10 <= 'F' {
					r += (r10 - 'A' + 10)
				} else if 'a' <= r10 && r10 <= 'f' {
					r += (r10 - 'a' + 10)
				} else {
					return nil, nil, newSyntaxErrorComplainer(code.String(), "THIS SHOULD NEVER HAPPEN!")
				}
			case 'a':
				r = '\a'
			case 'b':
				r = '\b'
			case 'e':
				r = '\x1B'
			case 'f':
				r = '\f'
			case 'n':
				r = '\n'
			case 'r':
				r = '\r'
			case 't':
				r = '\t'
			case 'u':
				r3, _, err := runeScanner.ReadRune()
				if nil != err {
					msg := "Problem after reading hexadecimal escape “\\x”."
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}
				code.buffer.WriteRune(r3)

				r4, _, err := runeScanner.ReadRune()
				if nil != err {
					msg := fmt.Sprintf("Problem after reading universal character escape sequence “\\u%s”.", string(r3))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}
				code.buffer.WriteRune(r4)

				r5, _, err := runeScanner.ReadRune()
				if nil != err {
					msg := fmt.Sprintf("Problem after reading universal character escape sequence “\\u%s%s”.", string(r3), string(r4))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}
				code.buffer.WriteRune(r5)

				r6, _, err := runeScanner.ReadRune()
				if nil != err {
					msg := fmt.Sprintf("Problem after reading universal character escape sequence “\\u%s%s%s”.", string(r3), string(r4), string(r5))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}
				code.buffer.WriteRune(r6)

				if !(('0' <= r3 && r3 <= '9') || ('A' <= r3 && r3 <= 'F') || ('a' <= r3 && r3 <= 'f')) {
					msg := fmt.Sprintf("Invalid universal character escape sequence: “\\u%s%s%s%s”.", string(r3), string(r4), string(r5), string(r6))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}

				if !(('0' <= r4 && r4 <= '9') || ('A' <= r4 && r4 <= 'F') || ('a' <= r4 && r4 <= 'f')) {
					msg := fmt.Sprintf("Invalid universal character escape sequence: “\\u%s%s%s%s”.", string(r3), string(r4), string(r5), string(r6))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}

				if !(('0' <= r5 && r5 <= '9') || ('A' <= r5 && r5 <= 'F') || ('a' <= r5 && r5 <= 'f')) {
					msg := fmt.Sprintf("Invalid universal character escape sequence: “\\u%s%s%s%s”.", string(r3), string(r4), string(r5), string(r6))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}

				if !(('0' <= r6 && r6 <= '9') || ('A' <= r6 && r6 <= 'F') || ('a' <= r6 && r6 <= 'f')) {
					msg := fmt.Sprintf("Invalid universal character escape sequence: “\\u%s%s%s%s”.", string(r3), string(r4), string(r5), string(r6))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}

				r = 0

				if '0' <= r3 && r3 <= '9' {
					r += (r3 - '0') * 16 * 16 * 16
				} else if 'A' <= r3 && r3 <= 'F' {
					r += (r3 - 'A' + 10) * 16 * 16 * 16
				} else if 'a' <= r3 && r3 <= 'f' {
					r += (r3 - 'a' + 10) * 16 * 16 * 16
				} else {
					return nil, nil, newSyntaxErrorComplainer(code.String(), "THIS SHOULD NEVER HAPPEN!")
				}

				if '0' <= r4 && r4 <= '9' {
					r += (r4 - '0') * 16 * 16
				} else if 'A' <= r4 && r4 <= 'F' {
					r += (r4 - 'A' + 10) * 16 * 16
				} else if 'a' <= r4 && r4 <= 'f' {
					r += (r4 - 'a' + 10) * 16 * 16
				} else {
					return nil, nil, newSyntaxErrorComplainer(code.String(), "THIS SHOULD NEVER HAPPEN!")
				}

				if '0' <= r5 && r5 <= '9' {
					r += (r5 - '0') * 16
				} else if 'A' <= r5 && r5 <= 'F' {
					r += (r5 - 'A' + 10) * 16
				} else if 'a' <= r5 && r5 <= 'f' {
					r += (r5 - 'a' + 10) * 16
				} else {
					return nil, nil, newSyntaxErrorComplainer(code.String(), "THIS SHOULD NEVER HAPPEN!")
				}

				if '0' <= r6 && r6 <= '9' {
					r += r6 - '0'
				} else if 'A' <= r6 && r6 <= 'F' {
					r += r6 - 'A' + 10
				} else if 'a' <= r6 && r6 <= 'f' {
					r += r6 - 'a' + 10
				} else {
					return nil, nil, newSyntaxErrorComplainer(code.String(), "THIS SHOULD NEVER HAPPEN!")
				}
			case 'v':
				r = '\v'
			case 'x':
				r3, _, err := runeScanner.ReadRune()
				if nil != err {
					msg := "Problem after reading hexadecimal escape “\\x”."
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}
				code.buffer.WriteRune(r3)

				r4, _, err := runeScanner.ReadRune()
				if nil != err {
					msg := fmt.Sprintf("Problem after reading hexadecimal escape “\\x%s”.", string(r3))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}
				code.buffer.WriteRune(r4)

				if !(('0' <= r3 && r3 <= '9') || ('A' <= r3 && r3 <= 'F') || ('a' <= r3 && r3 <= 'f')) {
					msg := fmt.Sprintf("Invalid hexadecimal escape sequence: “\\x%s%s”.", string(r3), string(r4))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}

				if !(('0' <= r4 && r4 <= '9') || ('A' <= r4 && r4 <= 'F') || ('a' <= r4 && r4 <= 'f')) {
					msg := fmt.Sprintf("Invalid hexadecimal escape sequence: “\\x%s%s”.", string(r3), string(r4))
					return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
				}

				r = 0

				if '0' <= r3 && r3 <= '9' {
					r += (r3 - '0') * 16
				} else if 'A' <= r3 && r3 <= 'F' {
					r += (r3 - 'A' + 10) * 16
				} else if 'a' <= r3 && r3 <= 'f' {
					r += (r3 - 'a' + 10) * 16
				} else {
					return nil, nil, newSyntaxErrorComplainer(code.String(), "THIS SHOULD NEVER HAPPEN!")
				}

				if '0' <= r4 && r4 <= '9' {
					r += r4 - '0'
				} else if 'A' <= r4 && r4 <= 'F' {
					r += r4 - 'A' + 10
				} else if 'a' <= r4 && r4 <= 'f' {
					r += r4 - 'a' + 10
				} else {
					return nil, nil, newSyntaxErrorComplainer(code.String(), "THIS SHOULD NEVER HAPPEN!")
				}
			case '\\':
				r = '\\'
			case '\'':
				r = '\''
			case '"':
				r = '"'
			case '?':
				r = '?'
			case '‘':
				r = '‘'
			case '’':
				r = '’'
			case '“':
				r = '“'
			case '”':
				r = '”'
			case '‹':
				r = '‹'
			case '›':
				r = '›'
			case '«':
				r = '«'
			case '»':
				r = '»'
			default:
				msg := fmt.Sprintf("Invalid blackslash escape sequence: \\%s", string(r2))
				return nil, nil, newSyntaxErrorComplainer(code.String(), msg)
			}
		}

		compiled.buffer.WriteRune(r)
	}

	return compiled, code, nil
}
예제 #29
0
파일: parse.go 프로젝트: bytbox/kakapo
func readToken(r io.RuneScanner) (token, error) {
	// Tokenizer states
	const (
		READY = iota
		READING
		STRLIT
		ESCAPE
		COMMENT
	)

	// Single-rune tokens
	const TOKS = "()"
	const WS = " \t\r\n"
	const SPLIT = TOKS + WS + ";"
	const PROTECT = '\''

	state := READY
	var tmp bytes.Buffer

	ch, _, err := r.ReadRune()
	if err != nil {
		return "", err
	}
	for err == nil {
		switch state {
		case READY:
			// c either begins or is a token
			if strings.ContainsRune(TOKS, ch) {
				return token(ch), nil
			} else if strings.ContainsRune(WS, ch) {
				// whitespace; ignore it
			} else if ch == ';' {
				// read to EOL
				state = COMMENT
			} else if ch == '"' {
				tmp.WriteRune(ch)
				state = STRLIT
			} else if ch == PROTECT {
				return token(ch), nil
			} else {
				tmp.WriteRune(ch)
				state = READING
			}
		case READING:
			if strings.ContainsRune(SPLIT, ch) {
				// the current token is done
				tok := token(tmp.String())
				tmp.Reset()
				state = READY
				r.UnreadRune()
				return tok, nil
			} else {
				tmp.WriteRune(ch)
			}
		case STRLIT:
			if ch == '\\' {
				state = ESCAPE
			} else {
				tmp.WriteRune(ch)
				if ch == '"' {
					tok := token(tmp.String())
					tmp.Reset()
					state = READY
					return tok, nil
				}
			}
		case ESCAPE:
			switch ch {
			case 'n':
				tmp.WriteRune('\n')
			case 't':
				tmp.WriteRune('\t')
			default:
				panic("Invalid escape character")
			}
			state = STRLIT
		case COMMENT:
			if ch == '\n' {
				state = READY
			}
		default:
			panic("Invalid state")
		}
		ch, _, err = r.ReadRune()
	}

	if err != io.EOF {
		return "", err
	}
	switch state {
	case READY:
		return "", err
	case COMMENT:
		return "", err
	}
	panic("Unexpected EOF")
}
예제 #30
0
파일: edit.go 프로젝트: chai2010/T
func ed(rs io.RuneScanner) (Edit, error) {
	a, err := parseCompoundAddr(rs)
	switch {
	case err != nil:
		return nil, err
	case a == nil:
		switch r, _, err := rs.ReadRune(); {
		case err == io.EOF:
			return Set(Dot, '.'), nil
		case err != nil:
			return nil, err
		case r == 'u':
			n, err := parseNumber(rs)
			if err != nil {
				return nil, err
			}
			return Undo(n), nil
		case r == 'r':
			n, err := parseNumber(rs)
			if err != nil {
				return nil, err
			}
			return Redo(n), nil
		default:
			if err := rs.UnreadRune(); err != nil {
				return nil, err
			}
			a = Dot
		}
	}
	switch r, _, err := rs.ReadRune(); {
	case err == io.EOF || err == nil && r == '\n':
		return Set(a, '.'), nil
	case err != nil:
		return nil, err
	case r == 'a' || r == 'c' || r == 'i':
		text, err := parseText(rs)
		if err != nil {
			return nil, err
		}
		switch r {
		case 'a':
			return Append(a, text), nil
		case 'c':
			return Change(a, text), nil
		default: // case 'i'
			return Insert(a, text), nil
		}
	case r == 'd':
		return Delete(a), nil
	case r == 'k':
		m, err := parseMarkRune(rs)
		if err != nil {
			return nil, err
		}
		return Set(a, m), nil
	case r == 'p':
		return Print(a), nil
	case r == '=':
		switch r, _, err := rs.ReadRune(); {
		case err == io.EOF:
			return WhereLine(a), nil
		case err != nil:
			return nil, err
		case r == '#':
			return Where(a), nil
		default:
			if err := rs.UnreadRune(); err != nil {
				return nil, err
			}
			return WhereLine(a), nil
		}
	case r == 't' || r == 'm':
		a1, err := parseAddrOrDot(rs)
		if err != nil {
			return nil, err
		}
		if r == 't' {
			return Copy(a, a1), nil
		}
		return Move(a, a1), nil
	case r == 's':
		n, err := parseNumber(rs)
		if err != nil {
			return nil, err
		}
		exp, err := parseRegexp2(rs)
		if err != nil {
			return nil, err
		}
		if len(exp) < 2 || len(exp) == 2 && exp[0] == exp[1] {
			// len==1 is just the open delim.
			// len==2 && exp[0]==exp[1] is just open and close delim.
			return nil, errors.New("missing pattern")
		}
		repl, err := parseDelimited(exp[0], rs)
		if err != nil {
			return nil, err
		}
		sub := Substitute{
			A:    a,
			RE:   string(exp),
			With: string(repl),
			From: n,
		}
		switch r, _, err := rs.ReadRune(); {
		case err == io.EOF:
			return sub, nil
		case err != nil:
			return nil, err
		case r == 'g':
			sub.Global = true
		default:
			if err := rs.UnreadRune(); err != nil {
				return nil, err
			}
		}
		return sub, nil
	case r == '|' || r == '>' || r == '<':
		c, err := parseCmd(rs)
		if err != nil {
			return nil, err
		}
		switch r {
		case '|':
			return Pipe(a, c), nil
		case '>':
			return PipeTo(a, c), nil
		default: // case '<'
			return PipeFrom(a, c), nil
		}
	default:
		return nil, errors.New("unknown command: " + string(r))
	}
}