github.com/nicgrayson/terraform@v0.4.3-0.20150415203910-c4de50829380/config/lang/y.go (about) 1 //line lang.y:6 2 package lang 3 4 import __yyfmt__ "fmt" 5 6 //line lang.y:6 7 import ( 8 "github.com/hashicorp/terraform/config/lang/ast" 9 ) 10 11 //line lang.y:14 12 type parserSymType struct { 13 yys int 14 node ast.Node 15 nodeList []ast.Node 16 str string 17 token *parserToken 18 } 19 20 const PROGRAM_BRACKET_LEFT = 57346 21 const PROGRAM_BRACKET_RIGHT = 57347 22 const PROGRAM_STRING_START = 57348 23 const PROGRAM_STRING_END = 57349 24 const PAREN_LEFT = 57350 25 const PAREN_RIGHT = 57351 26 const COMMA = 57352 27 const ARITH_OP = 57353 28 const IDENTIFIER = 57354 29 const INTEGER = 57355 30 const FLOAT = 57356 31 const STRING = 57357 32 33 var parserToknames = []string{ 34 "PROGRAM_BRACKET_LEFT", 35 "PROGRAM_BRACKET_RIGHT", 36 "PROGRAM_STRING_START", 37 "PROGRAM_STRING_END", 38 "PAREN_LEFT", 39 "PAREN_RIGHT", 40 "COMMA", 41 "ARITH_OP", 42 "IDENTIFIER", 43 "INTEGER", 44 "FLOAT", 45 "STRING", 46 } 47 var parserStatenames = []string{} 48 49 const parserEofCode = 1 50 const parserErrCode = 2 51 const parserMaxDepth = 200 52 53 //line lang.y:165 54 55 //line yacctab:1 56 var parserExca = []int{ 57 -1, 1, 58 1, -1, 59 -2, 0, 60 } 61 62 const parserNprod = 19 63 const parserPrivate = 57344 64 65 var parserTokenNames []string 66 var parserStates []string 67 68 const parserLast = 30 69 70 var parserAct = []int{ 71 72 9, 20, 16, 16, 7, 7, 3, 18, 10, 8, 73 1, 17, 14, 12, 13, 6, 6, 19, 8, 22, 74 15, 23, 24, 11, 2, 25, 16, 21, 4, 5, 75 } 76 var parserPact = []int{ 77 78 1, -1000, 1, -1000, -1000, -1000, -1000, 0, -1000, 15, 79 0, 1, -1000, -1000, -1, -1000, 0, -8, 0, -1000, 80 -1000, 12, -9, -1000, 0, -9, 81 } 82 var parserPgo = []int{ 83 84 0, 0, 29, 28, 23, 6, 27, 10, 85 } 86 var parserR1 = []int{ 87 88 0, 7, 7, 4, 4, 5, 5, 2, 1, 1, 89 1, 1, 1, 1, 1, 6, 6, 6, 3, 90 } 91 var parserR2 = []int{ 92 93 0, 0, 1, 1, 2, 1, 1, 3, 3, 1, 94 1, 1, 3, 1, 4, 0, 3, 1, 1, 95 } 96 var parserChk = []int{ 97 98 -1000, -7, -4, -5, -3, -2, 15, 4, -5, -1, 99 8, -4, 13, 14, 12, 5, 11, -1, 8, -1, 100 9, -6, -1, 9, 10, -1, 101 } 102 var parserDef = []int{ 103 104 1, -2, 2, 3, 5, 6, 18, 0, 4, 0, 105 0, 9, 10, 11, 13, 7, 0, 0, 15, 12, 106 8, 0, 17, 14, 0, 16, 107 } 108 var parserTok1 = []int{ 109 110 1, 111 } 112 var parserTok2 = []int{ 113 114 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 115 12, 13, 14, 15, 116 } 117 var parserTok3 = []int{ 118 0, 119 } 120 121 //line yaccpar:1 122 123 /* parser for yacc output */ 124 125 var parserDebug = 0 126 127 type parserLexer interface { 128 Lex(lval *parserSymType) int 129 Error(s string) 130 } 131 132 const parserFlag = -1000 133 134 func parserTokname(c int) string { 135 // 4 is TOKSTART above 136 if c >= 4 && c-4 < len(parserToknames) { 137 if parserToknames[c-4] != "" { 138 return parserToknames[c-4] 139 } 140 } 141 return __yyfmt__.Sprintf("tok-%v", c) 142 } 143 144 func parserStatname(s int) string { 145 if s >= 0 && s < len(parserStatenames) { 146 if parserStatenames[s] != "" { 147 return parserStatenames[s] 148 } 149 } 150 return __yyfmt__.Sprintf("state-%v", s) 151 } 152 153 func parserlex1(lex parserLexer, lval *parserSymType) int { 154 c := 0 155 char := lex.Lex(lval) 156 if char <= 0 { 157 c = parserTok1[0] 158 goto out 159 } 160 if char < len(parserTok1) { 161 c = parserTok1[char] 162 goto out 163 } 164 if char >= parserPrivate { 165 if char < parserPrivate+len(parserTok2) { 166 c = parserTok2[char-parserPrivate] 167 goto out 168 } 169 } 170 for i := 0; i < len(parserTok3); i += 2 { 171 c = parserTok3[i+0] 172 if c == char { 173 c = parserTok3[i+1] 174 goto out 175 } 176 } 177 178 out: 179 if c == 0 { 180 c = parserTok2[1] /* unknown char */ 181 } 182 if parserDebug >= 3 { 183 __yyfmt__.Printf("lex %s(%d)\n", parserTokname(c), uint(char)) 184 } 185 return c 186 } 187 188 func parserParse(parserlex parserLexer) int { 189 var parsern int 190 var parserlval parserSymType 191 var parserVAL parserSymType 192 parserS := make([]parserSymType, parserMaxDepth) 193 194 Nerrs := 0 /* number of errors */ 195 Errflag := 0 /* error recovery flag */ 196 parserstate := 0 197 parserchar := -1 198 parserp := -1 199 goto parserstack 200 201 ret0: 202 return 0 203 204 ret1: 205 return 1 206 207 parserstack: 208 /* put a state and value onto the stack */ 209 if parserDebug >= 4 { 210 __yyfmt__.Printf("char %v in %v\n", parserTokname(parserchar), parserStatname(parserstate)) 211 } 212 213 parserp++ 214 if parserp >= len(parserS) { 215 nyys := make([]parserSymType, len(parserS)*2) 216 copy(nyys, parserS) 217 parserS = nyys 218 } 219 parserS[parserp] = parserVAL 220 parserS[parserp].yys = parserstate 221 222 parsernewstate: 223 parsern = parserPact[parserstate] 224 if parsern <= parserFlag { 225 goto parserdefault /* simple state */ 226 } 227 if parserchar < 0 { 228 parserchar = parserlex1(parserlex, &parserlval) 229 } 230 parsern += parserchar 231 if parsern < 0 || parsern >= parserLast { 232 goto parserdefault 233 } 234 parsern = parserAct[parsern] 235 if parserChk[parsern] == parserchar { /* valid shift */ 236 parserchar = -1 237 parserVAL = parserlval 238 parserstate = parsern 239 if Errflag > 0 { 240 Errflag-- 241 } 242 goto parserstack 243 } 244 245 parserdefault: 246 /* default state action */ 247 parsern = parserDef[parserstate] 248 if parsern == -2 { 249 if parserchar < 0 { 250 parserchar = parserlex1(parserlex, &parserlval) 251 } 252 253 /* look through exception table */ 254 xi := 0 255 for { 256 if parserExca[xi+0] == -1 && parserExca[xi+1] == parserstate { 257 break 258 } 259 xi += 2 260 } 261 for xi += 2; ; xi += 2 { 262 parsern = parserExca[xi+0] 263 if parsern < 0 || parsern == parserchar { 264 break 265 } 266 } 267 parsern = parserExca[xi+1] 268 if parsern < 0 { 269 goto ret0 270 } 271 } 272 if parsern == 0 { 273 /* error ... attempt to resume parsing */ 274 switch Errflag { 275 case 0: /* brand new error */ 276 parserlex.Error("syntax error") 277 Nerrs++ 278 if parserDebug >= 1 { 279 __yyfmt__.Printf("%s", parserStatname(parserstate)) 280 __yyfmt__.Printf(" saw %s\n", parserTokname(parserchar)) 281 } 282 fallthrough 283 284 case 1, 2: /* incompletely recovered error ... try again */ 285 Errflag = 3 286 287 /* find a state where "error" is a legal shift action */ 288 for parserp >= 0 { 289 parsern = parserPact[parserS[parserp].yys] + parserErrCode 290 if parsern >= 0 && parsern < parserLast { 291 parserstate = parserAct[parsern] /* simulate a shift of "error" */ 292 if parserChk[parserstate] == parserErrCode { 293 goto parserstack 294 } 295 } 296 297 /* the current p has no shift on "error", pop stack */ 298 if parserDebug >= 2 { 299 __yyfmt__.Printf("error recovery pops state %d\n", parserS[parserp].yys) 300 } 301 parserp-- 302 } 303 /* there is no state on the stack with an error shift ... abort */ 304 goto ret1 305 306 case 3: /* no shift yet; clobber input char */ 307 if parserDebug >= 2 { 308 __yyfmt__.Printf("error recovery discards %s\n", parserTokname(parserchar)) 309 } 310 if parserchar == parserEofCode { 311 goto ret1 312 } 313 parserchar = -1 314 goto parsernewstate /* try again in the same state */ 315 } 316 } 317 318 /* reduction by production parsern */ 319 if parserDebug >= 2 { 320 __yyfmt__.Printf("reduce %v in:\n\t%v\n", parsern, parserStatname(parserstate)) 321 } 322 323 parsernt := parsern 324 parserpt := parserp 325 _ = parserpt // guard against "declared and not used" 326 327 parserp -= parserR2[parsern] 328 parserVAL = parserS[parserp+1] 329 330 /* consult goto table to find next state */ 331 parsern = parserR1[parsern] 332 parserg := parserPgo[parsern] 333 parserj := parserg + parserS[parserp].yys + 1 334 335 if parserj >= parserLast { 336 parserstate = parserAct[parserg] 337 } else { 338 parserstate = parserAct[parserj] 339 if parserChk[parserstate] != -parsern { 340 parserstate = parserAct[parserg] 341 } 342 } 343 // dummy call; replaced with literal code 344 switch parsernt { 345 346 case 1: 347 //line lang.y:35 348 { 349 parserResult = &ast.LiteralNode{ 350 Value: "", 351 Typex: ast.TypeString, 352 Posx: ast.Pos{Column: 1, Line: 1}, 353 } 354 } 355 case 2: 356 //line lang.y:43 357 { 358 parserResult = parserS[parserpt-0].node 359 360 // We want to make sure that the top value is always a Concat 361 // so that the return value is always a string type from an 362 // interpolation. 363 // 364 // The logic for checking for a LiteralNode is a little annoying 365 // because functionally the AST is the same, but we do that because 366 // it makes for an easy literal check later (to check if a string 367 // has any interpolations). 368 if _, ok := parserS[parserpt-0].node.(*ast.Concat); !ok { 369 if n, ok := parserS[parserpt-0].node.(*ast.LiteralNode); !ok || n.Typex != ast.TypeString { 370 parserResult = &ast.Concat{ 371 Exprs: []ast.Node{parserS[parserpt-0].node}, 372 Posx: parserS[parserpt-0].node.Pos(), 373 } 374 } 375 } 376 } 377 case 3: 378 //line lang.y:66 379 { 380 parserVAL.node = parserS[parserpt-0].node 381 } 382 case 4: 383 //line lang.y:70 384 { 385 var result []ast.Node 386 if c, ok := parserS[parserpt-1].node.(*ast.Concat); ok { 387 result = append(c.Exprs, parserS[parserpt-0].node) 388 } else { 389 result = []ast.Node{parserS[parserpt-1].node, parserS[parserpt-0].node} 390 } 391 392 parserVAL.node = &ast.Concat{ 393 Exprs: result, 394 Posx: result[0].Pos(), 395 } 396 } 397 case 5: 398 //line lang.y:86 399 { 400 parserVAL.node = parserS[parserpt-0].node 401 } 402 case 6: 403 //line lang.y:90 404 { 405 parserVAL.node = parserS[parserpt-0].node 406 } 407 case 7: 408 //line lang.y:96 409 { 410 parserVAL.node = parserS[parserpt-1].node 411 } 412 case 8: 413 //line lang.y:102 414 { 415 parserVAL.node = parserS[parserpt-1].node 416 } 417 case 9: 418 //line lang.y:106 419 { 420 parserVAL.node = parserS[parserpt-0].node 421 } 422 case 10: 423 //line lang.y:110 424 { 425 parserVAL.node = &ast.LiteralNode{ 426 Value: parserS[parserpt-0].token.Value.(int), 427 Typex: ast.TypeInt, 428 Posx: parserS[parserpt-0].token.Pos, 429 } 430 } 431 case 11: 432 //line lang.y:118 433 { 434 parserVAL.node = &ast.LiteralNode{ 435 Value: parserS[parserpt-0].token.Value.(float64), 436 Typex: ast.TypeFloat, 437 Posx: parserS[parserpt-0].token.Pos, 438 } 439 } 440 case 12: 441 //line lang.y:126 442 { 443 parserVAL.node = &ast.Arithmetic{ 444 Op: parserS[parserpt-1].token.Value.(ast.ArithmeticOp), 445 Exprs: []ast.Node{parserS[parserpt-2].node, parserS[parserpt-0].node}, 446 Posx: parserS[parserpt-2].node.Pos(), 447 } 448 } 449 case 13: 450 //line lang.y:134 451 { 452 parserVAL.node = &ast.VariableAccess{Name: parserS[parserpt-0].token.Value.(string), Posx: parserS[parserpt-0].token.Pos} 453 } 454 case 14: 455 //line lang.y:138 456 { 457 parserVAL.node = &ast.Call{Func: parserS[parserpt-3].token.Value.(string), Args: parserS[parserpt-1].nodeList, Posx: parserS[parserpt-3].token.Pos} 458 } 459 case 15: 460 //line lang.y:143 461 { 462 parserVAL.nodeList = nil 463 } 464 case 16: 465 //line lang.y:147 466 { 467 parserVAL.nodeList = append(parserS[parserpt-2].nodeList, parserS[parserpt-0].node) 468 } 469 case 17: 470 //line lang.y:151 471 { 472 parserVAL.nodeList = append(parserVAL.nodeList, parserS[parserpt-0].node) 473 } 474 case 18: 475 //line lang.y:157 476 { 477 parserVAL.node = &ast.LiteralNode{ 478 Value: parserS[parserpt-0].token.Value.(string), 479 Typex: ast.TypeString, 480 Posx: parserS[parserpt-0].token.Pos, 481 } 482 } 483 } 484 goto parserstack /* stack new state and value */ 485 }