PageRenderTime 59ms CodeModel.GetById 22ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/ruby19_parser.y

http://github.com/seattlerb/ruby_parser
Happy | 2109 lines | 1928 code | 181 blank | 0 comment | 0 complexity | 64755356cca7bf45ee95c3dd24797246 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1# -*- racc -*-
   2
   3class Ruby19Parser
   4
   5token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
   6      kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
   7      kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
   8      kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
   9      kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
  10      k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
  11      tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
  12      tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ
  13      tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF
  14      tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN
  15      tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE
  16      tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE
  17      tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY
  18      tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
  19      tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
  20      tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAST_TOKEN
  21      tLAMBDA tLAMBEG
  22
  23prechigh
  24  right    tBANG tTILDE tUPLUS
  25  right    tPOW
  26  right    tUMINUS_NUM tUMINUS
  27  left     tSTAR2 tDIVIDE tPERCENT
  28  left     tPLUS tMINUS
  29  left     tLSHFT tRSHFT
  30  left     tAMPER2
  31  left     tPIPE tCARET
  32  left     tGT tGEQ tLT tLEQ
  33  nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
  34  left     tANDOP
  35  left     tOROP
  36  nonassoc tDOT2 tDOT3
  37  right    tEH tCOLON
  38  left     kRESCUE_MOD
  39  right    tEQL tOP_ASGN
  40  nonassoc kDEFINED
  41  right    kNOT
  42  left     kOR kAND
  43  nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
  44  nonassoc tLBRACE_ARG
  45  nonassoc tLOWEST
  46preclow
  47
  48rule
  49
  50         program:   {
  51                      self.lexer.lex_state = :expr_beg
  52                    }
  53                    top_compstmt
  54                    {
  55                      result = new_compstmt val
  56                    }
  57
  58    top_compstmt: top_stmts opt_terms
  59                    {
  60                      result = val[0]
  61                    }
  62
  63       top_stmts: none
  64                | top_stmt
  65                | top_stmts terms top_stmt
  66                    {
  67                      result = self.block_append val[0], val[2]
  68                    }
  69                | error top_stmt
  70
  71        top_stmt: stmt
  72                | klBEGIN
  73                    {
  74                      if (self.in_def || self.in_single > 0) then
  75                        yyerror "BEGIN in method"
  76                      end
  77                      self.env.extend
  78                    }
  79                    tLCURLY top_compstmt tRCURLY
  80                    {
  81                      result = new_iter s(:preexe), nil, val[3]
  82                    }
  83
  84        bodystmt: compstmt opt_rescue opt_else opt_ensure
  85                    {
  86                      result = new_body val
  87                    }
  88
  89        compstmt: stmts opt_terms
  90                    {
  91                      result = new_compstmt val
  92                    }
  93
  94           stmts: none
  95                | stmt
  96                | stmts terms stmt
  97                    {
  98                      result = self.block_append val[0], val[2]
  99                    }
 100                | error stmt
 101                    {
 102                      result = val[1]
 103                    }
 104
 105            stmt: kALIAS fitem
 106                    {
 107                      lexer.lex_state = :expr_fname
 108                      result = self.lexer.lineno
 109                    }
 110                    fitem
 111                    {
 112                      result = s(:alias, val[1], val[3]).line(val[2])
 113                    }
 114                | kALIAS tGVAR tGVAR
 115                    {
 116                      result = s(:valias, val[1].to_sym, val[2].to_sym)
 117                    }
 118                | kALIAS tGVAR tBACK_REF
 119                    {
 120                      result = s(:valias, val[1].to_sym, :"$#{val[2]}")
 121                    }
 122                | kALIAS tGVAR tNTH_REF
 123                    {
 124                      yyerror "can't make alias for the number variables"
 125                    }
 126                | kUNDEF undef_list
 127                    {
 128                      result = val[1]
 129                    }
 130                | stmt kIF_MOD expr_value
 131                    {
 132                      result = new_if val[2], val[0], nil
 133                    }
 134                | stmt kUNLESS_MOD expr_value
 135                    {
 136                      result = new_if val[2], nil, val[0]
 137                    }
 138                | stmt kWHILE_MOD expr_value
 139                    {
 140                      result = new_while val[0], val[2], true
 141                    }
 142                | stmt kUNTIL_MOD expr_value
 143                    {
 144                      result = new_until val[0], val[2], true
 145                    }
 146                | stmt kRESCUE_MOD stmt
 147                    {
 148                      result = s(:rescue, val[0], new_resbody(s(:array), val[2]))
 149                    }
 150                | klEND tLCURLY compstmt tRCURLY
 151                    {
 152                      if (self.in_def || self.in_single > 0) then
 153                        yyerror "END in method; use at_exit"
 154                      end
 155                      result = new_iter s(:postexe), nil, val[2]
 156                    }
 157                | command_asgn
 158                | mlhs tEQL command_call
 159                    {
 160                      result = new_masgn val[0], val[2], :wrap
 161                    }
 162                | var_lhs tOP_ASGN command_call
 163                    {
 164                      result = new_op_asgn val
 165                    }
 166                | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_call
 167                    {
 168                      result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
 169                    }
 170                | primary_value tDOT tIDENTIFIER tOP_ASGN command_call
 171                    {
 172                      result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
 173                    }
 174                | primary_value tDOT tCONSTANT tOP_ASGN command_call
 175                    {
 176                      result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
 177                    }
 178                | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
 179                    {
 180                      result = s(:op_asgn, val[0], val[4], val[2], val[3])
 181                    }
 182                | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
 183                    {
 184                      result = s(:op_asgn, val[0], val[4], val[2], val[3])
 185                    }
 186                | backref tOP_ASGN command_call
 187                    {
 188                      self.backref_assign_error val[0]
 189                    }
 190                | lhs tEQL mrhs
 191                    {
 192                      result = self.node_assign val[0], s(:svalue, val[2])
 193                    }
 194                | mlhs tEQL arg_value
 195                    {
 196                      result = new_masgn val[0], val[2], :wrap
 197                    }
 198                | mlhs tEQL mrhs
 199                    {
 200                      result = new_masgn val[0], val[2]
 201                    }
 202                | expr
 203
 204    command_asgn: lhs tEQL command_call
 205                    {
 206                      result = self.node_assign val[0], val[2]
 207                    }
 208                | lhs tEQL command_asgn
 209                    {
 210                      result = self.node_assign val[0], val[2]
 211                    }
 212
 213            expr: command_call
 214                | expr kAND expr
 215                    {
 216                      result = logop(:and, val[0], val[2])
 217                    }
 218                | expr kOR expr
 219                    {
 220                      result = logop(:or, val[0], val[2])
 221                    }
 222                | kNOT opt_nl expr
 223                    {
 224                      result = s(:call, val[2], :"!")
 225                    }
 226                | tBANG command_call
 227                    {
 228                      result = s(:call, val[1], :"!")
 229                    }
 230                | arg
 231
 232      expr_value: expr
 233                    {
 234                      result = value_expr(val[0])
 235                    }
 236
 237    command_call: command
 238                | block_command
 239
 240   block_command: block_call
 241                | block_call tDOT operation2 command_args # TODO: dot_or_colon
 242                    {
 243                      result = new_call val[0], val[2].to_sym, val[3]
 244                    }
 245                | block_call tCOLON2 operation2 command_args
 246                    {
 247                      result = new_call val[0], val[2].to_sym, val[3]
 248                    }
 249
 250 cmd_brace_block: tLBRACE_ARG
 251                    {
 252                      self.env.extend(:dynamic)
 253                      result = self.lexer.lineno
 254                    }
 255                    opt_block_param
 256                    {
 257                      result = nil # self.env.dynamic.keys
 258                    }
 259                    compstmt tRCURLY
 260                    {
 261                      result = new_iter nil, val[2], val[4]
 262                      result.line = val[1]
 263
 264                      self.env.unextend
 265                    }
 266
 267         command: operation command_args =tLOWEST
 268                    {
 269                      result = new_call nil, val[0].to_sym, val[1]
 270                    }
 271                | operation command_args cmd_brace_block
 272                    {
 273                      result = new_call nil, val[0].to_sym, val[1]
 274                      if val[2] then
 275                        block_dup_check result, val[2]
 276
 277                        result, operation = val[2], result
 278                        result.insert 1, operation
 279                      end
 280                    }
 281                | primary_value tDOT operation2 command_args =tLOWEST
 282                    {
 283                      result = new_call val[0], val[2].to_sym, val[3]
 284                    }
 285                | primary_value tDOT operation2 command_args cmd_brace_block
 286                    {
 287                      recv, _, msg, args, block = val
 288                      call = new_call recv, msg.to_sym, args
 289
 290                      block_dup_check call, block
 291
 292                      block.insert 1, call
 293                      result = block
 294                    }
 295                | primary_value tCOLON2 operation2 command_args =tLOWEST
 296                    {
 297                      result = new_call val[0], val[2].to_sym, val[3]
 298                    }
 299                | primary_value tCOLON2 operation2 command_args cmd_brace_block
 300                    {
 301                      recv, _, msg, args, block = val
 302                      call = new_call recv, msg.to_sym, args
 303
 304                      block_dup_check call, block
 305
 306                      block.insert 1, call
 307                      result = block
 308                    }
 309                | kSUPER command_args
 310                    {
 311                      result = new_super val[1]
 312                    }
 313                | kYIELD command_args
 314                    {
 315                      result = new_yield val[1]
 316                    }
 317                | kRETURN call_args
 318                    {
 319                      line = val[0].last
 320                      result = s(:return, ret_args(val[1])).line(line)
 321                    }
 322                | kBREAK call_args
 323                    {
 324                      line = val[0].last
 325                      result = s(:break, ret_args(val[1])).line(line)
 326                    }
 327                | kNEXT call_args
 328                    {
 329                      line = val[0].last
 330                      result = s(:next, ret_args(val[1])).line(line)
 331                    }
 332
 333            mlhs: mlhs_basic
 334                | tLPAREN mlhs_inner rparen
 335                    {
 336                      result = val[1]
 337                    }
 338
 339      mlhs_inner: mlhs_basic
 340                | tLPAREN mlhs_inner rparen
 341                    {
 342                      result = s(:masgn, s(:array, val[1]))
 343                    }
 344
 345      mlhs_basic: mlhs_head
 346                    {
 347                      result = s(:masgn, val[0])
 348                    }
 349                | mlhs_head mlhs_item
 350                    {
 351                      result = s(:masgn, val[0] << val[1].compact)
 352                    }
 353                | mlhs_head tSTAR mlhs_node
 354                    {
 355                      result = s(:masgn, val[0] << s(:splat, val[2]))
 356                    }
 357                | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
 358                    {
 359                      ary = list_append val[0], s(:splat, val[2])
 360                      ary.concat val[4][1..-1]
 361                      result = s(:masgn, ary)
 362                    }
 363                | mlhs_head tSTAR
 364                    {
 365                      result = s(:masgn, val[0] << s(:splat))
 366                    }
 367                | mlhs_head tSTAR tCOMMA mlhs_post
 368                    {
 369                      ary = list_append val[0], s(:splat)
 370                      ary.concat val[3][1..-1]
 371                      result = s(:masgn, ary)
 372                    }
 373                | tSTAR mlhs_node
 374                    {
 375                      result = s(:masgn, s(:array, s(:splat, val[1])))
 376                    }
 377                | tSTAR mlhs_node tCOMMA mlhs_post
 378                    {
 379                      ary = s(:array, s(:splat, val[1]))
 380                      ary.concat val[3][1..-1]
 381                      result = s(:masgn, ary)
 382                    }
 383                | tSTAR
 384                    {
 385                      result = s(:masgn, s(:array, s(:splat)))
 386                    }
 387                | tSTAR tCOMMA mlhs_post
 388                    {
 389                      ary = s(:array, s(:splat))
 390                      ary.concat val[2][1..-1]
 391                      result = s(:masgn, ary)
 392                    }
 393
 394       mlhs_item: mlhs_node
 395                | tLPAREN mlhs_inner rparen
 396                    {
 397                      result = val[1]
 398                    }
 399
 400       mlhs_head: mlhs_item tCOMMA
 401                    {
 402                      result = s(:array, val[0])
 403                    }
 404                | mlhs_head mlhs_item tCOMMA
 405                    {
 406                      result = val[0] << val[1].compact
 407                    }
 408
 409       mlhs_post: mlhs_item
 410                    {
 411                      result = s(:array, val[0])
 412                    }
 413                | mlhs_post tCOMMA mlhs_item
 414                    {
 415                      result = list_append val[0], val[2]
 416                    }
 417
 418       mlhs_node: user_variable
 419                    {
 420                      result = self.assignable val[0]
 421                    }
 422                | keyword_variable
 423                    {
 424                      result = self.assignable val[0]
 425                    }
 426                | primary_value tLBRACK2 opt_call_args rbracket
 427                    {
 428                      result = self.aryset val[0], val[2]
 429                    }
 430                | primary_value tDOT tIDENTIFIER
 431                    {
 432                      result = s(:attrasgn, val[0], :"#{val[2]}=")
 433                    }
 434                | primary_value tCOLON2 tIDENTIFIER
 435                    {
 436                      result = s(:attrasgn, val[0], :"#{val[2]}=")
 437                    }
 438                | primary_value tDOT tCONSTANT
 439                    {
 440                      result = s(:attrasgn, val[0], :"#{val[2]}=")
 441                    }
 442                | primary_value tCOLON2 tCONSTANT
 443                    {
 444                      if (self.in_def || self.in_single > 0) then
 445                        yyerror "dynamic constant assignment"
 446                      end
 447
 448                      result = s(:const, s(:colon2, val[0], val[2].to_sym), nil)
 449                    }
 450                | tCOLON3 tCONSTANT
 451                    {
 452                      if (self.in_def || self.in_single > 0) then
 453                        yyerror "dynamic constant assignment"
 454                      end
 455
 456                      result = s(:const, nil, s(:colon3, val[1].to_sym))
 457                    }
 458                | backref
 459                    {
 460                      self.backref_assign_error val[0]
 461                    }
 462
 463             lhs: user_variable
 464                    {
 465                      result = self.assignable val[0]
 466                    }
 467                | keyword_variable
 468                    {
 469                      result = self.assignable val[0]
 470                    }
 471                | primary_value tLBRACK2 opt_call_args rbracket
 472                    {
 473                      result = self.aryset val[0], val[2]
 474                    }
 475                | primary_value tDOT tIDENTIFIER
 476                    {
 477                      result = s(:attrasgn, val[0], :"#{val[2]}=")
 478                    }
 479                | primary_value tCOLON2 tIDENTIFIER
 480                    {
 481                      result = s(:attrasgn, val[0], :"#{val[2]}=")
 482                    }
 483                | primary_value tDOT tCONSTANT
 484                    {
 485                      result = s(:attrasgn, val[0], :"#{val[2]}=")
 486                    }
 487                | primary_value tCOLON2 tCONSTANT
 488                    {
 489                      if (self.in_def || self.in_single > 0) then
 490                        yyerror "dynamic constant assignment"
 491                      end
 492
 493                      result = s(:const, s(:colon2, val[0], val[2].to_sym))
 494                    }
 495                | tCOLON3 tCONSTANT
 496                    {
 497                      if (self.in_def || self.in_single > 0) then
 498                        yyerror "dynamic constant assignment"
 499                      end
 500
 501                      result = s(:const, s(:colon3, val[1].to_sym))
 502                    }
 503                | backref
 504                    {
 505                      self.backref_assign_error val[0]
 506                    }
 507
 508           cname: tIDENTIFIER
 509                    {
 510                      yyerror "class/module name must be CONSTANT"
 511                    }
 512                | tCONSTANT
 513
 514           cpath: tCOLON3 cname
 515                    {
 516                      result = s(:colon3, val[1].to_sym)
 517                    }
 518                | cname
 519                    {
 520                      result = val[0].to_sym
 521                    }
 522                | primary_value tCOLON2 cname
 523                    {
 524                      result = s(:colon2, val[0], val[2].to_sym)
 525                    }
 526
 527           fname: tIDENTIFIER | tCONSTANT | tFID
 528                | op
 529                    {
 530                      lexer.lex_state = :expr_end
 531                      result = val[0]
 532                    }
 533
 534                | reswords
 535                    {
 536                      lexer.lex_state = :expr_end
 537                      result = val[0]
 538                    }
 539
 540            fsym: fname | symbol
 541
 542           fitem: fsym { result = s(:lit, val[0].to_sym) }
 543                | dsym
 544
 545      undef_list: fitem
 546                    {
 547                      result = new_undef val[0]
 548                    }
 549                |
 550                    undef_list tCOMMA
 551                    {
 552                      lexer.lex_state = :expr_fname
 553                    }
 554                    fitem
 555                    {
 556                      result = new_undef val[0], val[3]
 557                    }
 558
 559                op: tPIPE    | tCARET  | tAMPER2  | tCMP  | tEQ     | tEQQ
 560                |   tMATCH   | tNMATCH | tGT      | tGEQ  | tLT     | tLEQ
 561                |   tNEQ     | tLSHFT  | tRSHFT   | tPLUS | tMINUS  | tSTAR2
 562                |   tSTAR    | tDIVIDE | tPERCENT | tPOW  | tBANG   | tTILDE
 563                |   tUPLUS   | tUMINUS | tAREF    | tASET | tBACK_REF2
 564
 565        reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
 566                | kALIAS    | kAND      | kBEGIN        | kBREAK  | kCASE
 567                | kCLASS    | kDEF      | kDEFINED      | kDO     | kELSE
 568                | kELSIF    | kEND      | kENSURE       | kFALSE  | kFOR
 569                | kIN       | kMODULE   | kNEXT         | kNIL    | kNOT
 570                | kOR       | kREDO     | kRESCUE       | kRETRY  | kRETURN
 571                | kSELF     | kSUPER    | kTHEN         | kTRUE   | kUNDEF
 572                | kWHEN     | kYIELD    | kIF           | kUNLESS | kWHILE
 573                | kUNTIL
 574
 575             arg: lhs tEQL arg
 576                    {
 577                      result = self.node_assign val[0], val[2]
 578                    }
 579                | lhs tEQL arg kRESCUE_MOD arg
 580                    {
 581                      result = self.node_assign val[0], s(:rescue, val[2], new_resbody(s(:array), val[4]))
 582                    }
 583                | var_lhs tOP_ASGN arg
 584                    {
 585                      result = new_op_asgn val
 586                    }
 587                | var_lhs tOP_ASGN arg kRESCUE_MOD arg
 588                    {
 589                      result = new_op_asgn val
 590                      result = s(:rescue, result, new_resbody(s(:array), val[4]))
 591                    }
 592                | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg
 593                    {
 594                      val[2][0] = :arglist if val[2]
 595                      result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
 596                    }
 597                | primary_value tDOT tIDENTIFIER tOP_ASGN arg
 598                    {
 599                      result = s(:op_asgn2, val[0], :"#{val[2]}=", val[3].to_sym, val[4])
 600                    }
 601                | primary_value tDOT tCONSTANT tOP_ASGN arg
 602                    {
 603                      result = s(:op_asgn2, val[0], :"#{val[2]}=", val[3].to_sym, val[4])
 604                    }
 605                | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
 606                    {
 607                      result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
 608                    }
 609                | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
 610                    {
 611                      yyerror "constant re-assignment"
 612                    }
 613                | tCOLON3 tCONSTANT tOP_ASGN arg
 614                    {
 615                      yyerror "constant re-assignment"
 616                    }
 617                | backref tOP_ASGN arg
 618                    {
 619                      self.backref_assign_error val[0]
 620                    }
 621                | arg tDOT2 arg
 622                    {
 623                      v1, v2 = val[0], val[2]
 624                      if v1.node_type == :lit and v2.node_type == :lit and Fixnum === v1.last and Fixnum === v2.last then
 625                        result = s(:lit, (v1.last)..(v2.last))
 626                      else
 627                        result = s(:dot2, v1, v2)
 628                      end
 629                    }
 630                | arg tDOT3 arg
 631                    {
 632                      v1, v2 = val[0], val[2]
 633                      if v1.node_type == :lit and v2.node_type == :lit and Fixnum === v1.last and Fixnum === v2.last then
 634                        result = s(:lit, (v1.last)...(v2.last))
 635                      else
 636                        result = s(:dot3, v1, v2)
 637                      end
 638                    }
 639                | arg tPLUS arg
 640                    {
 641                      result = new_call val[0], :+, argl(val[2])
 642                    }
 643                | arg tMINUS arg
 644                    {
 645                      result = new_call val[0], :-, argl(val[2])
 646                    }
 647                | arg tSTAR2 arg
 648                    {
 649                      result = new_call val[0], :*, argl(val[2])
 650                    }
 651                | arg tDIVIDE arg
 652                    {
 653                      result = new_call val[0], :"/", argl(val[2])
 654                    }
 655                | arg tPERCENT arg
 656                    {
 657                      result = new_call val[0], :"%", argl(val[2])
 658                    }
 659                | arg tPOW arg
 660                    {
 661                      result = new_call val[0], :**, argl(val[2])
 662                    }
 663                | tUMINUS_NUM tINTEGER tPOW arg
 664                    {
 665                      result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
 666                    }
 667                | tUMINUS_NUM tFLOAT tPOW arg
 668                    {
 669                      result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
 670                    }
 671                | tUPLUS arg
 672                    {
 673                      result = new_call val[1], :"+@"
 674                    }
 675                | tUMINUS arg
 676                    {
 677                      result = new_call val[1], :"-@"
 678                    }
 679                | arg tPIPE arg
 680                    {
 681                      result = new_call val[0], :"|", argl(val[2])
 682                    }
 683                | arg tCARET arg
 684                    {
 685                      result = new_call val[0], :"^", argl(val[2])
 686                    }
 687                | arg tAMPER2 arg
 688                    {
 689                      result = new_call val[0], :"&", argl(val[2])
 690                    }
 691                | arg tCMP arg
 692                    {
 693                      result = new_call val[0], :"<=>", argl(val[2])
 694                    }
 695                | arg tGT arg
 696                    {
 697                      result = new_call val[0], :">", argl(val[2])
 698                    }
 699                | arg tGEQ arg
 700                    {
 701                      result = new_call val[0], :">=", argl(val[2])
 702                    }
 703                | arg tLT arg
 704                    {
 705                      result = new_call val[0], :"<", argl(val[2])
 706                    }
 707                | arg tLEQ arg
 708                    {
 709                      result = new_call val[0], :"<=", argl(val[2])
 710                    }
 711                | arg tEQ arg
 712                    {
 713                      result = new_call val[0], :"==", argl(val[2])
 714                    }
 715                | arg tEQQ arg
 716                    {
 717                      result = new_call val[0], :"===", argl(val[2])
 718                    }
 719                | arg tNEQ arg
 720                    {
 721                      result = new_call val[0], :"!=", argl(val[2])
 722                    }
 723                | arg tMATCH arg
 724                    {
 725                      result = self.get_match_node val[0], val[2]
 726                    }
 727                | arg tNMATCH arg
 728                    {
 729                      result = s(:not, self.get_match_node(val[0], val[2]))
 730                    }
 731                | tBANG arg
 732                    {
 733                      result = new_call val[1], :"!"
 734                    }
 735                | tTILDE arg
 736                    {
 737                      val[2] = value_expr val[2]
 738                      result = new_call val[1], :"~"
 739                    }
 740                | arg tLSHFT arg
 741                    {
 742                      val[0] = value_expr val[0]
 743                      val[2] = value_expr val[2]
 744                      result = new_call val[0], :"\<\<", argl(val[2])
 745                    }
 746                | arg tRSHFT arg
 747                    {
 748                      val[0] = value_expr val[0]
 749                      val[2] = value_expr val[2]
 750                      result = new_call val[0], :">>", argl(val[2])
 751                    }
 752                | arg tANDOP arg
 753                    {
 754                      result = logop(:and, val[0], val[2])
 755                    }
 756                | arg tOROP arg
 757                    {
 758                      result = logop(:or, val[0], val[2])
 759                    }
 760                | kDEFINED opt_nl arg
 761                    {
 762                      result = s(:defined, val[2])
 763                    }
 764                | arg tEH arg opt_nl tCOLON arg
 765                    {
 766                      result = s(:if, val[0], val[2], val[5])
 767                    }
 768                | primary
 769
 770       arg_value: arg
 771                    {
 772                      result = value_expr(val[0])
 773                    }
 774
 775       aref_args: none
 776                | args trailer
 777                    {
 778                      result = val[0]
 779                    }
 780                | args tCOMMA assocs trailer
 781                    {
 782                      result = val[0] << s(:hash, *val[2].values)
 783                    }
 784                | assocs trailer
 785                    {
 786                      result = s(:array, s(:hash, *val[0].values))
 787                    }
 788
 789      paren_args: tLPAREN2 opt_call_args rparen
 790                    {
 791                      result = val[1]
 792                    }
 793
 794  opt_paren_args: none
 795                | paren_args
 796
 797   opt_call_args: none
 798                    {
 799                      result = val[0]
 800                    }
 801                | call_args
 802                    {
 803                      result = val[0]
 804                    }
 805                | args tCOMMA
 806                    {
 807                      result = val[0]
 808                    }
 809                | args tCOMMA assocs tCOMMA
 810                    {
 811                      result = val[0] << s(:hash, *val[2][1..-1]) # TODO: self.args
 812                    }
 813                | assocs tCOMMA
 814                    {
 815                      result = s(:hash, *val[0].values)
 816                    }
 817
 818       call_args: command
 819                    {
 820                      warning "parenthesize argument(s) for future version"
 821                      result = s(:array, val[0])
 822                    }
 823                | args opt_block_arg
 824                    {
 825                      result = self.arg_blk_pass val[0], val[1]
 826                    }
 827                | assocs opt_block_arg
 828                    {
 829                      result = s(:array, s(:hash, *val[0].values))
 830                      result = self.arg_blk_pass result, val[1]
 831                    }
 832                | args tCOMMA assocs opt_block_arg
 833                    {
 834                      result = val[0] << s(:hash, *val[2].values)
 835                      result = self.arg_blk_pass result, val[3]
 836                    }
 837                | block_arg
 838
 839    command_args:   {
 840                      result = lexer.cmdarg.stack.dup # TODO: smell?
 841                      lexer.cmdarg.push true
 842                    }
 843                      call_args
 844                    {
 845                      lexer.cmdarg.stack.replace val[0]
 846                      result = val[1]
 847                    }
 848
 849       block_arg: tAMPER arg_value
 850                    {
 851                      result = s(:block_pass, val[1])
 852                    }
 853
 854   opt_block_arg: tCOMMA block_arg
 855                    {
 856                      result = val[1]
 857                    }
 858                | none
 859
 860            args: arg_value
 861                    {
 862                      result = s(:array, val[0])
 863                    }
 864                | tSTAR arg_value
 865                    {
 866                      result = s(:array, s(:splat, val[1]))
 867                    }
 868                | args tCOMMA arg_value
 869                    {
 870                      result = self.list_append val[0], val[2]
 871                    }
 872                | args tCOMMA tSTAR arg_value
 873                    {
 874                      result = self.list_append val[0], s(:splat, val[3])
 875                    }
 876
 877            mrhs: args tCOMMA arg_value
 878                    {
 879                      result = val[0] << val[2]
 880                    }
 881                | args tCOMMA tSTAR arg_value
 882                    {
 883                      result = self.arg_concat val[0], val[3]
 884                    }
 885                | tSTAR arg_value
 886                    {
 887                      result = s(:splat, val[1])
 888                    }
 889
 890         primary: literal
 891                | strings
 892                | xstring
 893                | regexp
 894                | words
 895                | qwords
 896                | var_ref
 897                | backref
 898                | tFID
 899                    {
 900                      result = new_call nil, val[0].to_sym
 901                    }
 902                | kBEGIN
 903                    {
 904                      result = self.lexer.lineno
 905                    }
 906                    bodystmt kEND
 907                    {
 908                      unless val[2] then
 909                        result = s(:nil)
 910                      else
 911                        result = s(:begin, val[2])
 912                      end
 913
 914                      result.line = val[1]
 915                    }
 916                | tLPAREN_ARG expr
 917                    {
 918                      lexer.lex_state = :expr_endarg
 919                    }
 920                    rparen
 921                    {
 922                      warning "(...) interpreted as grouped expression"
 923                      result = val[1]
 924                    }
 925                | tLPAREN compstmt tRPAREN
 926                    {
 927                      result = val[1] || s(:nil)
 928                      result.paren = true
 929                    }
 930                | primary_value tCOLON2 tCONSTANT
 931                    {
 932                      result = s(:colon2, val[0], val[2].to_sym)
 933                    }
 934                | tCOLON3 tCONSTANT
 935                    {
 936                      result = s(:colon3, val[1].to_sym)
 937                    }
 938                | tLBRACK aref_args tRBRACK
 939                    {
 940                      result = val[1] || s(:array)
 941                    }
 942                | tLBRACE assoc_list tRCURLY
 943                    {
 944                      result = s(:hash, *val[1].values)
 945                    }
 946                | kRETURN
 947                    {
 948                      result = s(:return)
 949                    }
 950                | kYIELD tLPAREN2 call_args rparen
 951                    {
 952                      result = new_yield val[2]
 953                    }
 954                | kYIELD tLPAREN2 rparen
 955                    {
 956                      result = new_yield
 957                    }
 958                | kYIELD
 959                    {
 960                      result = new_yield
 961                    }
 962                | kDEFINED opt_nl tLPAREN2 expr rparen
 963                    {
 964                      result = s(:defined, val[3])
 965                    }
 966                | kNOT tLPAREN2 expr rparen
 967                    {
 968                      result = s(:call, val[2], :"!")
 969                    }
 970                | kNOT tLPAREN2 rparen
 971                    {
 972                      raise "no3\non#{val.inspect}"
 973                    }
 974                | operation brace_block
 975                    {
 976                      oper, iter = val[0], val[1]
 977                      call = new_call nil, oper.to_sym
 978                      iter.insert 1, call
 979                      result = iter
 980                      call.line = iter.line
 981                    }
 982                | method_call
 983                | method_call brace_block
 984                    {
 985                      call, iter = val[0], val[1]
 986                      block_dup_check call, iter
 987                      iter.insert 1, call # FIX
 988                      result = iter
 989                    }
 990                | tLAMBDA lambda
 991                    {
 992                      result = val[1] # TODO: fix lineno
 993                    }
 994                | kIF expr_value then compstmt if_tail kEND
 995                    {
 996                      result = new_if val[1], val[3], val[4]
 997                    }
 998                | kUNLESS expr_value then compstmt opt_else kEND
 999                    {
1000                      result = new_if val[1], val[4], val[3]
1001                    }
1002                | kWHILE
1003                    {
1004                      lexer.cond.push true
1005                    }
1006                    expr_value do
1007                    {
1008                      lexer.cond.pop
1009                    }
1010                    compstmt kEND
1011                    {
1012                      result = new_while val[5], val[2], true
1013                    }
1014                | kUNTIL
1015                    {
1016                      lexer.cond.push true
1017                    }
1018                    expr_value do
1019                    {
1020                      lexer.cond.pop
1021                    }
1022                    compstmt kEND
1023                    {
1024                      result = new_until val[5], val[2], true
1025                    }
1026                | kCASE expr_value opt_terms case_body kEND
1027                    {
1028                      (_, line), expr, _, body, _ = val
1029                      result = new_case expr, body, line
1030                    }
1031                | kCASE            opt_terms case_body kEND
1032                    {
1033                      (_, line), _, body, _ = val
1034                      result = new_case nil, body, line
1035                    }
1036                | kFOR for_var kIN
1037                    {
1038                      lexer.cond.push true
1039                    }
1040                    expr_value do
1041                    {
1042                      lexer.cond.pop
1043                    }
1044                    compstmt kEND
1045                    {
1046                      result = new_for val[4], val[1], val[7]
1047                    }
1048                | kCLASS
1049                    {
1050                      result = self.lexer.lineno
1051                    }
1052                    cpath superclass
1053                    {
1054                      self.comments.push self.lexer.comments
1055                      if (self.in_def || self.in_single > 0) then
1056                        yyerror "class definition in method body"
1057                      end
1058                      self.env.extend
1059                    }
1060                    bodystmt kEND
1061                    {
1062                      result = new_class val
1063                      self.env.unextend
1064                      self.lexer.comments # we don't care about comments in the body
1065                    }
1066                | kCLASS tLSHFT
1067                    {
1068                      result = self.lexer.lineno
1069                    }
1070                    expr
1071                    {
1072                      result = self.in_def
1073                      self.in_def = false
1074                    }
1075                    term
1076                    {
1077                      result = self.in_single
1078                      self.in_single = 0
1079                      self.env.extend
1080                    }
1081                    bodystmt kEND
1082                    {
1083                      result = new_sclass val
1084                      self.env.unextend
1085                      self.lexer.comments # we don't care about comments in the body
1086                    }
1087                | kMODULE
1088                    {
1089                      result = self.lexer.lineno
1090                    }
1091                    cpath
1092                    {
1093                      self.comments.push self.lexer.comments
1094                      yyerror "module definition in method body" if
1095                        self.in_def or self.in_single > 0
1096
1097                      self.env.extend
1098                    }
1099                    bodystmt kEND
1100                    {
1101                      result = new_module val
1102                      self.env.unextend
1103                      self.lexer.comments # we don't care about comments in the body
1104                    }
1105                | kDEF fname
1106                    {
1107                      result = self.in_def
1108
1109                      self.comments.push self.lexer.comments
1110                      self.in_def = true
1111                      self.env.extend
1112                    }
1113                    f_arglist bodystmt kEND
1114                    {
1115                      in_def = val[2]
1116
1117                      result = new_defn val
1118
1119                      self.env.unextend
1120                      self.in_def = in_def
1121                      self.lexer.comments # we don't care about comments in the body
1122                    }
1123                | kDEF singleton dot_or_colon
1124                    {
1125                      self.comments.push self.lexer.comments
1126                      lexer.lex_state = :expr_fname
1127                    }
1128                    fname
1129                    {
1130                      self.in_single += 1
1131                      self.env.extend
1132                      lexer.lex_state = :expr_end # force for args
1133                      result = lexer.lineno
1134                    }
1135                    f_arglist bodystmt kEND
1136                    {
1137                      result = new_defs val
1138                      result[3].line val[5]
1139
1140                      self.env.unextend
1141                      self.in_single -= 1
1142                      self.lexer.comments # we don't care about comments in the body
1143                    }
1144                | kBREAK
1145                    {
1146                      result = s(:break)
1147                    }
1148                | kNEXT
1149                    {
1150                      result = s(:next)
1151                    }
1152                | kREDO
1153                    {
1154                      result = s(:redo)
1155                    }
1156                | kRETRY
1157                    {
1158                      result = s(:retry)
1159                    }
1160
1161   primary_value: primary
1162                    {
1163                      result = value_expr(val[0])
1164                    }
1165
1166                    # These are really stupid
1167         k_begin: kBEGIN
1168            k_if: kIF
1169        k_unless: kUNLESS
1170         k_while: kWHILE
1171         k_until: kUNTIL
1172          k_case: kCASE
1173           k_for: kFOR
1174         k_class: kCLASS
1175        k_module: kMODULE
1176           k_def: kDEF
1177           k_end: kEND
1178
1179            then: term
1180                | kTHEN
1181                | term kTHEN
1182
1183              do: term
1184                | kDO_COND
1185
1186         if_tail: opt_else
1187                | kELSIF expr_value then compstmt if_tail
1188                    {
1189                      result = s(:if, val[1], val[3], val[4])
1190                    }
1191
1192        opt_else: none
1193                | kELSE compstmt
1194                    {
1195                      result = val[1]
1196                    }
1197
1198         for_var: lhs
1199                | mlhs
1200                    {
1201                      val[0].delete_at 1 if val[0][1].nil? # HACK
1202                    }
1203
1204          f_marg: f_norm_arg
1205                | tLPAREN f_margs rparen
1206                    {
1207                      result = val[1]
1208                    }
1209
1210     f_marg_list: f_marg
1211                    {
1212                      result = s(:array, val[0])
1213                    }
1214                | f_marg_list tCOMMA f_marg
1215                    {
1216                      result = list_append val[0], val[2]
1217                    }
1218
1219         f_margs: f_marg_list
1220                    {
1221                      args, = val
1222
1223                      result = block_var args
1224                    }
1225                | f_marg_list tCOMMA tSTAR f_norm_arg
1226                    {
1227                      args, _, _, splat = val
1228
1229                      result = block_var args, "*#{splat}".to_sym
1230                    }
1231                | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1232                    {
1233                      args, _, _, splat, _, args2 = val
1234
1235                      result = block_var args, "*#{splat}".to_sym, args2
1236                    }
1237                | f_marg_list tCOMMA tSTAR
1238                    {
1239                      args, _, _ = val
1240
1241                      result = block_var args, :*
1242                    }
1243                | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1244                    {
1245                      args, _, _, _, args2 = val
1246
1247                      result = block_var args, :*, args2
1248                    }
1249                | tSTAR f_norm_arg
1250                    {
1251                      _, splat = val
1252
1253                      result = block_var :"*#{splat}"
1254                    }
1255                | tSTAR f_norm_arg tCOMMA f_marg_list
1256                    {
1257                      _, splat, _, args = val
1258
1259                      result = block_var :"*#{splat}", args
1260                    }
1261                | tSTAR
1262                    {
1263                      result = block_var :*
1264                    }
1265                | tSTAR tCOMMA f_marg_list
1266                    {
1267                      _, _, args = val
1268
1269                      result = block_var :*, args
1270                    }
1271
1272     block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_f_block_arg
1273                    {
1274                      result = args val
1275                    }
1276                | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
1277                    {
1278                      result = args val
1279                    }
1280                | f_arg tCOMMA f_block_optarg opt_f_block_arg
1281                    {
1282                      result = args val
1283                    }
1284                | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_f_block_arg
1285                    {
1286                      result = args val
1287                    }
1288                | f_arg tCOMMA f_rest_arg opt_f_block_arg
1289                    {
1290                      result = args val
1291                    }
1292                | f_arg tCOMMA
1293                    {
1294                      result = args val
1295                    }
1296                | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
1297                    {
1298                      result = args val
1299                    }
1300                | f_arg opt_f_block_arg
1301                    {
1302                      result = args val
1303                    }
1304                | f_block_optarg tCOMMA f_rest_arg opt_f_block_arg
1305                    {
1306                      result = args val
1307                    }
1308                | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
1309                    {
1310                      result = args val
1311                    }
1312                | f_block_optarg opt_f_block_arg
1313                    {
1314                      result = args val
1315                    }
1316                | f_block_optarg tCOMMA f_arg opt_f_block_arg
1317                    {
1318                      result = args val
1319                    }
1320                | f_rest_arg opt_f_block_arg
1321                    {
1322                      result = args val
1323                    }
1324                | f_rest_arg tCOMMA f_arg opt_f_block_arg
1325                    {
1326                      result = args val
1327                    }
1328                | f_block_arg
1329                    {
1330                      result = args val
1331                    }
1332
1333 opt_block_param: none
1334                | block_param_def
1335
1336 block_param_def: tPIPE opt_bv_decl tPIPE
1337                    {
1338                      result = args val
1339                      result = 0 if result == s(:args)
1340                    }
1341                | tOROP
1342                    {
1343                      result = 0
1344                      self.lexer.command_start = true
1345                    }
1346                | tPIPE block_param opt_bv_decl tPIPE
1347                    {
1348                      result = args val
1349                    }
1350
1351     opt_bv_decl: none
1352                | tSEMI bv_decls
1353                    {
1354                      result = val[1]
1355                    }
1356
1357        bv_decls: bvar
1358                    {
1359                      result = args val
1360                    }
1361                | bv_decls tCOMMA bvar
1362                    {
1363                      result = args val
1364                    }
1365
1366            bvar: tIDENTIFIER
1367                    {
1368                      result = s(:shadow, val[0].to_sym)
1369                    }
1370                | f_bad_arg
1371
1372          lambda:   {
1373                      # TODO: dyna_push ? hrm
1374                      result = lexer.lpar_beg
1375                      lexer.paren_nest += 1
1376                      lexer.lpar_beg = lexer.paren_nest
1377                    }
1378                    f_larglist lambda_body
1379                    {
1380                      lpar, args, body = val
1381                      lexer.lpar_beg = lpar
1382
1383                      args = 0 if args == s(:args)
1384
1385                      call = new_call nil, :lambda
1386                      result = new_iter call, args, body
1387                    }
1388
1389     f_larglist: tLPAREN2 f_args opt_bv_decl rparen
1390                    {
1391                      result = args val
1392                    }
1393                | f_args
1394                    {
1395                      result = val[0]
1396                    }
1397
1398     lambda_body: tLAMBEG compstmt tRCURLY
1399                    {
1400                      result = val[1]
1401                    }
1402                | kDO_LAMBDA compstmt kEND
1403                    {
1404                      result = val[1]
1405                    }
1406
1407        do_block: kDO_BLOCK
1408                    {
1409                      self.env.extend :dynamic
1410                      result = self.lexer.lineno
1411                    }
1412                    opt_block_param
1413                    {
1414                      result = nil # self.env.dynamic.keys
1415                    }
1416                    compstmt kEND
1417                    {
1418                      args   = val[2]
1419                      body   = val[4]
1420                      result = new_iter nil, args, body
1421                      result.line = val[1]
1422
1423                      self.env.unextend
1424                    }
1425
1426      block_call: command do_block
1427                    {
1428                      # TODO:
1429                      # if (nd_type($1) == NODE_YIELD) {
1430                      #     compile_error(PARSER_ARG "block given to yield");
1431
1432                      syntax_error "Both block arg and actual block given." if
1433                        val[0].block_pass?
1434
1435                      val = invert_block_call val if inverted? val
1436
1437                      result = val[1]
1438                      result.insert 1, val[0]
1439                    }
1440                | block_call tDOT operation2 opt_paren_args
1441                    {
1442                      result = new_call val[0], val[2].to_sym, val[3]
1443                    }
1444                | block_call tCOLON2 operation2 opt_paren_args
1445                    {
1446                      result = new_call val[0], val[2].to_sym, val[3]
1447                    }
1448
1449     method_call: operation
1450                    {
1451                      result = self.lexer.lineno
1452                    }
1453

Large files files are truncated, but you can click here to view the full file