176
200
and parse_package s = psep Dot ident s
178
and parse_import = parser
179
| [< '(Const (Ident k),_); '(Dot,_); p, t, s = parse_import >] -> (k :: p), t, s
202
and parse_class_field_resume s =
203
if not (do_resume()) then
204
plist parse_class_field s
206
(* junk all tokens until we reach next variable/function or next type declaration *)
208
(match List.map fst (Stream.npeek 2 s) with
209
| Kwd Public :: _ | Kwd Static :: _ | Kwd Var :: _ | Kwd Override :: _ ->
211
| [] | Eof :: _ | Kwd Extern :: _ | Kwd Class :: _ | Kwd Interface :: _ | Kwd Enum :: _ | Kwd Typedef :: _ ->
213
| [Kwd Private; Kwd Function]
214
| [Kwd Private; Kwd Var] ->
216
| [Kwd Private; Kwd Class]
217
| [Kwd Private; Kwd Interface]
218
| [Kwd Private; Kwd Enum]
219
| [Kwd Private; Kwd Typedef] ->
221
| [Kwd Function; Const _]
222
| [Kwd Function; Kwd New] ->
235
let c = parse_class_field s in
236
c :: parse_class_field_resume s
238
Stream.Error _ | Stream.Failure -> parse_class_field_resume s
240
and parse_import acc = parser
241
| [< '(Const (Ident k),_); '(Dot,p); s >] ->
242
if is_resuming p then raise (TypePath (List.rev (k :: acc)));
243
parse_import (k :: acc) s
180
244
| [< '(Const (Type t),_); s >] ->
181
[] , t , match s with parser
245
List.rev acc , t , match s with parser
182
246
| [< '(Dot,_); '(Const (Type s),_) >] -> Some s
216
281
and parse_type_path_normal s = parse_type_path1 [] s
218
283
and parse_type_path1 pack = parser
219
| [< '(Const (Ident name),_); '(Dot,_); t = parse_type_path1 (name :: pack) >] -> t
284
| [< '(Const (Ident name),_); '(Dot,p); s >] ->
285
if is_resuming p then
286
raise (TypePath (List.rev (name :: pack)))
288
parse_type_path1 (name :: pack) s
220
289
| [< '(Const (Type name),_); s >] ->
221
290
let params = (match s with parser
222
| [< '(Binop OpLt,_); l = psep Comma parse_type_path_variance; '(Binop OpGt,_) >] -> l
291
| [< '(Binop OpLt,_); l = psep Comma parse_type_path_or_const; '(Binop OpGt,_) >] -> l
231
and parse_type_path_variance = parser
232
| [< '(Binop OpAdd,_); t = parse_type_path >] -> VCo, t
233
| [< '(Binop OpSub,_); t = parse_type_path >] -> VContra, t
234
| [< '(Binop OpMult,_); t = parse_type_path >] -> VBi, t
235
| [< t = parse_type_path >] -> VNo, t
300
and parse_type_path_or_const = parser
301
| [< '(Const (String s),_); >] -> TPConst (String s)
302
| [< '(Const (Int i),_); >] -> TPConst (Int i)
303
| [< '(Const (Float f),_); >] -> TPConst (Float f)
304
| [< t = parse_type_path >] -> TPType t
237
306
and parse_type_path_next t = parser
238
307
| [< '(Arrow,_); t2 = parse_type_path >] ->
246
315
and parse_type_anonymous_resume name = parser
247
316
| [< '(DblDot,p); t = parse_type_path; s >] ->
248
(name, AFVar t, p) ::
317
(name, None, AFVar t, p) ::
249
318
match s with parser
250
319
| [< '(BrClose,_) >] -> []
251
| [< '(Comma,_); l = psep Comma parse_type_anonymous; '(BrClose,_) >] -> l
320
| [< '(Comma,_) >] ->
322
| [< '(BrClose,_) >] -> []
323
| [< name = any_ident; s >] -> parse_type_anonymous_resume name s
324
| [< >] -> serror());
252
325
| [< >] -> serror()
254
and parse_type_anonymous = parser
255
| [< name = any_ident; '(DblDot,p); t = parse_type_path >] -> (name, AFVar t, p)
257
327
and parse_enum s =
259
329
match s with parser
278
348
(FProp (name,doc,l,i1,i2,t),punion p1 p2)
279
349
| [< t = parse_type_opt; s >] ->
280
350
let e , p2 = (match s with parser
281
| [< '(Binop OpAssign,_) when List.mem AStatic l; e = expr; p2 = semicolon >] -> Some e , p2
351
| [< '(Binop OpAssign,_) when List.mem AStatic l; e = toplevel_expr; p2 = semicolon >] -> Some e , p2
282
352
| [< '(Semicolon,p2) >] -> None , p2
283
353
| [< >] -> serror()
285
355
(FVar (name,doc,l,t,e),punion p1 p2))
286
356
| [< '(Kwd Function,p1); name = parse_fun_name; pl = parse_constraint_params; '(POpen,_); al = psep Comma parse_fun_param; '(PClose,_); t = parse_type_opt; s >] ->
287
357
let e = (match s with parser
288
| [< e = expr >] -> e
358
| [< e = toplevel_expr >] -> e
289
359
| [< '(Semicolon,p) >] -> (EBlock [],p)
290
360
| [< >] -> serror()
299
369
if l = [] && doc = None then raise Stream.Failure else serror()
301
and parse_signature_field = parser
371
and parse_signature_field flag = parser
302
372
| [< '(Kwd Var,p1); name = any_ident; s >] ->
303
373
(match s with parser
304
| [< '(DblDot,_); t = parse_type_path; p2 = semicolon >] -> (name,AFVar t,punion p1 p2)
305
| [< '(POpen,_); i1 = property_ident; '(Comma,_); i2 = property_ident; '(PClose,_); '(DblDot,_); t = parse_type_path; p2 = semicolon >] -> (name,AFProp (t,i1,i2),punion p1 p2))
374
| [< '(DblDot,_); t = parse_type_path; p2 = semicolon >] -> (name,flag,AFVar t,punion p1 p2)
375
| [< '(POpen,_); i1 = property_ident; '(Comma,_); i2 = property_ident; '(PClose,_); '(DblDot,_); t = parse_type_path; p2 = semicolon >] -> (name,flag,AFProp (t,i1,i2),punion p1 p2)
306
377
| [< '(Kwd Function,p1); name = any_ident; '(POpen,_); al = psep Comma parse_fun_param_type; '(PClose,_); '(DblDot,_); t = parse_type_path; p2 = semicolon >] ->
307
(name,AFFun (al,t),punion p1 p2)
378
(name,flag,AFFun (al,t),punion p1 p2)
379
| [< '(Kwd Private,_) when flag = None; s >] -> parse_signature_field (Some false) s
380
| [< '(Kwd Public,_) when flag = None; s >] -> parse_signature_field (Some true) s
309
382
and parse_cf_rights allow_static l = parser
310
383
| [< '(Kwd Static,_) when allow_static; l = parse_cf_rights false (AStatic :: l) >] -> l
334
408
and parse_constraint_param = parser
335
| [< '(Binop OpAdd,_); '(Const (Type name),_); s >] -> parse_constraint_param_next VCo name s
336
| [< '(Binop OpSub,_); '(Const (Type name),_); s >] -> parse_constraint_param_next VContra name s
337
| [< '(Binop OpMult,_); '(Const (Type name),_); s >] -> parse_constraint_param_next VBi name s
338
| [< '(Const (Type name),_); s >] -> parse_constraint_param_next VNo name s
340
and parse_constraint_param_next v name = parser
341
| [< '(DblDot,_); s >] ->
343
| [< '(POpen,_); l = psep Comma parse_type_path_normal; '(PClose,_) >] -> (v,name,l)
344
| [< t = parse_type_path_normal >] -> (v,name,[t])
346
| [< >] -> (v,name,[])
409
| [< '(Const (Type name),_); s >] ->
411
| [< '(DblDot,_); s >] ->
413
| [< '(POpen,_); l = psep Comma parse_type_path_normal; '(PClose,_) >] -> (name,l)
414
| [< t = parse_type_path_normal >] -> (name,[t])
348
418
and parse_class_herit = parser
349
419
| [< '(Kwd Extends,_); t = parse_type_path_normal >] -> HExtends t
352
422
and block1 = parser
353
423
| [< '(Const (Ident name),p); s >] -> block2 name true p s
354
424
| [< '(Const (Type name),p); s >] -> block2 name false p s
355
| [< b = block >] -> EBlock b
425
| [< b = block [] >] -> EBlock b
357
427
and block2 name ident p = parser
358
428
| [< '(DblDot,_); e = expr; l = parse_obj_decl >] -> EObjectDecl ((name,e) :: l)
359
429
| [< e = expr_next (EConst (if ident then Ident name else Type name),p); s >] ->
361
431
let _ = semicolon s in
432
let b = block [e] s in
366
(!display_error) e p;
436
(!display_error) err p;
371
441
let e = parse_block_elt s in
445
display (EBlock (List.rev (e :: acc)),snd e)
374
446
| Stream.Failure ->
376
448
| Stream.Error _ ->
377
449
let tk , pos = (match Stream.peek s with None -> last_token s | Some t -> t) in
378
450
(!display_error) (Unexpected tk) pos;
381
453
(!display_error) e p;
384
456
and parse_block_elt = parser
385
457
| [< '(Kwd Var,p1); vl = psep Comma parse_var_decl; p2 = semicolon >] -> (EVars vl,punion p1 p2)
407
479
| [< >] -> (name,t,None)
409
481
and expr = parser
410
| [< '(BrOpen,p1); e = block1; '(BrClose,p2) >] -> (e,punion p1 p2)
482
| [< '(BrOpen,p1); b = block1; '(BrClose,p2); s >] ->
483
let e = (b,punion p1 p2) in
485
| EObjectDecl _ -> expr_next e s
411
487
| [< '(Const c,p); s >] -> expr_next (EConst c,p) s
412
488
| [< '(Kwd This,p); s >] -> expr_next (EConst (Ident "this"),p) s
489
| [< '(Kwd Callback,p); s >] -> expr_next (EConst (Ident "callback"),p) s
413
490
| [< '(Kwd Cast,p1); s >] ->
414
491
(match s with parser
415
492
| [< '(POpen,_); e = expr; s >] ->
416
493
(match s with parser
417
494
| [< '(Comma,_); t = parse_type_path; '(PClose,p2); s >] -> expr_next (ECast (e,Some t),punion p1 p2) s
418
| [< >] -> expr_next (ECast (e,None),punion p1 (pos e)) s)
419
| [< e = expr; s >] -> expr_next (ECast (e,None),punion p1 (pos e)) s)
495
| [< '(PClose,p2); s >] -> expr_next (ECast (e,None),punion p1 (pos e)) s
497
| [< e = expr; s >] -> expr_next (ECast (e,None),punion p1 (pos e)) s
420
499
| [< '(Kwd Throw,p); e = expr >] -> (EThrow e,p)
421
| [< '(Kwd New,p1); t = parse_type_path_normal; '(POpen,_); al = psep Comma expr; '(PClose,p2); s >] -> expr_next (ENew (t,al),punion p1 p2) s
500
| [< '(Kwd New,p1); t = parse_type_path_normal; '(POpen,p); s >] ->
501
if is_resuming p then display (EDisplayNew t,punion p1 p);
503
| [< al = psep Comma expr; '(PClose,p2); s >] -> expr_next (ENew (t,al),punion p1 p2) s
422
505
| [< '(POpen,p1); e = expr; '(PClose,p2); s >] -> expr_next (EParenthesis e, punion p1 p2) s
423
506
| [< '(BkOpen,p1); l = parse_array_decl; '(BkClose,p2); s >] -> expr_next (EArrayDecl l, punion p1 p2) s
424
| [< '(Kwd Function,p1); '(POpen,_); al = psep Comma parse_fun_param; '(PClose,_); t = parse_type_opt; e = expr; s >] ->
430
expr_next (EFunction f, punion p1 (pos e)) s
507
| [< '(Kwd Function,p1); '(POpen,_); al = psep Comma parse_fun_param; '(PClose,_); t = parse_type_opt; s >] ->
514
EFunction f, punion p1 (pos e)
517
expr_next (make (expr s)) s
519
Display e -> display (make e))
431
520
| [< '(Unop op,p1) when is_prefix op; e = expr >] -> make_unop op e p1
432
521
| [< '(Binop OpSub,p1); e = expr >] -> make_unop Neg e p1
433
| [< '(Kwd For,p); '(POpen,_); name = any_ident; '(Kwd In,_); it = expr; '(PClose,_); e = expr; s >] ->
434
expr_next (EFor (name,it,e),punion p (pos e)) s
522
| [< '(Kwd For,p); '(POpen,_); name = any_ident; '(Kwd In,_); it = expr; '(PClose,_); s >] ->
525
expr_next (EFor (name,it,e),punion p (pos e)) s
527
Display e -> display (EFor (name,it,e),punion p (pos e)))
435
528
| [< '(Kwd If,p); '(POpen,_); cond = expr; '(PClose,_); e1 = expr; s >] ->
436
529
let e2 , s = (match s with parser
437
530
| [< '(Kwd Else,_); e2 = expr; s >] -> Some e2 , s
439
match Stream.npeek 2 s with
440
| [(Semicolon,_);(Kwd Else,_)] ->
444
| [< e2 = expr; s >] -> Some e2, s
533
we can't directly npeek 2 elements because this might
534
remove some documentation tag.
536
match Stream.npeek 1 s with
538
(match Stream.npeek 2 s with
539
| [(Semicolon,_); (Kwd Else,_)] ->
543
| [< e2 = expr; s >] -> Some e2, s
450
550
| [< '(Kwd Return,p); e = popt expr >] -> (EReturn e, match e with None -> p | Some e -> punion p (pos e))
451
551
| [< '(Kwd Break,p) >] -> (EBreak,p)
452
552
| [< '(Kwd Continue,p) >] -> (EContinue,p)
453
| [< '(Kwd While,p1); '(POpen,_); cond = expr; '(PClose,_); e = expr; s >] -> expr_next (EWhile (cond,e,NormalWhile),punion p1 (pos e)) s
553
| [< '(Kwd While,p1); '(POpen,_); cond = expr; '(PClose,_); s >] ->
556
expr_next (EWhile (cond,e,NormalWhile),punion p1 (pos e)) s
558
Display e -> display (EWhile (cond,e,NormalWhile),punion p1 (pos e)))
454
559
| [< '(Kwd Do,p1); e = expr; '(Kwd While,_); '(POpen,_); cond = expr; '(PClose,_); s >] -> expr_next (EWhile (cond,e,DoWhile),punion p1 (pos e)) s
455
| [< '(Kwd Switch,p1); e = expr; '(BrOpen,_); cases , def = parse_switch_cases; '(BrClose,p2); s >] -> expr_next (ESwitch (e,cases,def),punion p1 p2) s
456
| [< '(Kwd Try,p1); e = expr; cl = plist parse_catch; s >] -> expr_next (ETry (e,cl),p1) s
560
| [< '(Kwd Switch,p1); e = expr; '(BrOpen,_); cases , def = parse_switch_cases e []; '(BrClose,p2); s >] -> expr_next (ESwitch (e,cases,def),punion p1 p2) s
561
| [< '(Kwd Try,p1); e = expr; cl = plist (parse_catch e); s >] -> expr_next (ETry (e,cl),p1) s
457
562
| [< '(IntInterval i,p1); e2 = expr >] -> make_binop OpInterval (EConst (Int i),p1) e2
458
563
| [< '(Kwd Untyped,p1); e = expr >] -> (EUntyped e,punion p1 (pos e))
460
565
and expr_next e1 = parser
461
| [< '(Dot,_); s >] ->
463
| [< '(Const (Ident f),p); s >] -> expr_next (EField (e1,f) , punion (pos e1) p) s
464
| [< '(Const (Type t),p); s >] -> expr_next (EType (e1,t) , punion (pos e1) p) s
466
| [< '(POpen,p1); params = psep Comma expr; '(PClose,p2); s >] ->
467
expr_next (ECall (e1,params) , punion (pos e1) p2) s
566
| [< '(Dot,p); s >] ->
567
if is_resuming p then display (EDisplay e1,p);
569
| [< '(Const (Ident f),p2) when p.pmax = p2.pmin; s >] -> expr_next (EField (e1,f) , punion (pos e1) p2) s
570
| [< '(Const (Type t),p2) when p.pmax = p2.pmin; s >] -> expr_next (EType (e1,t) , punion (pos e1) p2) s
572
| [< '(POpen,p1); s >] ->
573
if is_resuming p1 then display (EDisplay e1,p1);
575
| [< params = psep Comma expr; '(PClose,p2); s >] -> expr_next (ECall (e1,params) , punion (pos e1) p2) s
468
577
| [< '(BkOpen,_); e2 = expr; '(BkClose,p2); s >] ->
469
578
expr_next (EArray (e1,e2), punion (pos e1) p2) s
470
579
| [< '(Binop OpGt,_); s >] ->
490
599
make_binop op e1 e2
491
600
| [< '(Unop op,p) when is_postfix e1 op; s >] ->
492
601
expr_next (EUnop (op,Postfix,e1), punion (pos e1) p) s
602
| [< '(Question,_); e2 = expr; '(DblDot,_); e3 = expr >] ->
603
(ETernary (e1,e2,e3),punion (pos e1) (pos e3))
495
and parse_switch_cases = parser
496
| [< '(Kwd Default,p1); '(DblDot,_); e = block1; l , def = parse_switch_cases >] ->
606
and parse_switch_cases eswitch cases = parser
607
| [< '(Kwd Default,p1); '(DblDot,_); s >] ->
608
let b = (try block1 s with Display e -> display (ESwitch (eswitch,cases,Some e),p1)) in
609
let l , def = parse_switch_cases eswitch cases s in
497
610
(match def with None -> () | Some (e,p) -> error Duplicate_default p);
499
| [< '(Kwd Case,p1); e = expr; '(DblDot,_); b = block1; l , def = parse_switch_cases >] ->
500
(e,(b,p1)) :: l , def
612
| [< '(Kwd Case,p1); el = psep Comma expr; '(DblDot,_); s >] ->
613
let b = (try block1 s with Display e -> display (ESwitch (eswitch,List.rev ((el,e) :: cases),None),p1)) in
614
parse_switch_cases eswitch ((el,(b,p1)) :: cases) s
616
List.rev cases , None
504
and parse_catch = parser
505
| [< '(Kwd Catch,_); '(POpen,_); name = any_ident; s >] ->
618
and parse_catch etry = parser
619
| [< '(Kwd Catch,p); '(POpen,_); name = any_ident; s >] ->
506
620
match s with parser
507
| [< '(DblDot,_); t = parse_type_path; '(PClose,_); e = expr >] -> (name,t,e)
621
| [< '(DblDot,_); t = parse_type_path; '(PClose,_); s >] ->
624
| [< e = expr >] -> (name,t,e)
627
Display e -> display (ETry (etry,[name,t,e]),p))
508
628
| [< '(_,p) >] -> error Missing_type p
630
and toplevel_expr s =
510
636
let parse code file =
511
637
let old = Lexer.save() in
512
638
let old_cache = !cache in