Home | History | Annotate | Download | only in syntax
      1 // Copyright 2016 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package syntax
      6 
      7 import "fmt"
      8 
      9 type token uint
     10 
     11 const (
     12 	_ token = iota
     13 	_EOF
     14 
     15 	// names and literals
     16 	_Name
     17 	_Literal
     18 
     19 	// operators and operations
     20 	_Operator // excluding '*' (_Star)
     21 	_AssignOp
     22 	_IncOp
     23 	_Assign
     24 	_Define
     25 	_Arrow
     26 	_Star
     27 
     28 	// delimiters
     29 	_Lparen
     30 	_Lbrack
     31 	_Lbrace
     32 	_Rparen
     33 	_Rbrack
     34 	_Rbrace
     35 	_Comma
     36 	_Semi
     37 	_Colon
     38 	_Dot
     39 	_DotDotDot
     40 
     41 	// keywords
     42 	_Break
     43 	_Case
     44 	_Chan
     45 	_Const
     46 	_Continue
     47 	_Default
     48 	_Defer
     49 	_Else
     50 	_Fallthrough
     51 	_For
     52 	_Func
     53 	_Go
     54 	_Goto
     55 	_If
     56 	_Import
     57 	_Interface
     58 	_Map
     59 	_Package
     60 	_Range
     61 	_Return
     62 	_Select
     63 	_Struct
     64 	_Switch
     65 	_Type
     66 	_Var
     67 
     68 	tokenCount
     69 )
     70 
     71 const (
     72 	// for BranchStmt
     73 	Break       = _Break
     74 	Continue    = _Continue
     75 	Fallthrough = _Fallthrough
     76 	Goto        = _Goto
     77 
     78 	// for CallStmt
     79 	Go    = _Go
     80 	Defer = _Defer
     81 )
     82 
     83 var tokstrings = [...]string{
     84 	// source control
     85 	_EOF: "EOF",
     86 
     87 	// names and literals
     88 	_Name:    "name",
     89 	_Literal: "literal",
     90 
     91 	// operators and operations
     92 	_Operator: "op",
     93 	_AssignOp: "op=",
     94 	_IncOp:    "opop",
     95 	_Assign:   "=",
     96 	_Define:   ":=",
     97 	_Arrow:    "<-",
     98 	_Star:     "*",
     99 
    100 	// delimiters
    101 	_Lparen:    "(",
    102 	_Lbrack:    "[",
    103 	_Lbrace:    "{",
    104 	_Rparen:    ")",
    105 	_Rbrack:    "]",
    106 	_Rbrace:    "}",
    107 	_Comma:     ",",
    108 	_Semi:      ";",
    109 	_Colon:     ":",
    110 	_Dot:       ".",
    111 	_DotDotDot: "...",
    112 
    113 	// keywords
    114 	_Break:       "break",
    115 	_Case:        "case",
    116 	_Chan:        "chan",
    117 	_Const:       "const",
    118 	_Continue:    "continue",
    119 	_Default:     "default",
    120 	_Defer:       "defer",
    121 	_Else:        "else",
    122 	_Fallthrough: "fallthrough",
    123 	_For:         "for",
    124 	_Func:        "func",
    125 	_Go:          "go",
    126 	_Goto:        "goto",
    127 	_If:          "if",
    128 	_Import:      "import",
    129 	_Interface:   "interface",
    130 	_Map:         "map",
    131 	_Package:     "package",
    132 	_Range:       "range",
    133 	_Return:      "return",
    134 	_Select:      "select",
    135 	_Struct:      "struct",
    136 	_Switch:      "switch",
    137 	_Type:        "type",
    138 	_Var:         "var",
    139 }
    140 
    141 func (tok token) String() string {
    142 	var s string
    143 	if 0 <= tok && int(tok) < len(tokstrings) {
    144 		s = tokstrings[tok]
    145 	}
    146 	if s == "" {
    147 		s = fmt.Sprintf("<tok-%d>", tok)
    148 	}
    149 	return s
    150 }
    151 
    152 // Make sure we have at most 64 tokens so we can use them in a set.
    153 const _ uint64 = 1 << (tokenCount - 1)
    154 
    155 // contains reports whether tok is in tokset.
    156 func contains(tokset uint64, tok token) bool {
    157 	return tokset&(1<<tok) != 0
    158 }
    159 
    160 type LitKind uint
    161 
    162 const (
    163 	IntLit LitKind = iota
    164 	FloatLit
    165 	ImagLit
    166 	RuneLit
    167 	StringLit
    168 )
    169 
    170 type Operator uint
    171 
    172 const (
    173 	_    Operator = iota
    174 	Def           // :=
    175 	Not           // !
    176 	Recv          // <-
    177 
    178 	// precOrOr
    179 	OrOr // ||
    180 
    181 	// precAndAnd
    182 	AndAnd // &&
    183 
    184 	// precCmp
    185 	Eql // ==
    186 	Neq // !=
    187 	Lss // <
    188 	Leq // <=
    189 	Gtr // >
    190 	Geq // >=
    191 
    192 	// precAdd
    193 	Add // +
    194 	Sub // -
    195 	Or  // |
    196 	Xor // ^
    197 
    198 	// precMul
    199 	Mul    // *
    200 	Div    // /
    201 	Rem    // %
    202 	And    // &
    203 	AndNot // &^
    204 	Shl    // <<
    205 	Shr    // >>
    206 )
    207 
    208 var opstrings = [...]string{
    209 	// prec == 0
    210 	Def:  ":", // : in :=
    211 	Not:  "!",
    212 	Recv: "<-",
    213 
    214 	// precOrOr
    215 	OrOr: "||",
    216 
    217 	// precAndAnd
    218 	AndAnd: "&&",
    219 
    220 	// precCmp
    221 	Eql: "==",
    222 	Neq: "!=",
    223 	Lss: "<",
    224 	Leq: "<=",
    225 	Gtr: ">",
    226 	Geq: ">=",
    227 
    228 	// precAdd
    229 	Add: "+",
    230 	Sub: "-",
    231 	Or:  "|",
    232 	Xor: "^",
    233 
    234 	// precMul
    235 	Mul:    "*",
    236 	Div:    "/",
    237 	Rem:    "%",
    238 	And:    "&",
    239 	AndNot: "&^",
    240 	Shl:    "<<",
    241 	Shr:    ">>",
    242 }
    243 
    244 func (op Operator) String() string {
    245 	var s string
    246 	if 0 <= op && int(op) < len(opstrings) {
    247 		s = opstrings[op]
    248 	}
    249 	if s == "" {
    250 		s = fmt.Sprintf("<op-%d>", op)
    251 	}
    252 	return s
    253 }
    254 
    255 // Operator precedences
    256 const (
    257 	_ = iota
    258 	precOrOr
    259 	precAndAnd
    260 	precCmp
    261 	precAdd
    262 	precMul
    263 )
    264