github.com/jingcheng-WU/gonum@v0.9.1-0.20210323123734-f1a2a11a8f7b/graph/formats/dot/internal/util/litconv.go (about)

     1  // Code generated by gocc; DO NOT EDIT.
     2  
     3  // This file is dual licensed under CC0 and The Gonum License.
     4  //
     5  // Copyright ©2017 The Gonum Authors. All rights reserved.
     6  // Use of this source code is governed by a BSD-style
     7  // license that can be found in the LICENSE file.
     8  //
     9  // Copyright ©2017 Robin Eklind.
    10  // This file is made available under a Creative Commons CC0 1.0
    11  // Universal Public Domain Dedication.
    12  
    13  package util
    14  
    15  import (
    16  	"fmt"
    17  	"strconv"
    18  	"unicode"
    19  	"unicode/utf8"
    20  )
    21  
    22  /* Interface */
    23  
    24  /*
    25  Convert the literal value of a scanned token to rune
    26  */
    27  func RuneValue(lit []byte) rune {
    28  	if lit[1] == '\\' {
    29  		return escapeCharVal(lit)
    30  	}
    31  	r, size := utf8.DecodeRune(lit[1:])
    32  	if size != len(lit)-2 {
    33  		panic(fmt.Sprintf("Error decoding rune. Lit: %s, rune: %d, size%d\n", lit, r, size))
    34  	}
    35  	return r
    36  }
    37  
    38  /*
    39  Convert the literal value of a scanned token to int64
    40  */
    41  func IntValue(lit []byte) (int64, error) {
    42  	return strconv.ParseInt(string(lit), 10, 64)
    43  }
    44  
    45  /*
    46  Convert the literal value of a scanned token to uint64
    47  */
    48  func UintValue(lit []byte) (uint64, error) {
    49  	return strconv.ParseUint(string(lit), 10, 64)
    50  }
    51  
    52  /* Util */
    53  
    54  func escapeCharVal(lit []byte) rune {
    55  	var i, base, max uint32
    56  	offset := 2
    57  	switch lit[offset] {
    58  	case 'a':
    59  		return '\a'
    60  	case 'b':
    61  		return '\b'
    62  	case 'f':
    63  		return '\f'
    64  	case 'n':
    65  		return '\n'
    66  	case 'r':
    67  		return '\r'
    68  	case 't':
    69  		return '\t'
    70  	case 'v':
    71  		return '\v'
    72  	case '\\':
    73  		return '\\'
    74  	case '\'':
    75  		return '\''
    76  	case '0', '1', '2', '3', '4', '5', '6', '7':
    77  		i, base, max = 3, 8, 255
    78  	case 'x':
    79  		i, base, max = 2, 16, 255
    80  		offset++
    81  	case 'u':
    82  		i, base, max = 4, 16, unicode.MaxRune
    83  		offset++
    84  	case 'U':
    85  		i, base, max = 8, 16, unicode.MaxRune
    86  		offset++
    87  	default:
    88  		panic(fmt.Sprintf("Error decoding character literal: %s\n", lit))
    89  	}
    90  
    91  	var x uint32
    92  	for ; i > 0 && offset < len(lit)-1; i-- {
    93  		ch, size := utf8.DecodeRune(lit[offset:])
    94  		offset += size
    95  		d := uint32(digitVal(ch))
    96  		if d >= base {
    97  			panic(fmt.Sprintf("charVal(%s): illegal character (%c) in escape sequence. size=%d, offset=%d", lit, ch, size, offset))
    98  		}
    99  		x = x*base + d
   100  	}
   101  	if x > max || 0xD800 <= x && x < 0xE000 {
   102  		panic(fmt.Sprintf("Error decoding escape char value. Lit:%s, offset:%d, escape sequence is invalid Unicode code point\n", lit, offset))
   103  	}
   104  
   105  	return rune(x)
   106  }
   107  
   108  func digitVal(ch rune) int {
   109  	switch {
   110  	case '0' <= ch && ch <= '9':
   111  		return int(ch) - '0'
   112  	case 'a' <= ch && ch <= 'f':
   113  		return int(ch) - 'a' + 10
   114  	case 'A' <= ch && ch <= 'F':
   115  		return int(ch) - 'A' + 10
   116  	}
   117  	return 16 // larger than any legal digit val
   118  }