mcc-fj.opp.exp 25.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
File "mcc-fj.mly", line 195, characters 35-44:
Warning: the token TokAssign is unused.
File "mcc-fj.mly", line 204, characters 20-27:
Warning: the token TokCase is unused.
File "mcc-fj.mly", line 210, characters 20-30:
Warning: the token TokDefault is unused.
File "mcc-fj.mly", line 219, characters 20-27:
Warning: the token TokGoto is unused.
File "mcc-fj.mly", line 255, characters 20-28:
Warning: the token TokQuest is unused.
File "mcc-fj.mly", line 260, characters 20-33:
Warning: the token TokRightArrow is unused.
File "mcc-fj.mly", line 238, characters 20-29:
Warning: the token TokSwitch is unused.
File "mcc-fj.mly", line 242, characters 20-29:
Warning: the token TokThrows is unused.
%{
open Symbol
open Fj_ast
open Fj_ast_util
open Fj_ast_state
open Fj_ast_exn

(*
 * The name of the root class.
 *)
let object_sym = Symbol.add "FjObject"

(* 
 * The star symbol is used for parsing import statements
 *)
let star_sym = Symbol.add "*"

(*
 * Var name in a declaration.
 *)
type var_name =
   VarNameId of symbol * pos
 | VarNameArray of var_name * pos
 | VarNameFun of var_name * (symbol * ty) list * pos

let pos_of_var_name = function
   VarNameId (_, pos) -> pos
 | VarNameArray (_, pos) -> pos
 | VarNameFun (_, _, pos) -> pos

(*
 * This is a temporary hack because new arrays do
 * not allow arbitrary types.
 *)
let var_of_var_name = function
   VarNameId (id, pos) ->
      id, pos
 | VarNameArray (_, pos)
 | VarNameFun (_, _, pos) ->
      raise (AstException (pos, StringError "complex array allocations not implemented"))

(*
 * Build a variable name from an id and a nest tree.
 *)
let make_var_name id nest pos =
   let rec collect name = function
      0 -> name
    | i -> collect (VarNameArray (name, pos)) (pred i)
   in
      collect (VarNameId (id, pos)) nest

(*
 * Do the same for types.
 *)
let make_type id nest pos =
   let rec collect ty = function
      0 -> ty
    | i -> collect (TypeArray (ty, pos)) (pred i)
   in
      collect (TypeId (id, pos)) nest

(*
 * Build a variable declaration from the syntax.
 *)
let rec make_var_decl ty = function
   VarNameId (n, pos) ->
      n, ty, pos
 | VarNameArray (v, pos) ->
      make_var_decl (TypeArray (ty, pos)) v
 | VarNameFun (v, args, pos) ->
      make_var_decl (TypeFun (List.map snd args, ty, pos)) v

and make_var_decls ty decls =
   List.map (make_var_decl ty) decls

(*
 * Make a param decl from a var decl.
 *)
let make_param_decls args =
   List.map (fun (v, ty, _) -> v, ty) args

(*
 * Build a variable declaration from the syntax.
 *)
let make_var_init_decls ty defs =
   (* Build the declaration with an initializer *)
   let rec make_def ty e = function
      VarNameId (n, pos) ->
         n, ty, e, pos
    | VarNameArray (v, pos) ->
         make_def (TypeArray (ty, pos)) e v
    | VarNameFun (v, args, pos) ->
         make_def (TypeFun (List.map snd args, ty, pos)) e v
   in

   (* Initial type *)
   let make_init_def (v, e) =
      make_def ty e v
   in
      List.map make_init_def defs

(*
 * A function definition.
 *)
let get_fun_var (v, ty) =
   v, ty, pos_of_type ty

let make_fun_def ty_mods ty decl body pos =
   let pos = union_pos (pos_of_type ty) pos in
   match decl with
      VarNameFun (res, vars, _) ->
         let vars = List.map get_fun_var vars in
         let f, ty, _ = make_var_decl ty res in
            FunDefs ([ty_mods, f, vars, ty, SeqExpr (body, pos), pos], pos)
    | VarNameId _
    | VarNameArray _ ->
         raise (AstException (pos, StringError "not a function"))

(*
 * Constructor definition.
 *)
let make_const_def ty_mods decl body pos =
   match decl with
      VarNameFun (res, vars, _) ->
         let vars = List.map get_fun_var vars in
         let f, _, _ = make_var_decl (TypeVoid pos) res in
            ConstDef (ty_mods, f, vars, SeqExpr (body, pos), pos)
    | VarNameId _
    | VarNameArray _ ->
         raise (AstException (pos, StringError "not a function"))

(*
 * Unary expression.
 *)
let make_unop op expr =
   UnOpExpr (op, expr, pos_of_expr expr)

(*
 * Binary expressions.
 *)
let make_binop op expr1 expr2 =
   let pos = union_pos (pos_of_expr expr1) (pos_of_expr expr2) in
      BinOpExpr (op, expr1, expr2, pos)

let make_boolop op expr1 expr2 =
   let pos = union_pos (pos_of_expr expr1) (pos_of_expr expr2) in
      BoolOpExpr (op, expr1, expr2, pos)

(*
 * Pre and pos increment.
 *)
let make_uarith_op pos op expr =
   let pos = union_pos pos (pos_of_expr expr) in
      UArithExpr (op, expr, pos)

(*
 * Optional expression.
 *)
let make_opt_expr opt_expr def_expr =
   match opt_expr with
      Some expr -> expr
    | None -> def_expr
%}
%start prog
%token <Fj_ast.pos> TokVolatile
%token <Fj_ast.pos> TokTrue
%token <Fj_ast.pos> TokTransient
%token <Fj_ast.pos> TokThrows
%token <Fj_ast.pos> TokSynchronized
%token <Fj_ast.pos> TokSwitch
%token <string * Fj_ast.pos> TokString
%token <Fj_ast.pos> TokStrictfp
%token <Fj_ast.pos> TokStatic
%token <Fj_ast.pos> TokSemi
%token <Fj_ast.pos> TokRightParen
%token <Fj_ast.pos> TokRightBrack
%token <Fj_ast.pos> TokRightBrace
%token <Fj_ast.pos> TokRightArrow
%token <Fj_ast.pos> TokReturn
%token <Fj_ast.pos> TokQuest
%token <Fj_ast.pos> TokPublic
%token <Fj_ast.pos> TokProtected
%token <Fj_ast.pos> TokPrivate
%token <Fj_ast.pos> TokPackage
%token <Fj_ast.pos> TokNil
%token <Fj_ast.pos> TokNew
%token <Fj_ast.pos> TokNative
%token <Fj_ast.pos> TokLeftBrace
%token <Fj_ast.pos> TokInterface
%token <int * Fj_ast.pos> TokInt
%token <Fj_ast.pos> TokImport
%token <Fj_ast.pos> TokImplements
%token <Fj_ast.pos> TokIf
%token <Symbol.symbol * Fj_ast.pos> TokId
%token <Fj_ast.pos> TokGoto
%token <float * Fj_ast.pos> TokFloat
%token <Fj_ast.pos> TokFinal
%token <Fj_ast.pos> TokFalse
%token <Fj_ast.pos> TokExtends
%token TokEof
%token <Fj_ast.pos> TokDoubleBrack
%token <Fj_ast.pos> TokDo
%token <Fj_ast.pos> TokDefault
%token <Fj_ast.pos> TokContinue
%token <Fj_ast.pos> TokConst
%token <Fj_ast.pos> TokColon
%token <Fj_ast.pos> TokClass
%token <char * Fj_ast.pos> TokChar
%token <Fj_ast.pos> TokCase
%token <Fj_ast.pos> TokBreak
%token <Fj_ast.pos> TokBang
%token <Fj_ast.binop * Fj_ast.pos> TokAssign
%token <Fj_ast.pos> TokAbstract
%token <Fj_ast.pos> TokInstanceof
%token <Fj_ast.pos> TokComma
%token <Fj_ast.pos> TokEq
%token <Fj_ast.pos> TokLOr
%token <Fj_ast.pos> TokLAnd
%token <Fj_ast.pos> TokPipe
%token <Fj_ast.pos> TokHat
%token <Fj_ast.pos> TokAmp
%token <Fj_ast.pos> TokNotEq
%token <Fj_ast.pos> TokEqEq
%token <Fj_ast.pos> TokLt
%token <Fj_ast.pos> TokLe
%token <Fj_ast.pos> TokGt
%token <Fj_ast.pos> TokGe
%token <Fj_ast.pos> TokLsr
%token <Fj_ast.pos> TokLsl
%token <Fj_ast.pos> TokAsr
%token <Fj_ast.pos> TokPlus
%token <Fj_ast.pos> TokMinus
%token <Fj_ast.pos> TokStar
%token <Fj_ast.pos> TokSlash
%token <Fj_ast.pos> TokPercent
%token <Fj_ast.pos> TokThrow
%token <Fj_ast.pos> TokPlusPlus
%token <Fj_ast.pos> TokMinusMinus
%token <Fj_ast.pos> TokLeftParen
%token <Fj_ast.pos> TokLeftBrack
%token <Fj_ast.pos> TokDot
%token <Fj_ast.pos> TokWhile
%token <Fj_ast.pos> TokFor
%token <Fj_ast.pos> TokElse
%token <Fj_ast.pos> TokTry
%token <Fj_ast.pos> TokFinally
%token <Fj_ast.pos> TokCatch
%nonassoc TokInstanceof 
%left TokComma 
%right TokEq 
%left TokLOr 
%left TokLAnd 
%left TokPipe 
%left TokHat 
%left TokAmp 
%left TokNotEq TokEqEq 
%left TokLt TokLe TokGt TokGe 
%left TokLsr TokLsl TokAsr 
%left TokPlus TokMinus 
%left TokStar TokSlash TokPercent 
%nonassoc TokThrow 
%right prec_unary prec_cast TokPlusPlus TokMinusMinus 
%left prec_subscript prec_apply TokLeftParen TokLeftBrack TokDot 
%right TokWhile TokFor 
%nonassoc prec_ifthen 
%nonassoc prec_ifthenelse TokElse 
%nonassoc TokTry 
%left TokFinally TokCatch 
%type <Fj_ast.prog> prog
%%

prog:
289 290 291 292 293
| _1 = opt_package_stmt _2 = opt_import_list _3 = class_or_interface_defs _4 = TokEof
    {          ( {  prog_package = _1;
               prog_imports = _2;
               prog_defs    = _3 }
          )}
294 295 296

opt_package_stmt:
| 
297 298 299
    {      ( None )}
| _1 = TokPackage _2 = rev_dotted_name _3 = TokSemi
    {      ( Some (List.rev _2, union_pos _1 _3) )}
300 301 302

opt_import_list:
| 
303 304 305
    {      ( [] )}
| _1 = rev_import_list
    {      ( List.rev _1 )}
306 307

rev_import_list:
308 309 310 311
| _1 = import_stmt
    {      ( [_1] )}
| _1 = rev_import_list _2 = import_stmt
    {      ( _2 :: _1 )}
312 313

import_stmt:
314 315 316 317
| _1 = TokImport _2 = rev_dotted_name _3 = TokSemi
    {      ( List.rev _2, union_pos _1 _3 )}
| _1 = TokImport _2 = rev_dotted_name _3 = TokDot _4 = TokStar _5 = TokSemi
    {      ( List.rev (star_sym :: _2), union_pos _1 _5 )}
318 319

rev_dotted_name:
320 321 322 323
| _1 = TokId
    {      ( [fst _1] )}
| _1 = rev_dotted_name _2 = TokDot _3 = TokId
    {      ( (fst _3) :: _1 )}
324 325

class_or_interface_defs:
326 327
| _1 = rev_class_or_interface_defs
    {          ( List.rev _1 )}
328 329 330

rev_class_or_interface_defs:
| 
331 332 333
    {          ( [] )}
| _1 = rev_class_or_interface_defs _2 = class_or_interface_def
    {          ( _2 :: _1 )}
334 335

class_or_interface_def:
336 337 338
| _1 = rev_type_mod_list _2 = class_or_interface_def_content
    {          ( (* Add type modifier information *)
            match _2 with
339
               TypeDef (_, v, ty, pos) ->
340
                  TypeDef (List.rev _1, v, ty, pos)
341
             | ClassDef (_, a, b, c, d, e) ->
342
                  ClassDef (List.rev _1, a, b, c, d, e) 
343 344
             | _ ->
                  failwith "Internal error while parsing class/interface def."
345
          )}
346 347

class_or_interface_def_content:
348 349 350 351
| _1 = class_def
    {          ( _1 )}
| _1 = interface_def
    {          ( _1 )}
352 353

interface_def:
354 355 356 357
| _1 = TokInterface _2 = TokId _3 = opt_extends_list _4 = TokLeftBrace _5 = rev_interface_body _6 = TokRightBrace
    {          ( let pos = union_pos _1 _6 in
            let v, _ = _2 in
            let ty = TypeInterface (v, _3, List.rev _5, pos) in
358
               TypeDef ([], v, ty, pos)
359
          )}
360 361

class_def:
362 363 364 365 366
| _1 = TokClass _2 = TokId _3 = opt_extends _4 = opt_implements _5 = TokLeftBrace _6 = class_body _7 = TokRightBrace
    {          ( let pos = union_pos _1 _7 in
            let v, _ = _2 in
               ClassDef ([], v, _3, _4, _6, pos)
          )}
367 368 369

opt_extends_list:
| 
370 371 372
    {          ( [] )}
| _1 = TokExtends _2 = var_list
    {          ( List.map fst _2 )}
373 374 375

opt_extends:
| 
376 377 378
    {          ( object_sym )}
| _1 = TokExtends _2 = TokId
    {          ( fst _2 )}
379 380 381

opt_implements:
| 
382 383 384
    {          ( [] )}
| _1 = TokImplements _2 = var_list
    {          ( List.map fst _2 )}
385 386

var_list:
387 388
| _1 = rev_var_list
    {          ( List.rev _1 )}
389 390

rev_var_list:
391 392 393 394
| _1 = TokId
    {          ( [_1] )}
| _1 = rev_var_list _2 = TokComma _3 = TokId
    {          ( _3 :: _1 )}
395 396 397

rev_interface_body:
| 
398 399 400
    {          ( [] )}
| _1 = rev_interface_body _2 = rev_var_decl_list _3 = TokSemi
    {          ( _2 @ _1 )}
401 402

class_body:
403 404
| _1 = rev_member_defs
    {          ( List.rev _1 )}
405 406 407

rev_member_defs:
| 
408 409 410 411
    {          ( [] )}
| _1 = rev_member_defs _2 = rev_type_mod_list _3 = member_def
    {          ( let ty_mods = List.rev _2 in
            let mem_def = match _3 with
412 413 414 415 416 417 418 419 420
               VarDefs (_, vdl, pos) ->
                  VarDefs (ty_mods, vdl, pos)
             | FunDefs ([_, f, vars, ty, se, pos], pos2) ->
                  FunDefs ([ty_mods, f, vars, ty, se, pos], pos2)
             | ConstDef (_, f, vars, se, pos) ->
                  ConstDef (ty_mods, f, vars, se, pos )
             | _ ->
                  failwith "Internal Error: Unexpected def while parsing"
            in
421 422
               mem_def :: _1
          )}
423 424

member_def:
425 426 427 428 429 430
| _1 = var_defs
    {          ( _1 )}
| _1 = fun_def
    {          ( _1 )}
| _1 = const_def
    {          ( _1 )}
431 432 433

rev_type_mod_list:
| 
434 435 436
    {          ( [] )}
| _1 = rev_type_mod_list _2 = type_mod
    {          ( _2 :: _1 )}
437 438

type_mod:
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
| _1 = TokPublic
    {          ( ModPublic _1 )}
| _1 = TokProtected
    {          ( ModProtected _1 )}
| _1 = TokPrivate
    {          ( ModPrivate _1 )}
| _1 = TokStatic
    {          ( ModStatic _1 )}
| _1 = TokFinal
    {          ( ModFinal _1 )}
| _1 = TokNative
    {          ( ModNative _1 )}
| _1 = TokAbstract
    {          ( ModAbstract _1 )}
| _1 = TokSynchronized
    {          ( ModSynchronized _1 )}
| _1 = TokTransient
    {          ( ModTransient _1 )}
| _1 = TokVolatile
    {          ( ModVolatile _1 )}
| _1 = TokStrictfp
    {          ( ModStrictfp _1 )}
| _1 = TokConst
    {          ( raise (AstException (_1, 
               (StringError "'const' is reserved, but not a Java keyword"))) )}
464 465

type_spec:
466 467
| _1 = id_brackets
    {          ( let id, nest, pos = _1 in
468
               make_type id nest pos
469
          )}
470 471

id_brackets:
472 473
| _1 = TokId
    {          ( let id, pos = _1 in
474
               id, 0, pos
475 476 477 478
          )}
| _1 = TokId _2 = brackets
    {          ( let id, pos1 = _1 in
            let nest, pos2 = _2 in
479 480
            let pos = union_pos pos1 pos2 in
               id, nest, pos
481
          )}
482 483

brackets:
484 485 486 487 488 489
| _1 = TokDoubleBrack
    {          ( 1, _1 )}
| _1 = brackets _2 = TokDoubleBrack
    {          ( let count, pos1 = _1 in
              succ count, union_pos pos1 _2
          )}
490 491 492

opt_var_decl_list:
| 
493 494 495
    {          ( [] )}
| _1 = var_decl_list
    {          ( _1 )}
496 497

var_decl_list:
498 499
| _1 = rev_var_decl_list
    {          ( List.rev _1 )}
500 501

rev_var_decl_list:
502 503 504 505
| _1 = var_decl
    {          ( [_1] )}
| _1 = rev_var_decl_list _2 = TokComma _3 = var_decl
    {          ( _3 :: _1 )}
506 507

var_decl:
508 509
| _1 = type_spec _2 = direct_decl
    {          ( make_var_decl _1 _2 )}
510 511

var_defs:
512 513 514 515
| _1 = type_spec _2 = init_def_list _3 = TokSemi
    {          ( let pos = union_pos (pos_of_type _1) _3 in
               VarDefs ([], make_var_init_decls _1 _2, pos)
          )}
516 517

init_def_list:
518 519
| _1 = rev_init_def_list
    {          ( List.rev _1 )}
520 521

rev_init_def_list:
522 523 524 525
| _1 = init_def
    {          ( [_1] )}
| _1 = rev_init_def_list _2 = TokComma _3 = init_def
    {          ( _3 :: _1 )}
526 527

init_def:
528 529 530 531
| _1 = direct_decl
    {          ( _1, None )}
| _1 = direct_decl _2 = TokEq _3 = expr
    {          ( _1, Some _3 )}
532 533

direct_decl:
534 535
| _1 = id_brackets
    {          ( let id, nest, pos = _1 in
536
               make_var_name id nest pos
537 538 539
          )}
| _1 = fun_decl
    {          ( _1 )}
540 541

fun_decl:
542 543
| _1 = id_brackets _2 = TokLeftParen _3 = opt_var_decl_list _4 = TokRightParen
    {          ( let id, nest, pos1 = _1 in
544
            let name = make_var_name id nest pos1 in
545 546 547 548 549 550 551 552 553 554 555
            let pos = union_pos pos1 _4 in
               VarNameFun (name, make_param_decls _3, pos)
          )}
| _1 = fun_decl _2 = TokDoubleBrack %prec prec_subscript
    {          ( let pos = union_pos (pos_of_var_name _1) _2 in
               VarNameArray (_1, pos)
          )}
| _1 = fun_decl _2 = TokLeftParen _3 = opt_var_decl_list _4 = TokRightParen %prec prec_apply
    {          ( let pos = union_pos (pos_of_var_name _1) _4 in
               VarNameFun (_1, make_param_decls _3, pos)
          )}
556 557

fun_def:
558 559
| _1 = type_spec _2 = direct_decl _3 = TokLeftBrace _4 = stmt_list _5 = TokRightBrace
    {          ( make_fun_def [] _1 _2 _4 _5 )}
560 561

const_def:
562 563
| _1 = direct_decl _2 = TokLeftBrace _3 = stmt_list _4 = TokRightBrace
    {          ( make_const_def [] _1 _3 _4 )}
564 565

expr:
566 567 568 569
| _1 = ncast_expr
    {          ( _1 )}
| _1 = cast_expr
    {          ( _1 )}
570 571

ncast_expr:
572 573
| _1 = TokInt
    {          ( let i, pos = _1 in
574
               IntExpr (i, pos)
575 576 577
          )}
| _1 = TokFloat
    {          ( let x, pos = _1 in
578
               FloatExpr (x, pos)
579 580 581
          )}
| _1 = TokChar
    {          ( let c, pos = _1 in
582
               CharExpr (c, pos)
583 584 585
          )}
| _1 = TokString
    {          ( let s, pos = _1 in
586
               StringExpr (s, pos)
587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656
          )}
| _1 = TokNil
    {          ( NilExpr _1 )}
| _1 = TokTrue
    {          ( BoolExpr (true, _1) )}
| _1 = TokFalse
    {          ( BoolExpr (false, _1) )}
| _1 = TokMinus _2 = expr %prec prec_unary
    {          ( make_unop UMinusOp _2 )}
| _1 = TokBang _2 = expr %prec prec_unary
    {          ( make_unop UNotOp _2 )}
| _1 = TokPlusPlus _2 = expr %prec prec_unary
    {          ( make_uarith_op _1 PreIncrOp _2 )}
| _1 = TokMinusMinus _2 = expr %prec prec_unary
    {          ( make_uarith_op _1 PreDecrOp _2 )}
| _1 = expr _2 = TokPlusPlus %prec prec_unary
    {          ( make_uarith_op _2 PostIncrOp _1 )}
| _1 = expr _2 = TokMinusMinus %prec prec_unary
    {          ( make_uarith_op _2 PostDecrOp _1 )}
| _1 = expr _2 = TokPlus _3 = expr
    {          ( make_binop PlusOp _1 _3 )}
| _1 = expr _2 = TokMinus _3 = expr
    {          ( make_binop MinusOp _1 _3 )}
| _1 = expr _2 = TokStar _3 = expr
    {          ( make_binop TimesOp _1 _3 )}
| _1 = expr _2 = TokSlash _3 = expr
    {          ( make_binop DivideOp _1 _3 )}
| _1 = expr _2 = TokPercent _3 = expr
    {          ( make_binop ModOp _1 _3 )}
| _1 = expr _2 = TokLsl _3 = expr
    {          ( make_binop LslOp _1 _3 )}
| _1 = expr _2 = TokLsr _3 = expr
    {          ( make_binop LsrOp _1 _3 )}
| _1 = expr _2 = TokAsr _3 = expr
    {          ( make_binop AsrOp _1 _3 )}
| _1 = expr _2 = TokLAnd _3 = expr
    {          ( make_boolop LAndOp _1 _3 )}
| _1 = expr _2 = TokLOr _3 = expr
    {          ( make_boolop LOrOp _1 _3 )}
| _1 = expr _2 = TokEqEq _3 = expr
    {          ( make_binop EqOp _1 _3 )}
| _1 = expr _2 = TokNotEq _3 = expr
    {          ( make_binop NeqOp _1 _3 )}
| _1 = expr _2 = TokLe _3 = expr
    {          ( make_binop LeOp _1 _3 )}
| _1 = expr _2 = TokLt _3 = expr
    {          ( make_binop LtOp _1 _3 )}
| _1 = expr _2 = TokGe _3 = expr
    {          ( make_binop GeOp _1 _3 )}
| _1 = expr _2 = TokGt _3 = expr
    {          ( make_binop GtOp _1 _3 )}
| _1 = expr _2 = TokEq _3 = expr
    {          ( let pos = union_pos (pos_of_expr _1) (pos_of_expr _3) in
               AssignExpr (None, _1, _3, pos)
          )}
| _1 = expr _2 = binop _3 = TokEq _4 = expr %prec TokEq
    {          ( let pos = union_pos (pos_of_expr _1) (pos_of_expr _4) in
               AssignExpr (Some _2, _1, _4, pos)
          )}
| _1 = expr _2 = TokInstanceof _3 = TokId
    {          ( let id, pos = _3 in
            let pos = union_pos (pos_of_expr _1) pos in
               InstanceofExpr (_1, id, pos)
          )}
| _1 = TokNew _2 = new_expr
    {          ( _2 )}
| _1 = TokThrow _2 = expr
    {          ( let pos = union_pos _1 (pos_of_expr _2) in
               ThrowExpr (_2, pos)
          )}
657 658

cast_expr:
659 660
| _1 = TokId
    {          ( let id, pos = _1 in
661
               VarExpr (id, pos)
662 663 664 665 666 667 668 669 670 671 672 673 674 675 676
          )}
| _1 = cast_expr _2 = TokDot _3 = TokId
    {          ( let pos = union_pos (pos_of_expr _1) (snd _3) in
               ProjectExpr (_1, fst _3, pos)
          )}
| _1 = cast_expr _2 = TokLeftBrack _3 = expr _4 = TokRightBrack %prec prec_subscript
    {          ( let pos = union_pos (pos_of_expr _1) _4 in
               SubscriptExpr (_1, _3, pos)
          )}
| _1 = cast_expr _2 = TokLeftParen _3 = arg_list _4 = TokRightParen %prec prec_apply
    {          ( let pos = union_pos (pos_of_expr _1) _4 in
               ApplyExpr (_1, _3, pos)
          )}
| _1 = TokLeftParen _2 = TokId _3 = TokRightParen _4 = cast_expr %prec prec_cast
    {          ( let id, pos2 = _2 in
677
            let ty = make_type id 0 pos2 in
678 679 680 681 682 683
            let pos = union_pos _1 (pos_of_expr _4) in
               CastExpr (ty, _4, pos)
          )}
| _1 = TokLeftParen _2 = TokId _3 = brackets _4 = TokRightParen _5 = cast_expr %prec prec_cast
    {          ( let id, pos2 = _2 in
            let nest, pos3 = _3 in
684
            let ty = make_type id nest (union_pos pos2 pos3) in
685 686 687 688 689 690 691
            let pos = union_pos _1 (pos_of_expr _5) in
               CastExpr (ty, _5, pos)
          )}
| _1 = TokLeftParen _2 = ncast_expr _3 = TokRightParen %prec prec_apply
    {          ( _2 )}
| _1 = TokLeftParen _2 = TokId _3 = TokRightParen %prec prec_apply
    {          ( let id, pos = _2 in
692
               VarExpr (id, pos)
693
          )}
694 695

new_expr:
696 697 698
| _1 = new_array _2 = rev_brackets
    {          ( let id, pos1 = var_of_var_name _1 in
            let dimens, pos2 = _2 in
699 700
            let pos = union_pos pos1 pos2 in
               NewArrayExpr (id, List.rev dimens, pos)
701 702 703 704 705 706 707 708
          )}
| _1 = TokId _2 = TokLeftParen _3 = rev_arg_list _4 = TokRightParen
    {          ( let id, pos1 = _1 in
            let pos = union_pos pos1 _4 in
               NewConstExpr (id, List.rev _3, pos)
          )}
| _1 = new_const
    {          ( let id, pos = _1 in
709
               NewConstExpr (id, [], pos)
710
          )}
711 712

new_array:
713 714 715 716
| _1 = new_type
    {           ( _1 )}
| _1 = TokId
    {           ( let id, pos = _1 in
717
                VarNameId (id, pos)
718
           )}
719 720

new_type:
721 722 723 724 725 726 727 728 729 730 731
| _1 = new_type _2 = TokDoubleBrack
    {           ( let pos = union_pos (pos_of_var_name _1) _2 in
               VarNameArray (_1, pos)
           )}
| _1 = new_type _2 = TokLeftParen _3 = opt_var_decl_list _4 = TokRightParen
    {           ( let pos = union_pos (pos_of_var_name _1) _4 in
               VarNameFun (_1, make_param_decls _3, pos)
           )}
| _1 = TokId _2 = TokDoubleBrack
    {           ( let id, pos1 = _1 in
             let pos = union_pos pos1 _2 in
732
                VarNameArray (VarNameId (id, pos1), pos)
733 734 735 736 737 738 739 740
           )}
| _1 = TokId _2 = TokLeftParen _3 = var_decl_list _4 = TokRightParen
    {           ( let id, pos1 = _1 in
             let pos = union_pos pos1 _4 in
                VarNameFun (VarNameId (id, pos1), make_param_decls _3, pos)
           )}
| _1 = new_const
    {           ( let id, pos = _1 in
741
               VarNameFun (VarNameId (id, pos), [], pos)
742
           )}
743 744

new_const:
745 746
| _1 = TokId _2 = TokLeftParen _3 = TokRightParen
    {           ( _1 )}
747 748

rev_brackets:
749 750 751 752 753 754 755 756 757
| _1 = TokLeftBrack _2 = expr _3 = TokRightBrack %prec prec_subscript
    {          ( let pos = union_pos _1 _3 in
               [_2], pos
          )}
| _1 = rev_brackets _2 = TokLeftBrack _3 = expr _4 = TokRightBrack %prec prec_subscript
    {          ( let args, pos1 = _1 in
            let pos = union_pos pos1 _4 in
               _3 :: args, pos
          )}
758 759 760

opt_label:
| 
761 762 763
    {         ( None )}
| _1 = TokId
    {         ( Some (fst _1) )}
764 765 766

opt_expr:
| 
767 768 769
    {          ( None )}
| _1 = expr
    {          ( Some _1 )}
770 771

stmt:
772 773 774 775 776 777 778 779 780 781 782 783 784 785
| _1 = TokSemi
    {          ( SeqExpr ([], _1) )}
| _1 = expr _2 = TokSemi
    {          ( _1 )}
| _1 = TokIf _2 = TokLeftParen _3 = expr _4 = TokRightParen _5 = stmt %prec prec_ifthen
    {          ( let pos = union_pos _1 (pos_of_expr _5) in
               IfExpr (_3, _5, None, pos)
          )}
| _1 = TokIf _2 = TokLeftParen _3 = expr _4 = TokRightParen _5 = stmt _6 = TokElse _7 = stmt %prec prec_ifthenelse
    {          ( let pos = union_pos _1 (pos_of_expr _7) in
               IfExpr (_3, _5, Some _7, pos)
          )}
| _1 = TokFor _2 = TokLeftParen _3 = opt_expr _4 = TokSemi _5 = opt_expr _6 = TokSemi _7 = opt_expr _8 = TokRightParen _9 = stmt %prec TokFor
    {          ( let pos = union_pos _1 (pos_of_expr _9) in
786
            let def_expr = IntExpr (1, pos) in
787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832
            let init = make_opt_expr _3 def_expr in
            let test = make_opt_expr _5 def_expr in
            let step = make_opt_expr _7 def_expr in
               ForExpr (init, test, step, _9, pos)
          )}
| _1 = TokWhile _2 = TokLeftParen _3 = expr _4 = TokRightParen _5 = stmt %prec TokWhile
    {          ( let pos = union_pos _1 (pos_of_expr _5) in
               WhileExpr (_3, _5, pos)
          )}
| _1 = TokDo _2 = stmt _3 = TokWhile _4 = TokLeftParen _5 = expr _6 = TokRightParen
    {          ( let pos = union_pos _1 _6 in
               DoExpr (_2, _5, pos)
          )}
| _1 = TokReturn _2 = expr _3 = TokSemi
    {          ( let pos = union_pos _1 (pos_of_expr _2) in
               ReturnExpr (_2, pos)
          )}
| _1 = TokBreak _2 = opt_label _3 = TokSemi
    {          ( let pos = union_pos _1 _3 in
               BreakExpr (_2, pos)
          )}
| _1 = TokContinue _2 = opt_label _3 = TokSemi
    {          ( let pos = union_pos _1 _3 in
               ContinueExpr (_2, pos)
          )}
| _1 = TokLeftBrace _2 = stmt_list _3 = TokRightBrace
    {          ( let pos = union_pos _1 _3 in
               SeqExpr (_2, pos)
          )}
| _1 = TokTry _2 = TokLeftBrace _3 = stmt_list _4 = TokRightBrace _5 = rev_catches _6 = opt_finally %prec TokTry
    {          ( let pos = union_pos _1 _4 in
               TryExpr (SeqExpr (_3, pos), _5, _6, pos)
          )}
| _1 = var_defs
    {          ( let pos = pos_of_def _1 in
               DefExpr (_1, pos)
          )}
| _1 = fun_def
    {          ( let pos = pos_of_def _1 in
               DefExpr (_1, pos)
          )}
| _1 = TokId _2 = TokColon _3 = stmt
    {          ( let sym, pos = _1 in
            let pos = union_pos (snd _1) (pos_of_expr _3) in
               LabeledExpr (sym, _3, pos)
          )}
833 834 835

rev_catches:
| 
836 837 838 839 840
    {          ( [] )}
| _1 = rev_catches _2 = TokCatch _3 = TokLeftParen _4 = TokId _5 = TokId _6 = TokRightParen _7 = TokLeftBrace _8 = stmt_list _9 = TokRightBrace %prec TokCatch
    {          ( let pos = union_pos _7 _9 in
               (fst _4, fst _5, SeqExpr (_8, pos)) :: _1
          )}
841 842 843

opt_finally:
| 
844 845 846 847 848
    {          ( None )}
| _1 = TokFinally _2 = TokLeftBrace _3 = stmt_list _4 = TokRightBrace %prec TokFinally
    {          ( let pos = union_pos _1 _4 in
               Some (SeqExpr (_3, pos))
          )}
849 850

stmt_list:
851 852
| _1 = rev_stmt_list
    {          ( List.rev _1 )}
853 854 855

rev_stmt_list:
| 
856 857 858
    {          ( [] )}
| _1 = rev_stmt_list _2 = stmt
    {          ( _2 :: _1 )}
859 860 861

arg_list:
| 
862 863 864
    {          ( [] )}
| _1 = rev_arg_list
    {          ( List.rev _1 )}
865 866

rev_arg_list:
867 868 869 870
| _1 = expr
    {          ( [_1] )}
| _1 = rev_arg_list _2 = TokComma _3 = expr
    {          ( _3 :: _1 )}
871 872

binop:
873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894
| _1 = TokPlus
    {          ( PlusOp )}
| _1 = TokMinus
    {          ( MinusOp )}
| _1 = TokStar
    {          ( TimesOp )}
| _1 = TokSlash
    {          ( DivideOp )}
| _1 = TokPercent
    {          ( ModOp )}
| _1 = TokAmp
    {          ( BAndOp )}
| _1 = TokPipe
    {          ( BOrOp )}
| _1 = TokHat
    {          ( BXorOp )}
| _1 = TokLsl
    {          ( LslOp )}
| _1 = TokLsr
    {          ( LsrOp )}
| _1 = TokAsr
    {          ( AsrOp )}
895 896 897 898 899

%%