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