diff options
Diffstat (limited to 'parsing/parser.mly')
-rw-r--r-- | parsing/parser.mly | 926 |
1 files changed, 549 insertions, 377 deletions
diff --git a/parsing/parser.mly b/parsing/parser.mly index 429d6bec0..343f7c73b 100644 --- a/parsing/parser.mly +++ b/parsing/parser.mly @@ -17,46 +17,34 @@ open Location open Asttypes open Longident open Parsetree +open Ast_helper + +let mktyp d = Typ.mk ~loc:(symbol_rloc()) d +let mkpat d = Pat.mk ~loc:(symbol_rloc()) d +let mkexp d = Exp.mk ~loc:(symbol_rloc()) d +let mkmty d = Mty.mk ~loc:(symbol_rloc()) d +let mksig d = Sig.mk ~loc:(symbol_rloc()) d +let mkmod d = Mod.mk ~loc:(symbol_rloc()) d +let mkstr d = Str.mk ~loc:(symbol_rloc()) d +let mkclass d = Cl.mk ~loc:(symbol_rloc()) d +let mkcty d = Cty.mk ~loc:(symbol_rloc()) d +let mkctf d = Ctf.mk ~loc:(symbol_rloc()) d +let mkcf d = Cf.mk ~loc:(symbol_rloc()) d -let mktyp d = - { ptyp_desc = d; ptyp_loc = symbol_rloc() } -let mkpat d = - { ppat_desc = d; ppat_loc = symbol_rloc() } -let mkexp d = - { pexp_desc = d; pexp_loc = symbol_rloc() } -let mkmty d = - { pmty_desc = d; pmty_loc = symbol_rloc() } -let mksig d = - { psig_desc = d; psig_loc = symbol_rloc() } -let mkmod d = - { pmod_desc = d; pmod_loc = symbol_rloc() } -let mkstr d = - { pstr_desc = d; pstr_loc = symbol_rloc() } -let mkfield d = - { pfield_desc = d; pfield_loc = symbol_rloc() } -let mkclass d = - { pcl_desc = d; pcl_loc = symbol_rloc() } -let mkcty d = - { pcty_desc = d; pcty_loc = symbol_rloc() } -let mkctf d = - { pctf_desc = d; pctf_loc = symbol_rloc () } -let mkcf d = - { pcf_desc = d; pcf_loc = symbol_rloc () } let mkrhs rhs pos = mkloc rhs (rhs_loc pos) let mkoption d = let loc = {d.ptyp_loc with loc_ghost = true} in - { ptyp_desc = Ptyp_constr(mkloc (Ldot (Lident "*predef*", "option")) loc,[d]); - ptyp_loc = loc} + Typ.mk ~loc (Ptyp_constr(mkloc (Ldot (Lident "*predef*", "option")) loc,[d])) let reloc_pat x = { x with ppat_loc = symbol_rloc () };; let reloc_exp x = { x with pexp_loc = symbol_rloc () };; let mkoperator name pos = let loc = rhs_loc pos in - { pexp_desc = Pexp_ident(mkloc (Lident name) loc); pexp_loc = loc } + Exp.mk ~loc (Pexp_ident(mkloc (Lident name) loc)) let mkpatvar name pos = - { ppat_desc = Ppat_var (mkrhs name pos); ppat_loc = rhs_loc pos } + Pat.mk ~loc:(rhs_loc pos) (Ppat_var (mkrhs name pos)) (* Ghost expressions and patterns: @@ -75,18 +63,13 @@ let mkpatvar name pos = AST node, then the location must be real; in all other cases, it must be ghost. *) -let ghexp d = { pexp_desc = d; pexp_loc = symbol_gloc () };; -let ghpat d = { ppat_desc = d; ppat_loc = symbol_gloc () };; -let ghtyp d = { ptyp_desc = d; ptyp_loc = symbol_gloc () };; -let ghloc d = { txt = d; loc = symbol_gloc () };; - -let mkassert e = - match e with - | {pexp_desc = Pexp_construct ({ txt = Lident "false" }, None , false); - pexp_loc = _ } -> - mkexp (Pexp_assertfalse) - | _ -> mkexp (Pexp_assert (e)) -;; +let ghexp d = Exp.mk ~loc:(symbol_gloc ()) d +let ghpat d = Pat.mk ~loc:(symbol_gloc ()) d +let ghtyp d = Typ.mk ~loc:(symbol_gloc ()) d +let ghloc d = { txt = d; loc = symbol_gloc () } + +let ghunit () = + ghexp (Pexp_construct (mknoloc (Lident "()"), None)) let mkinfix arg1 name arg2 = mkexp(Pexp_apply(mkoperator name 2, ["", arg1; "", arg2])) @@ -123,57 +106,51 @@ let mkuplus name arg = mkexp(Pexp_apply(mkoperator ("~" ^ name) 1, ["", arg])) let mkexp_cons consloc args loc = - {pexp_desc = Pexp_construct(mkloc (Lident "::") consloc, Some args, false); - pexp_loc = loc} + Exp.mk ~loc (Pexp_construct(mkloc (Lident "::") consloc, Some args)) let mkpat_cons consloc args loc = - {ppat_desc = Ppat_construct(mkloc (Lident "::") consloc, Some args, false); - ppat_loc = loc} + Pat.mk ~loc (Ppat_construct(mkloc (Lident "::") consloc, Some args)) let rec mktailexp nilloc = function [] -> let loc = { nilloc with loc_ghost = true } in let nil = { txt = Lident "[]"; loc = loc } in - { pexp_desc = Pexp_construct (nil, None, false); pexp_loc = loc } + Exp.mk ~loc (Pexp_construct (nil, None)) | e1 :: el -> let exp_el = mktailexp nilloc el in - let l = {loc_start = e1.pexp_loc.loc_start; + let loc = {loc_start = e1.pexp_loc.loc_start; loc_end = exp_el.pexp_loc.loc_end; loc_ghost = true} in - let arg = {pexp_desc = Pexp_tuple [e1; exp_el]; pexp_loc = l} in - mkexp_cons {l with loc_ghost = true} arg l + let arg = Exp.mk ~loc (Pexp_tuple [e1; exp_el]) in + mkexp_cons {loc with loc_ghost = true} arg loc let rec mktailpat nilloc = function [] -> let loc = { nilloc with loc_ghost = true } in let nil = { txt = Lident "[]"; loc = loc } in - { ppat_desc = Ppat_construct (nil, None, false); ppat_loc = loc } + Pat.mk ~loc (Ppat_construct (nil, None)) | p1 :: pl -> let pat_pl = mktailpat nilloc pl in - let l = {loc_start = p1.ppat_loc.loc_start; + let loc = {loc_start = p1.ppat_loc.loc_start; loc_end = pat_pl.ppat_loc.loc_end; loc_ghost = true} in - let arg = {ppat_desc = Ppat_tuple [p1; pat_pl]; ppat_loc = l} in - mkpat_cons {l with loc_ghost = true} arg l + let arg = Pat.mk ~loc (Ppat_tuple [p1; pat_pl]) in + mkpat_cons {loc with loc_ghost = true} arg loc + +let mkstrexp e attrs = + { pstr_desc = Pstr_eval (e, attrs); pstr_loc = e.pexp_loc } -let mkstrexp e = - { pstr_desc = Pstr_eval e; pstr_loc = e.pexp_loc } +let mkexp_constraint e (t1, t2) = + match t1, t2 with + | Some t, None -> ghexp(Pexp_constraint(e, t)) + | _, Some t -> ghexp(Pexp_coerce(e, t1, t)) + | None, None -> assert false let array_function str name = ghloc (Ldot(Lident str, (if !Clflags.fast then "unsafe_" ^ name else name))) -let rec deep_mkrangepat c1 c2 = - if c1 = c2 then ghpat(Ppat_constant(Const_char c1)) else - ghpat(Ppat_or(ghpat(Ppat_constant(Const_char c1)), - deep_mkrangepat (Char.chr(Char.code c1 + 1)) c2)) - -let rec mkrangepat c1 c2 = - if c1 > c2 then mkrangepat c2 c1 else - if c1 = c2 then mkpat(Ppat_constant(Const_char c1)) else - reloc_pat (deep_mkrangepat c1 c2) - let syntax_error () = raise Syntaxerr.Escape_error @@ -184,6 +161,9 @@ let unclosed opening_name opening_num closing_name closing_num = let expecting pos nonterm = raise Syntaxerr.(Error(Expecting(rhs_loc pos, nonterm))) +let not_expecting pos nonterm = + raise Syntaxerr.(Error(Not_expecting(rhs_loc pos, nonterm))) + let bigarray_function str name = ghloc (Ldot(Ldot(Lident "Bigarray", str), name)) @@ -255,10 +235,10 @@ let varify_constructors var_names t = Ptyp_var s | Ptyp_constr(longident, lst) -> Ptyp_constr(longident, List.map loop lst) - | Ptyp_object lst -> - Ptyp_object (List.map loop_core_field lst) - | Ptyp_class (longident, lst, lbl_list) -> - Ptyp_class (longident, List.map loop lst, lbl_list) + | Ptyp_object (lst, o) -> + Ptyp_object (List.map (fun (s, t) -> (s, loop t)) lst, o) + | Ptyp_class (longident, lst) -> + Ptyp_class (longident, List.map loop lst) | Ptyp_alias(core_type, string) -> check_variable var_names t.ptyp_loc string; Ptyp_alias(loop core_type, string) @@ -270,17 +250,10 @@ let varify_constructors var_names t = Ptyp_poly(string_lst, loop core_type) | Ptyp_package(longident,lst) -> Ptyp_package(longident,List.map (fun (n,typ) -> (n,loop typ) ) lst) + | Ptyp_extension (s, arg) -> + Ptyp_extension (s, arg) in {t with ptyp_desc = desc} - and loop_core_field t = - let desc = - match t.pfield_desc with - | Pfield(n,typ) -> - Pfield(n,loop typ) - | Pfield_var -> - Pfield_var - in - { t with pfield_desc=desc} and loop_row_field = function | Rtag(label,flag,lst) -> @@ -291,13 +264,23 @@ let varify_constructors var_names t = loop t let wrap_type_annotation newtypes core_type body = - let exp = mkexp(Pexp_constraint(body,Some core_type,None)) in + let exp = mkexp(Pexp_constraint(body,core_type)) in let exp = List.fold_right (fun newtype exp -> mkexp (Pexp_newtype (newtype, exp))) newtypes exp in (exp, ghtyp(Ptyp_poly(newtypes,varify_constructors newtypes core_type))) +let wrap_exp_attrs body (ext, attrs) = + (* todo: keep exact location for the entire attribute *) + let body = {body with pexp_attributes = attrs @ body.pexp_attributes} in + match ext with + | None -> body + | Some id -> ghexp(Pexp_extension (id, PStr [mkstrexp body []])) + +let mkexp_attrs d attrs = + wrap_exp_attrs (mkexp d) attrs + %} /* Tokens */ @@ -362,11 +345,15 @@ let wrap_type_annotation newtypes core_type body = %token LBRACKETBAR %token LBRACKETLESS %token LBRACKETGREATER +%token LBRACKETPERCENT +%token LBRACKETPERCENTPERCENT %token LESS %token LESSMINUS %token LET %token <string> LIDENT %token LPAREN +%token LBRACKETAT +%token LBRACKETATAT %token MATCH %token METHOD %token MINUS @@ -382,6 +369,7 @@ let wrap_type_annotation newtypes core_type body = %token <string> OPTLABEL %token OR /* %token PARSER */ +%token PERCENT %token PLUS %token PLUSDOT %token <string> PREFIXOP @@ -397,7 +385,7 @@ let wrap_type_annotation newtypes core_type body = %token SHARP %token SIG %token STAR -%token <string> STRING +%token <string * string option> STRING %token STRUCT %token THEN %token TILDE @@ -458,9 +446,14 @@ The precedences must be listed from low to high. %nonassoc below_EQUAL %left INFIXOP0 EQUAL LESS GREATER /* expr (e OP e OP e) */ %right INFIXOP1 /* expr (e OP e OP e) */ +%nonassoc below_LBRACKETAT +%nonassoc LBRACKETAT +%nonassoc LBRACKETATAT +%nonassoc LBRACKETPERCENT +%nonassoc LBRACKETPERCENTPERCENT %right COLONCOLON /* expr (e :: e :: e) */ %left INFIXOP2 PLUS PLUSDOT MINUS MINUSDOT /* expr (e OP e OP e) */ -%left INFIXOP3 STAR /* expr (e OP e OP e) */ +%left PERCENT INFIXOP3 STAR /* expr (e OP e OP e) */ %right INFIXOP4 /* expr (e OP e OP e) */ %nonassoc prec_unary_minus prec_unary_plus /* unary - */ %nonassoc prec_constant_constructor /* cf. simple_expr (C versus C x) */ @@ -485,8 +478,12 @@ The precedences must be listed from low to high. %type <Parsetree.toplevel_phrase> toplevel_phrase %start use_file /* for the #use directive */ %type <Parsetree.toplevel_phrase list> use_file -%start any_longident -%type <Longident.t> any_longident +%start parse_core_type +%type <Parsetree.core_type> parse_core_type +%start parse_expression +%type <Parsetree.expression> parse_expression +%start parse_pattern +%type <Parsetree.pattern> parse_pattern %% /* Entry points */ @@ -495,11 +492,11 @@ implementation: structure EOF { $1 } ; interface: - signature EOF { List.rev $1 } + signature EOF { $1 } ; toplevel_phrase: top_structure SEMISEMI { Ptop_def $1 } - | seq_expr SEMISEMI { Ptop_def[mkstrexp $1] } + | seq_expr post_item_attributes SEMISEMI { Ptop_def[mkstrexp $1 $2] } | toplevel_directive SEMISEMI { $1 } | EOF { raise End_of_file } ; @@ -509,17 +506,26 @@ top_structure: ; use_file: use_file_tail { $1 } - | seq_expr use_file_tail { Ptop_def[mkstrexp $1] :: $2 } + | seq_expr post_item_attributes use_file_tail { Ptop_def[mkstrexp $1 $2] :: $3 } ; use_file_tail: EOF { [] } | SEMISEMI EOF { [] } - | SEMISEMI seq_expr use_file_tail { Ptop_def[mkstrexp $2] :: $3 } + | SEMISEMI seq_expr post_item_attributes use_file_tail { Ptop_def[mkstrexp $2 $3] :: $4 } | SEMISEMI structure_item use_file_tail { Ptop_def[$2] :: $3 } | SEMISEMI toplevel_directive use_file_tail { $2 :: $3 } | structure_item use_file_tail { Ptop_def[$1] :: $2 } | toplevel_directive use_file_tail { $1 :: $2 } ; +parse_core_type: + core_type EOF { $1 } +; +parse_expression: + seq_expr EOF { $1 } +; +parse_pattern: + pattern EOF { $1 } +; /* Module expressions */ @@ -548,75 +554,97 @@ module_expr: { mkmod(Pmod_unpack $3) } | LPAREN VAL expr COLON package_type RPAREN { mkmod(Pmod_unpack( - ghexp(Pexp_constraint($3, Some(ghtyp(Ptyp_package $5)), None)))) } + ghexp(Pexp_constraint($3, ghtyp(Ptyp_package $5))))) } | LPAREN VAL expr COLON package_type COLONGREATER package_type RPAREN { mkmod(Pmod_unpack( - ghexp(Pexp_constraint($3, Some(ghtyp(Ptyp_package $5)), - Some(ghtyp(Ptyp_package $7)))))) } + ghexp(Pexp_coerce($3, Some(ghtyp(Ptyp_package $5)), + ghtyp(Ptyp_package $7))))) } | LPAREN VAL expr COLONGREATER package_type RPAREN { mkmod(Pmod_unpack( - ghexp(Pexp_constraint($3, None, Some(ghtyp(Ptyp_package $5)))))) } + ghexp(Pexp_coerce($3, None, ghtyp(Ptyp_package $5))))) } | LPAREN VAL expr COLON error { unclosed "(" 1 ")" 5 } | LPAREN VAL expr COLONGREATER error { unclosed "(" 1 ")" 5 } | LPAREN VAL expr error { unclosed "(" 1 ")" 4 } + | module_expr attribute + { Mod.attr $1 $2 } + | extension + { mkmod(Pmod_extension $1) } ; + structure: - structure_tail { $1 } - | seq_expr structure_tail { mkstrexp $1 :: $2 } + str_attribute structure { $1 :: $2 } + | seq_expr post_item_attributes structure_tail { mkstrexp $1 $2 :: $3 } + | structure_tail { $1 } ; structure_tail: - /* empty */ { [] } - | SEMISEMI { [] } - | SEMISEMI seq_expr structure_tail { mkstrexp $2 :: $3 } - | SEMISEMI structure_item structure_tail { $2 :: $3 } - | structure_item structure_tail { $1 :: $2 } + /* empty */ { [] } + | SEMISEMI structure { $2 } + | structure_item structure_tail { $1 :: $2 } +; +str_attribute: + post_item_attribute { mkstr(Pstr_attribute $1) } ; structure_item: - LET rec_flag let_bindings - { match $3 with - [{ ppat_desc = Ppat_any; ppat_loc = _ }, exp] -> mkstr(Pstr_eval exp) - | _ -> mkstr(Pstr_value($2, List.rev $3)) } - | EXTERNAL val_ident COLON core_type EQUAL primitive_declaration - { mkstr(Pstr_primitive(mkrhs $2 2, {pval_type = $4; pval_prim = $6; - pval_loc = symbol_rloc ()})) } + LET ext_attributes rec_flag let_bindings + { + match $4 with + [ {pvb_pat = { ppat_desc = Ppat_any; ppat_loc = _ }; pvb_expr = exp; pvb_attributes = attrs}] -> + let exp = wrap_exp_attrs exp $2 in + mkstr(Pstr_eval (exp, attrs)) + | l -> + begin match $2 with + | None, [] -> mkstr(Pstr_value($3, List.rev l)) + | Some _, _ -> not_expecting 2 "extension" + | None, _ :: _ -> not_expecting 2 "attribute" + end + } + | EXTERNAL val_ident COLON core_type EQUAL primitive_declaration post_item_attributes + { mkstr + (Pstr_primitive (Val.mk (mkrhs $2 2) $4 + ~prim:$6 ~attrs:$7 ~loc:(symbol_rloc ()))) } | TYPE type_declarations - { mkstr(Pstr_type(List.rev $2)) } - | EXCEPTION UIDENT constructor_arguments - { mkstr(Pstr_exception(mkrhs $2 2, $3)) } - | EXCEPTION UIDENT EQUAL constr_longident - { mkstr(Pstr_exn_rebind(mkrhs $2 2, mkloc $4 (rhs_loc 4))) } - | MODULE UIDENT module_binding - { mkstr(Pstr_module(mkrhs $2 2, $3)) } - | MODULE REC module_rec_bindings + { mkstr(Pstr_type (List.rev $2) ) } + | EXCEPTION exception_declaration + { mkstr(Pstr_exception $2) } + | EXCEPTION UIDENT EQUAL constr_longident post_item_attributes + { mkstr(Pstr_exn_rebind(mkrhs $2 2, mkloc $4 (rhs_loc 4), $5)) } + | MODULE module_binding + { mkstr(Pstr_module $2) } + | MODULE REC module_bindings { mkstr(Pstr_recmodule(List.rev $3)) } - | MODULE TYPE ident EQUAL module_type - { mkstr(Pstr_modtype(mkrhs $3 3, $5)) } - | OPEN override_flag mod_longident - { mkstr(Pstr_open ($2, mkrhs $3 3)) } + | MODULE TYPE ident post_item_attributes + { mkstr(Pstr_modtype (Mtd.mk (mkrhs $3 3) ~attrs:$4)) } + | MODULE TYPE ident EQUAL module_type post_item_attributes + { mkstr(Pstr_modtype (Mtd.mk (mkrhs $3 3) ~typ:$5 ~attrs:$6)) } + | OPEN override_flag mod_longident post_item_attributes + { mkstr(Pstr_open ($2, mkrhs $3 3, $4)) } | CLASS class_declarations { mkstr(Pstr_class (List.rev $2)) } | CLASS TYPE class_type_declarations { mkstr(Pstr_class_type (List.rev $3)) } - | INCLUDE module_expr - { mkstr(Pstr_include $2) } + | INCLUDE module_expr post_item_attributes + { mkstr(Pstr_include ($2, $3)) } + | item_extension post_item_attributes + { mkstr(Pstr_extension ($1, $2)) } ; -module_binding: +module_binding_body: EQUAL module_expr { $2 } | COLON module_type EQUAL module_expr { mkmod(Pmod_constraint($4, $2)) } - | LPAREN UIDENT COLON module_type RPAREN module_binding + | LPAREN UIDENT COLON module_type RPAREN module_binding_body { mkmod(Pmod_functor(mkrhs $2 2, $4, $6)) } ; -module_rec_bindings: - module_rec_binding { [$1] } - | module_rec_bindings AND module_rec_binding { $3 :: $1 } +module_bindings: + module_binding { [$1] } + | module_bindings AND module_binding { $3 :: $1 } ; -module_rec_binding: - UIDENT COLON module_type EQUAL module_expr { (mkrhs $1 1, $3, $5) } +module_binding: + UIDENT module_binding_body post_item_attributes + { Mb.mk (mkrhs $1 1) $2 ~attrs:$3 } ; /* Module types */ @@ -625,7 +653,7 @@ module_type: mty_longident { mkmty(Pmty_ident (mkrhs $1 1)) } | SIG signature END - { mkmty(Pmty_signature(List.rev $2)) } + { mkmty(Pmty_signature $2) } | SIG signature error { unclosed "sig" 1 "end" 3 } | FUNCTOR LPAREN UIDENT COLON module_type RPAREN MINUSGREATER module_type @@ -633,45 +661,59 @@ module_type: { mkmty(Pmty_functor(mkrhs $3 3, $5, $8)) } | module_type WITH with_constraints { mkmty(Pmty_with($1, List.rev $3)) } - | MODULE TYPE OF module_expr + | MODULE TYPE OF module_expr %prec below_LBRACKETAT { mkmty(Pmty_typeof $4) } | LPAREN module_type RPAREN { $2 } | LPAREN module_type error { unclosed "(" 1 ")" 3 } + | extension + { mkmty(Pmty_extension $1) } + | module_type attribute + { Mty.attr $1 $2 } ; signature: - /* empty */ { [] } - | signature signature_item { $2 :: $1 } - | signature signature_item SEMISEMI { $2 :: $1 } + sig_attribute signature { $1 :: $2 } + | signature_tail { $1 } +; +signature_tail: + /* empty */ { [] } + | SEMISEMI signature { $2 } + | signature_item signature_tail { $1 :: $2 } +; +sig_attribute: + post_item_attribute { mksig(Psig_attribute $1) } ; signature_item: - VAL val_ident COLON core_type - { mksig(Psig_value(mkrhs $2 2, {pval_type = $4; pval_prim = []; - pval_loc = symbol_rloc()})) } - | EXTERNAL val_ident COLON core_type EQUAL primitive_declaration - { mksig(Psig_value(mkrhs $2 2, {pval_type = $4; pval_prim = $6; - pval_loc = symbol_rloc()})) } + VAL val_ident COLON core_type post_item_attributes + { mksig(Psig_value + (Val.mk (mkrhs $2 2) $4 ~attrs:$5 ~loc:(symbol_rloc()))) } + | EXTERNAL val_ident COLON core_type EQUAL primitive_declaration post_item_attributes + { mksig(Psig_value + (Val.mk (mkrhs $2 2) $4 ~prim:$6 ~attrs:$7 + ~loc:(symbol_rloc()))) } | TYPE type_declarations - { mksig(Psig_type(List.rev $2)) } - | EXCEPTION UIDENT constructor_arguments - { mksig(Psig_exception(mkrhs $2 2, $3)) } - | MODULE UIDENT module_declaration - { mksig(Psig_module(mkrhs $2 2, $3)) } + { mksig(Psig_type (List.rev $2)) } + | EXCEPTION exception_declaration + { mksig(Psig_exception $2) } + | MODULE UIDENT module_declaration post_item_attributes + { mksig(Psig_module (Md.mk (mkrhs $2 2) $3 ~attrs:$4)) } | MODULE REC module_rec_declarations - { mksig(Psig_recmodule(List.rev $3)) } - | MODULE TYPE ident - { mksig(Psig_modtype(mkrhs $3 3, Pmodtype_abstract)) } - | MODULE TYPE ident EQUAL module_type - { mksig(Psig_modtype(mkrhs $3 3, Pmodtype_manifest $5)) } - | OPEN override_flag mod_longident - { mksig(Psig_open ($2, mkrhs $3 3)) } - | INCLUDE module_type - { mksig(Psig_include $2) } + { mksig(Psig_recmodule (List.rev $3)) } + | MODULE TYPE ident post_item_attributes + { mksig(Psig_modtype (Mtd.mk (mkrhs $3 3) ~attrs:$4)) } + | MODULE TYPE ident EQUAL module_type post_item_attributes + { mksig(Psig_modtype (Mtd.mk (mkrhs $3 3) ~typ:$5 ~attrs:$6)) } + | OPEN override_flag mod_longident post_item_attributes + { mksig(Psig_open ($2, mkrhs $3 3, $4)) } + | INCLUDE module_type post_item_attributes %prec below_WITH + { mksig(Psig_include ($2, $3)) } | CLASS class_descriptions { mksig(Psig_class (List.rev $2)) } | CLASS TYPE class_type_declarations { mksig(Psig_class_type (List.rev $3)) } + | item_extension post_item_attributes + { mksig(Psig_extension ($1, $2)) } ; module_declaration: @@ -685,7 +727,8 @@ module_rec_declarations: | module_rec_declarations AND module_rec_declaration { $3 :: $1 } ; module_rec_declaration: - UIDENT COLON module_type { (mkrhs $1 1, $3) } + UIDENT COLON module_type post_item_attributes + { Md.mk (mkrhs $1 1) $3 ~attrs:$4 } ; /* Class expressions */ @@ -695,11 +738,12 @@ class_declarations: | class_declaration { [$1] } ; class_declaration: - virtual_flag class_type_parameters LIDENT class_fun_binding - { let params, variance = List.split (fst $2) in - {pci_virt = $1; pci_params = params, snd $2; - pci_name = mkrhs $3 3; pci_expr = $4; pci_variance = variance; - pci_loc = symbol_rloc ()} } + virtual_flag class_type_parameters LIDENT class_fun_binding post_item_attributes + { + Ci.mk (mkrhs $3 3) $4 + ~virt:$1 ~params:$2 + ~attrs:$5 ~loc:(symbol_rloc ()) + } ; class_fun_binding: EQUAL class_expr @@ -710,8 +754,8 @@ class_fun_binding: { let (l,o,p) = $1 in mkclass(Pcl_fun(l, o, p, $2)) } ; class_type_parameters: - /*empty*/ { [], symbol_gloc () } - | LBRACKET type_parameter_list RBRACKET { List.rev $2, symbol_rloc () } + /*empty*/ { [] } + | LBRACKET type_parameter_list RBRACKET { List.rev $2 } ; class_fun_def: labeled_simple_pattern MINUSGREATER class_expr @@ -728,6 +772,10 @@ class_expr: { mkclass(Pcl_apply($1, List.rev $2)) } | LET rec_flag let_bindings IN class_expr { mkclass(Pcl_let ($2, List.rev $3, $5)) } + | class_expr attribute + { Cl.attr $1 $2 } + | extension + { mkclass(Pcl_extension $1) } ; class_simple_expr: LBRACKET core_type_comma_list RBRACKET class_longident @@ -749,7 +797,7 @@ class_simple_expr: ; class_structure: class_self_pattern class_fields - { { pcstr_pat = $1; pcstr_fields = List.rev $2 } } + { Cstr.mk $1 (List.rev $2) } ; class_self_pattern: LPAREN pattern RPAREN @@ -767,19 +815,18 @@ class_fields: ; class_field: | INHERIT override_flag class_expr parent_binder - { mkcf (Pcf_inher ($2, $3, $4)) } - | VAL virtual_value - { mkcf (Pcf_valvirt $2) } + { mkcf (Pcf_inherit ($2, $3, $4)) } | VAL value { mkcf (Pcf_val $2) } - | virtual_method - { mkcf (Pcf_virt $1) } - | concrete_method - { mkcf (Pcf_meth $1) } + | METHOD method_ + { mkcf (Pcf_method $2) } | CONSTRAINT constrain_field - { mkcf (Pcf_constr $2) } + { mkcf (Pcf_constraint $2) } | INITIALIZER seq_expr - { mkcf (Pcf_init $2) } + { mkcf (Pcf_initializer $2) } + | class_field post_item_attribute + { Cf.attr $1 $2 } + | item_extension { mkcf(Pcf_extension $1) } ; parent_binder: AS LIDENT @@ -787,37 +834,37 @@ parent_binder: | /* empty */ { None } ; -virtual_value: +value: +/* TODO: factorize these rules (also with method): */ override_flag MUTABLE VIRTUAL label COLON core_type { if $1 = Override then syntax_error (); - mkloc $4 (rhs_loc 4), Mutable, $6 } + mkloc $4 (rhs_loc 4), Mutable, Cfk_virtual $6 } | VIRTUAL mutable_flag label COLON core_type - { mkrhs $3 3, $2, $5 } -; -value: - override_flag mutable_flag label EQUAL seq_expr - { mkrhs $3 3, $2, $1, $5 } + { mkrhs $3 3, $2, Cfk_virtual $5 } + | override_flag mutable_flag label EQUAL seq_expr + { mkrhs $3 3, $2, Cfk_concrete ($1, $5) } | override_flag mutable_flag label type_constraint EQUAL seq_expr - { let (t, t') = $4 in - mkrhs $3 3, $2, $1, ghexp(Pexp_constraint($6, t, t')) } -; -virtual_method: - METHOD override_flag PRIVATE VIRTUAL label COLON poly_type - { if $2 = Override then syntax_error (); - mkloc $5 (rhs_loc 5), Private, $7 } - | METHOD override_flag VIRTUAL private_flag label COLON poly_type - { if $2 = Override then syntax_error (); - mkloc $5 (rhs_loc 5), $4, $7 } -; -concrete_method : - METHOD override_flag private_flag label strict_binding - { mkloc $4 (rhs_loc 4), $3, $2, ghexp(Pexp_poly ($5, None)) } - | METHOD override_flag private_flag label COLON poly_type EQUAL seq_expr - { mkloc $4 (rhs_loc 4), $3, $2, ghexp(Pexp_poly($8,Some $6)) } - | METHOD override_flag private_flag label COLON TYPE lident_list + { + let e = mkexp_constraint $6 $4 in + mkrhs $3 3, $2, Cfk_concrete ($1, e) + } +; +method_: +/* TODO: factorize those rules... */ + override_flag PRIVATE VIRTUAL label COLON poly_type + { if $1 = Override then syntax_error (); + mkloc $4 (rhs_loc 4), Private, Cfk_virtual $6 } + | override_flag VIRTUAL private_flag label COLON poly_type + { if $1 = Override then syntax_error (); + mkloc $4 (rhs_loc 4), $3, Cfk_virtual $6 } + | override_flag private_flag label strict_binding + { mkloc $3 (rhs_loc 3), $2, Cfk_concrete ($1, ghexp(Pexp_poly ($4, None))) } + | override_flag private_flag label COLON poly_type EQUAL seq_expr + { mkloc $3 (rhs_loc 3), $2, Cfk_concrete ($1, ghexp(Pexp_poly($7, Some $5))) } + | override_flag private_flag label COLON TYPE lident_list DOT core_type EQUAL seq_expr - { let exp, poly = wrap_type_annotation $7 $9 $11 in - mkloc $4 (rhs_loc 4), $3, $2, ghexp(Pexp_poly(exp, Some poly)) } + { let exp, poly = wrap_type_annotation $6 $8 $10 in + mkloc $3 (rhs_loc 3), $2, Cfk_concrete ($1, ghexp(Pexp_poly(exp, Some poly))) } ; /* Class types */ @@ -825,14 +872,18 @@ concrete_method : class_type: class_signature { $1 } - | QUESTION LIDENT COLON simple_core_type_or_tuple MINUSGREATER class_type - { mkcty(Pcty_fun("?" ^ $2 , mkoption $4, $6)) } - | OPTLABEL simple_core_type_or_tuple MINUSGREATER class_type - { mkcty(Pcty_fun("?" ^ $1, mkoption $2, $4)) } - | LIDENT COLON simple_core_type_or_tuple MINUSGREATER class_type - { mkcty(Pcty_fun($1, $3, $5)) } - | simple_core_type_or_tuple MINUSGREATER class_type - { mkcty(Pcty_fun("", $1, $3)) } + | QUESTION LIDENT COLON simple_core_type_or_tuple_no_attr MINUSGREATER class_type + { mkcty(Pcty_arrow("?" ^ $2 , mkoption $4, $6)) } + | OPTLABEL simple_core_type_or_tuple_no_attr MINUSGREATER class_type + { mkcty(Pcty_arrow("?" ^ $1, mkoption $2, $4)) } + | LIDENT COLON simple_core_type_or_tuple_no_attr MINUSGREATER class_type + { mkcty(Pcty_arrow($1, $3, $5)) } + | simple_core_type_or_tuple_no_attr MINUSGREATER class_type + { mkcty(Pcty_arrow("", $1, $3)) } + | class_type attribute + { Cty.attr $1 $2 } + | extension + { mkcty(Pcty_extension $1) } ; class_signature: LBRACKET core_type_comma_list RBRACKET clty_longident @@ -846,8 +897,7 @@ class_signature: ; class_sig_body: class_self_type class_sig_fields - { { pcsig_self = $1; pcsig_fields = List.rev $2; - pcsig_loc = symbol_rloc(); } } + { Csig.mk $1 (List.rev $2) } ; class_self_type: LPAREN core_type RPAREN @@ -860,11 +910,16 @@ class_sig_fields: | class_sig_fields class_sig_field { $2 :: $1 } ; class_sig_field: - INHERIT class_signature { mkctf (Pctf_inher $2) } + INHERIT class_signature { mkctf (Pctf_inherit $2) } | VAL value_type { mkctf (Pctf_val $2) } - | virtual_method_type { mkctf (Pctf_virt $1) } - | method_type { mkctf (Pctf_meth $1) } - | CONSTRAINT constrain_field { mkctf (Pctf_cstr $2) } + | METHOD private_virtual_flags label COLON poly_type + { + let (p, v) = $2 in + mkctf (Pctf_method ($3, p, v, $5)) + } + | CONSTRAINT constrain_field { mkctf (Pctf_constraint $2) } + | class_sig_field post_item_attribute { Ctf.attr $1 $2 } + | item_extension { mkctf(Pctf_extension $1) } ; value_type: VIRTUAL mutable_flag label COLON core_type @@ -874,16 +929,6 @@ value_type: | label COLON core_type { $1, Immutable, Concrete, $3 } ; -method_type: - METHOD private_flag label COLON poly_type - { $3, $2, $5 } -; -virtual_method_type: - METHOD PRIVATE VIRTUAL label COLON poly_type - { $4, Private, $6 } - | METHOD VIRTUAL private_flag label COLON poly_type - { $4, $3, $6 } -; constrain: core_type EQUAL core_type { $1, $3, symbol_rloc() } ; @@ -895,22 +940,24 @@ class_descriptions: | class_description { [$1] } ; class_description: - virtual_flag class_type_parameters LIDENT COLON class_type - { let params, variance = List.split (fst $2) in - {pci_virt = $1; pci_params = params, snd $2; - pci_name = mkrhs $3 3; pci_expr = $5; pci_variance = variance; - pci_loc = symbol_rloc ()} } + virtual_flag class_type_parameters LIDENT COLON class_type post_item_attributes + { + Ci.mk (mkrhs $3 3) $5 + ~virt:$1 ~params:$2 + ~attrs:$6 ~loc:(symbol_rloc ()) + } ; class_type_declarations: class_type_declarations AND class_type_declaration { $3 :: $1 } | class_type_declaration { [$1] } ; class_type_declaration: - virtual_flag class_type_parameters LIDENT EQUAL class_signature - { let params, variance = List.split (fst $2) in - {pci_virt = $1; pci_params = params, snd $2; - pci_name = mkrhs $3 3; pci_expr = $5; pci_variance = variance; - pci_loc = symbol_rloc ()} } + virtual_flag class_type_parameters LIDENT EQUAL class_signature post_item_attributes + { + Ci.mk (mkrhs $3 3) $5 + ~virt:$1 ~params:$2 + ~attrs:$6 ~loc:(symbol_rloc ()) + } ; /* Core expressions */ @@ -966,38 +1013,39 @@ expr: { $1 } | simple_expr simple_labeled_expr_list { mkexp(Pexp_apply($1, List.rev $2)) } - | LET rec_flag let_bindings IN seq_expr - { mkexp(Pexp_let($2, List.rev $3, $5)) } - | LET MODULE UIDENT module_binding IN seq_expr - { mkexp(Pexp_letmodule(mkrhs $3 3, $4, $6)) } - | LET OPEN override_flag mod_longident IN seq_expr - { mkexp(Pexp_open($3, mkrhs $4 4, $6)) } - | FUNCTION opt_bar match_cases - { mkexp(Pexp_function("", None, List.rev $3)) } - | FUN labeled_simple_pattern fun_def - { let (l,o,p) = $2 in mkexp(Pexp_function(l, o, [p, $3])) } - | FUN LPAREN TYPE LIDENT RPAREN fun_def - { mkexp(Pexp_newtype($4, $6)) } - | MATCH seq_expr WITH opt_bar match_cases - { mkexp(Pexp_match($2, List.rev $5)) } - | TRY seq_expr WITH opt_bar match_cases - { mkexp(Pexp_try($2, List.rev $5)) } - | TRY seq_expr WITH error + | LET ext_attributes rec_flag let_bindings IN seq_expr + { mkexp_attrs (Pexp_let($3, List.rev $4, $6)) $2 } + | LET MODULE ext_attributes UIDENT module_binding_body IN seq_expr + { mkexp_attrs (Pexp_letmodule(mkrhs $4 4, $5, $7)) $3 } + | LET OPEN override_flag ext_attributes mod_longident IN seq_expr + { mkexp_attrs (Pexp_open($3, mkrhs $5 5, $7)) $4 } + | FUNCTION ext_attributes opt_bar match_cases + { mkexp_attrs (Pexp_function(List.rev $4)) $2 } + | FUN ext_attributes labeled_simple_pattern fun_def + { let (l,o,p) = $3 in + mkexp_attrs (Pexp_fun(l, o, p, $4)) $2 } + | FUN ext_attributes LPAREN TYPE LIDENT RPAREN fun_def + { mkexp_attrs (Pexp_newtype($5, $7)) $2 } + | MATCH ext_attributes seq_expr WITH opt_bar match_cases + { mkexp_attrs (Pexp_match($3, List.rev $6)) $2 } + | TRY ext_attributes seq_expr WITH opt_bar match_cases + { mkexp_attrs (Pexp_try($3, List.rev $6)) $2 } + | TRY ext_attributes seq_expr WITH error { syntax_error() } | expr_comma_list %prec below_COMMA { mkexp(Pexp_tuple(List.rev $1)) } | constr_longident simple_expr %prec below_SHARP - { mkexp(Pexp_construct(mkrhs $1 1, Some $2, false)) } + { mkexp(Pexp_construct(mkrhs $1 1, Some $2)) } | name_tag simple_expr %prec below_SHARP { mkexp(Pexp_variant($1, Some $2)) } - | IF seq_expr THEN expr ELSE expr - { mkexp(Pexp_ifthenelse($2, $4, Some $6)) } - | IF seq_expr THEN expr - { mkexp(Pexp_ifthenelse($2, $4, None)) } - | WHILE seq_expr DO seq_expr DONE - { mkexp(Pexp_while($2, $4)) } - | FOR val_ident EQUAL seq_expr direction_flag seq_expr DO seq_expr DONE - { mkexp(Pexp_for(mkrhs $2 2, $4, $6, $5, $8)) } + | IF ext_attributes seq_expr THEN expr ELSE expr + { mkexp_attrs(Pexp_ifthenelse($3, $5, Some $7)) $2 } + | IF ext_attributes seq_expr THEN expr + { mkexp_attrs (Pexp_ifthenelse($3, $5, None)) $2 } + | WHILE ext_attributes seq_expr DO seq_expr DONE + { mkexp_attrs (Pexp_while($3, $5)) $2 } + | FOR ext_attributes val_ident EQUAL seq_expr direction_flag seq_expr DO seq_expr DONE + { mkexp_attrs(Pexp_for(mkrhs $3 3, $5, $7, $6, $9)) $2 } | expr COLONCOLON expr { mkexp_cons (rhs_loc 2) (ghexp(Pexp_tuple[$1;$3])) (symbol_rloc()) } | LPAREN COLONCOLON RPAREN LPAREN expr COMMA expr RPAREN @@ -1022,6 +1070,8 @@ expr: { mkinfix $1 "-." $3 } | expr STAR expr { mkinfix $1 "*" $3 } + | expr PERCENT expr + { mkinfix $1 "%" $3 } | expr EQUAL expr { mkinfix $1 "=" $3 } | expr LESS expr @@ -1054,14 +1104,16 @@ expr: { bigarray_set $1 $4 $7 } | label LESSMINUS expr { mkexp(Pexp_setinstvar(mkrhs $1 1, $3)) } - | ASSERT simple_expr %prec below_SHARP - { mkassert $2 } - | LAZY simple_expr %prec below_SHARP - { mkexp (Pexp_lazy ($2)) } - | OBJECT class_structure END - { mkexp (Pexp_object($2)) } - | OBJECT class_structure error + | ASSERT ext_attributes simple_expr %prec below_SHARP + { mkexp_attrs (Pexp_assert $3) $2 } + | LAZY ext_attributes simple_expr %prec below_SHARP + { mkexp_attrs (Pexp_lazy $3) $2 } + | OBJECT ext_attributes class_structure END + { mkexp_attrs (Pexp_object $3) $2 } + | OBJECT ext_attributes class_structure error { unclosed "object" 1 "end" 3 } + | expr attribute + { Exp.attr $1 $2 } ; simple_expr: val_longident @@ -1069,22 +1121,22 @@ simple_expr: | constant { mkexp(Pexp_constant $1) } | constr_longident %prec prec_constant_constructor - { mkexp(Pexp_construct(mkrhs $1 1, None, false)) } + { mkexp(Pexp_construct(mkrhs $1 1, None)) } | name_tag %prec prec_constant_constructor { mkexp(Pexp_variant($1, None)) } | LPAREN seq_expr RPAREN { reloc_exp $2 } | LPAREN seq_expr error { unclosed "(" 1 ")" 3 } - | BEGIN seq_expr END - { reloc_exp $2 } - | BEGIN END - { mkexp (Pexp_construct (mkloc (Lident "()") (symbol_rloc ()), - None, false)) } - | BEGIN seq_expr error + | BEGIN ext_attributes seq_expr END + { wrap_exp_attrs (reloc_exp $3) $2 (* check location *) } + | BEGIN ext_attributes END + { mkexp_attrs (Pexp_construct (mkloc (Lident "()") (symbol_rloc ()), + None)) $2 } + | BEGIN ext_attributes seq_expr error { unclosed "begin" 1 "end" 3 } | LPAREN seq_expr type_constraint RPAREN - { let (t, t') = $3 in mkexp(Pexp_constraint($2, t, t')) } + { mkexp_constraint $2 $3 } | simple_expr DOT label_longident { mkexp(Pexp_field($1, mkrhs $3 3)) } | mod_longident DOT LPAREN seq_expr RPAREN @@ -1106,15 +1158,15 @@ simple_expr: | simple_expr DOT LBRACE expr_comma_list error { unclosed "{" 3 "}" 5 } | LBRACE record_expr RBRACE - { let (exten, fields) = $2 in mkexp(Pexp_record(fields, exten)) } + { let (exten, fields) = $2 in mkexp (Pexp_record(fields, exten)) } | LBRACE record_expr error { unclosed "{" 1 "}" 3 } | LBRACKETBAR expr_semi_list opt_semi BARRBRACKET - { mkexp(Pexp_array(List.rev $2)) } + { mkexp (Pexp_array(List.rev $2)) } | LBRACKETBAR expr_semi_list opt_semi error { unclosed "[|" 1 "|]" 4 } | LBRACKETBAR BARRBRACKET - { mkexp(Pexp_array []) } + { mkexp (Pexp_array []) } | LBRACKET expr_semi_list opt_semi RBRACKET { reloc_exp (mktailexp (rhs_loc 4) (List.rev $2)) } | LBRACKET expr_semi_list opt_semi error @@ -1123,23 +1175,25 @@ simple_expr: { mkexp(Pexp_apply(mkoperator $1 1, ["",$2])) } | BANG simple_expr { mkexp(Pexp_apply(mkoperator "!" 1, ["",$2])) } - | NEW class_longident - { mkexp(Pexp_new(mkrhs $2 2)) } + | NEW ext_attributes class_longident + { mkexp_attrs (Pexp_new(mkrhs $3 3)) $2 } | LBRACELESS field_expr_list opt_semi GREATERRBRACE - { mkexp(Pexp_override(List.rev $2)) } + { mkexp (Pexp_override(List.rev $2)) } | LBRACELESS field_expr_list opt_semi error { unclosed "{<" 1 ">}" 4 } | LBRACELESS GREATERRBRACE - { mkexp(Pexp_override []) } + { mkexp (Pexp_override [])} | simple_expr SHARP label { mkexp(Pexp_send($1, $3)) } | LPAREN MODULE module_expr RPAREN { mkexp (Pexp_pack $3) } | LPAREN MODULE module_expr COLON package_type RPAREN { mkexp (Pexp_constraint (ghexp (Pexp_pack $3), - Some (ghtyp (Ptyp_package $5)), None)) } + ghtyp (Ptyp_package $5))) } | LPAREN MODULE module_expr COLON error { unclosed "(" 1 ")" 5 } + | extension + { mkexp (Pexp_extension $1) } ; simple_labeled_expr_list: labeled_simple_expr @@ -1176,6 +1230,9 @@ lident_list: | LIDENT lident_list { $1 :: $2 } ; let_binding: + let_binding_ post_item_attributes { let (p, e) = $1 in Vb.mk ~attrs:$2 p e } +; +let_binding_: val_ident fun_binding { (mkpatvar $1 1, $2) } | val_ident COLON typevar_list DOT core_type EQUAL seq_expr @@ -1192,31 +1249,37 @@ fun_binding: strict_binding { $1 } | type_constraint EQUAL seq_expr - { let (t, t') = $1 in ghexp(Pexp_constraint($3, t, t')) } + { mkexp_constraint $3 $1 } ; strict_binding: EQUAL seq_expr { $2 } | labeled_simple_pattern fun_binding - { let (l, o, p) = $1 in ghexp(Pexp_function(l, o, [p, $2])) } + { let (l, o, p) = $1 in ghexp(Pexp_fun(l, o, p, $2)) } | LPAREN TYPE LIDENT RPAREN fun_binding { mkexp(Pexp_newtype($3, $5)) } ; match_cases: - pattern match_action { [$1, $2] } - | match_cases BAR pattern match_action { ($3, $4) :: $1 } + match_case { [$1] } + | match_cases BAR match_case { $3 :: $1 } +; +match_case: + pattern MINUSGREATER seq_expr + { Exp.case $1 $3 } + | pattern WHEN seq_expr MINUSGREATER seq_expr + { Exp.case $1 ~guard:$3 $5 } ; fun_def: - match_action { $1 } + MINUSGREATER seq_expr { $2 } +/* Cf #5939: we used to accept (fun p when e0 -> e) */ | labeled_simple_pattern fun_def - { let (l,o,p) = $1 in ghexp(Pexp_function(l, o, [p, $2])) } + { + let (l,o,p) = $1 in + ghexp(Pexp_fun(l, o, p, $2)) + } | LPAREN TYPE LIDENT RPAREN fun_def { mkexp(Pexp_newtype($3, $5)) } ; -match_action: - MINUSGREATER seq_expr { $2 } - | WHEN seq_expr MINUSGREATER seq_expr { ghexp(Pexp_when($2, $4)) } -; expr_comma_list: expr_comma_list COMMA expr { $3 :: $1 } | expr COMMA expr { [$3; $1] } @@ -1266,7 +1329,7 @@ pattern: | pattern_comma_list %prec below_COMMA { mkpat(Ppat_tuple(List.rev $1)) } | constr_longident pattern %prec prec_constr_appl - { mkpat(Ppat_construct(mkrhs $1 1, Some $2, false)) } + { mkpat(Ppat_construct(mkrhs $1 1, Some $2)) } | name_tag pattern %prec prec_constr_appl { mkpat(Ppat_variant($1, Some $2)) } | pattern COLONCOLON pattern @@ -1283,6 +1346,8 @@ pattern: { expecting 3 "pattern" } | LAZY simple_pattern { mkpat(Ppat_lazy $2) } + | pattern attribute + { Pat.attr $1 $2 } ; simple_pattern: val_ident %prec below_EQUAL @@ -1291,10 +1356,10 @@ simple_pattern: { mkpat(Ppat_any) } | signed_constant { mkpat(Ppat_constant $1) } - | CHAR DOTDOT CHAR - { mkrangepat $1 $3 } + | signed_constant DOTDOT signed_constant + { mkpat(Ppat_interval ($1, $3)) } | constr_longident - { mkpat(Ppat_construct(mkrhs $1 1, None, false)) } + { mkpat(Ppat_construct(mkrhs $1 1, None)) } | name_tag { mkpat(Ppat_variant($1, None)) } | SHARP type_longident @@ -1330,6 +1395,8 @@ simple_pattern: ghtyp(Ptyp_package $5))) } | LPAREN MODULE UIDENT COLON package_type error { unclosed "(" 1 ")" 6 } + | extension + { mkpat(Ppat_extension $1) } ; pattern_comma_list: @@ -1358,8 +1425,8 @@ lbl_pattern: /* Primitive declarations */ primitive_declaration: - STRING { [$1] } - | STRING primitive_declaration { $1 :: $2 } + STRING { [fst $1] } + | STRING primitive_declaration { fst $1 :: $2 } ; /* Type declarations */ @@ -1370,16 +1437,12 @@ type_declarations: ; type_declaration: - optional_type_parameters LIDENT type_kind constraints - { let (params, variance) = List.split $1 in - let (kind, private_flag, manifest) = $3 in - (mkrhs $2 2, {ptype_params = params; - ptype_cstrs = List.rev $4; - ptype_kind = kind; - ptype_private = private_flag; - ptype_manifest = manifest; - ptype_variance = variance; - ptype_loc = symbol_rloc() }) } + optional_type_parameters LIDENT type_kind constraints post_item_attributes + { let (kind, priv, manifest) = $3 in + Type.mk (mkrhs $2 2) + ~params:$1 ~cstrs:(List.rev $4) + ~kind ~priv ?manifest ~attrs:$5 ~loc:(symbol_rloc()) + } ; constraints: constraints CONSTRAINT constrain { $3 :: $1 } @@ -1430,9 +1493,9 @@ type_parameter: type_variance QUOTE ident { mkrhs $3 3, $1 } ; type_variance: - /* empty */ { false, false } - | PLUS { true, false } - | MINUS { false, true } + /* empty */ { Invariant } + | PLUS { Covariant } + | MINUS { Contravariant } ; type_parameter_list: type_parameter { [$1] } @@ -1443,23 +1506,26 @@ constructor_declarations: | constructor_declarations BAR constructor_declaration { $3 :: $1 } ; constructor_declaration: - - | constr_ident generalized_constructor_arguments - { let arg_types,ret_type = $2 in - (mkrhs $1 1, arg_types,ret_type, symbol_rloc()) } -; - -constructor_arguments: - /*empty*/ { [] } - | OF core_type_list { List.rev $2 } + | constr_ident attributes generalized_constructor_arguments + { + let args,res = $3 in + Type.constructor (mkrhs $1 1) ~args ?res ~loc:(symbol_rloc()) ~attrs:$2 + } +; +exception_declaration: + | constructor_declaration post_item_attributes + { + let cd = $1 in + {cd with pcd_attributes = cd.pcd_attributes @ $2} + } ; - generalized_constructor_arguments: /*empty*/ { ([],None) } | OF core_type_list { (List.rev $2,None) } | COLON core_type_list MINUSGREATER simple_core_type { (List.rev $2,Some $4) } - | COLON simple_core_type { ([],Some $2) } + | COLON simple_core_type + { ([],Some $2) } ; @@ -1469,8 +1535,10 @@ label_declarations: | label_declarations SEMI label_declaration { $3 :: $1 } ; label_declaration: - mutable_flag label COLON poly_type - { (mkrhs $2 2, $1, $4, symbol_rloc()) } + mutable_flag label attributes COLON poly_type + { + Type.field (mkrhs $2 2) $5 ~mut:$1 ~attrs:$3 ~loc:(symbol_rloc()) + } ; /* "with" constraints (additional type equations over signature components) */ @@ -1481,31 +1549,26 @@ with_constraints: ; with_constraint: TYPE type_parameters label_longident with_type_binder core_type constraints - { let params, variance = List.split $2 in - (mkrhs $3 3, - Pwith_type {ptype_params = List.map (fun x -> Some x) params; - ptype_cstrs = List.rev $6; - ptype_kind = Ptype_abstract; - ptype_manifest = Some $5; - ptype_private = $4; - ptype_variance = variance; - ptype_loc = symbol_rloc()}) } + { Pwith_type + (mkrhs $3 3, + (Type.mk (mkrhs (Longident.last $3) 3) + ~params:(List.map (fun (x, v) -> Some x, v) $2) + ~cstrs:(List.rev $6) + ~manifest:$5 + ~priv:$4 + ~loc:(symbol_rloc()))) } /* used label_longident instead of type_longident to disallow functor applications in type path */ | TYPE type_parameters label COLONEQUAL core_type - { let params, variance = List.split $2 in - (mkrhs (Lident $3) 3, - Pwith_typesubst { ptype_params = List.map (fun x -> Some x) params; - ptype_cstrs = []; - ptype_kind = Ptype_abstract; - ptype_manifest = Some $5; - ptype_private = Public; - ptype_variance = variance; - ptype_loc = symbol_rloc()}) } + { Pwith_typesubst + (Type.mk (mkrhs $3 3) + ~params:(List.map (fun (x, v) -> Some x, v) $2) + ~manifest:$5 + ~loc:(symbol_rloc())) } | MODULE mod_longident EQUAL mod_ext_longident - { (mkrhs $2 2, Pwith_module (mkrhs $4 4)) } + { Pwith_module (mkrhs $2 2, mkrhs $4 4) } | MODULE UIDENT COLONEQUAL mod_ext_longident - { (mkrhs (Lident $2) 2, Pwith_modsubst (mkrhs $4 4)) } + { Pwith_modsubst (mkrhs $2 2, mkrhs $4 4) } ; with_type_binder: EQUAL { Public } @@ -1520,7 +1583,7 @@ typevar_list: ; poly_type: core_type - { mktyp(Ptyp_poly([], $1)) } + { $1 } | typevar_list DOT core_type { mktyp(Ptyp_poly(List.rev $1, $3)) } ; @@ -1551,7 +1614,17 @@ simple_core_type: { $1 } | LPAREN core_type_comma_list RPAREN %prec below_SHARP { match $2 with [sty] -> sty | _ -> raise Parse_error } + | simple_core_type attribute + { Typ.attr $1 $2 } +; + +simple_core_type_no_attr: + simple_core_type2 %prec below_SHARP + { $1 } + | LPAREN core_type_comma_list RPAREN %prec below_SHARP + { match $2 with [sty] -> sty | _ -> raise Parse_error } ; + simple_core_type2: QUOTE ident { mktyp(Ptyp_var $2) } @@ -1564,35 +1637,37 @@ simple_core_type2: | LPAREN core_type_comma_list RPAREN type_longident { mktyp(Ptyp_constr(mkrhs $4 4, List.rev $2)) } | LESS meth_list GREATER - { mktyp(Ptyp_object $2) } + { let (f, c) = $2 in mktyp(Ptyp_object (f, c)) } | LESS GREATER - { mktyp(Ptyp_object []) } - | SHARP class_longident opt_present - { mktyp(Ptyp_class(mkrhs $2 2, [], $3)) } - | simple_core_type2 SHARP class_longident opt_present - { mktyp(Ptyp_class(mkrhs $3 3, [$1], $4)) } - | LPAREN core_type_comma_list RPAREN SHARP class_longident opt_present - { mktyp(Ptyp_class(mkrhs $5 5, List.rev $2, $6)) } + { mktyp(Ptyp_object ([], Closed)) } + | SHARP class_longident + { mktyp(Ptyp_class(mkrhs $2 2, [])) } + | simple_core_type2 SHARP class_longident + { mktyp(Ptyp_class(mkrhs $3 3, [$1])) } + | LPAREN core_type_comma_list RPAREN SHARP class_longident + { mktyp(Ptyp_class(mkrhs $5 5, List.rev $2)) } | LBRACKET tag_field RBRACKET - { mktyp(Ptyp_variant([$2], true, None)) } + { mktyp(Ptyp_variant([$2], Closed, None)) } /* PR#3835: this is not LR(1), would need lookahead=2 | LBRACKET simple_core_type RBRACKET - { mktyp(Ptyp_variant([$2], true, None)) } + { mktyp(Ptyp_variant([$2], Closed, None)) } */ | LBRACKET BAR row_field_list RBRACKET - { mktyp(Ptyp_variant(List.rev $3, true, None)) } + { mktyp(Ptyp_variant(List.rev $3, Closed, None)) } | LBRACKET row_field BAR row_field_list RBRACKET - { mktyp(Ptyp_variant($2 :: List.rev $4, true, None)) } + { mktyp(Ptyp_variant($2 :: List.rev $4, Closed, None)) } | LBRACKETGREATER opt_bar row_field_list RBRACKET - { mktyp(Ptyp_variant(List.rev $3, false, None)) } + { mktyp(Ptyp_variant(List.rev $3, Open, None)) } | LBRACKETGREATER RBRACKET - { mktyp(Ptyp_variant([], false, None)) } + { mktyp(Ptyp_variant([], Open, None)) } | LBRACKETLESS opt_bar row_field_list RBRACKET - { mktyp(Ptyp_variant(List.rev $3, true, Some [])) } + { mktyp(Ptyp_variant(List.rev $3, Closed, Some [])) } | LBRACKETLESS opt_bar row_field_list GREATER name_tag_list RBRACKET - { mktyp(Ptyp_variant(List.rev $3, true, Some (List.rev $5))) } + { mktyp(Ptyp_variant(List.rev $3, Closed, Some (List.rev $5))) } | LPAREN MODULE package_type RPAREN { mktyp(Ptyp_package $3) } + | extension + { mktyp (Ptyp_extension $1) } ; package_type: mty_longident { (mkrhs $1 1, []) } @@ -1627,34 +1702,40 @@ amper_type_list: core_type { [$1] } | amper_type_list AMPERSAND core_type { $3 :: $1 } ; -opt_present: - LBRACKETGREATER name_tag_list RBRACKET { List.rev $2 } - | /* empty */ { [] } -; name_tag_list: name_tag { [$1] } | name_tag_list name_tag { $2 :: $1 } ; simple_core_type_or_tuple: - simple_core_type { $1 } + simple_core_type %prec below_LBRACKETAT { $1 } | simple_core_type STAR core_type_list { mktyp(Ptyp_tuple($1 :: List.rev $3)) } ; +simple_core_type_or_tuple_no_attr: + simple_core_type_no_attr + { $1 } + | simple_core_type_no_attr STAR core_type_list_no_attr + { mktyp(Ptyp_tuple($1 :: List.rev $3)) } +; core_type_comma_list: core_type { [$1] } | core_type_comma_list COMMA core_type { $3 :: $1 } ; core_type_list: - simple_core_type { [$1] } + simple_core_type %prec below_LBRACKETAT { [$1] } | core_type_list STAR simple_core_type { $3 :: $1 } ; +core_type_list_no_attr: + simple_core_type_no_attr { [$1] } + | core_type_list STAR simple_core_type_no_attr { $3 :: $1 } +; meth_list: - field SEMI meth_list { $1 :: $3 } - | field opt_semi { [$1] } - | DOTDOT { [mkfield Pfield_var] } + field SEMI meth_list { let (f, c) = $3 in ($1 :: f, c) } + | field opt_semi { [$1], Closed } + | DOTDOT { [], Open } ; field: - label COLON poly_type { mkfield(Pfield($1, $3)) } + label COLON poly_type /* ok */ { ($1, $3) } ; label: LIDENT { $1 } @@ -1665,7 +1746,7 @@ label: constant: INT { Const_int $1 } | CHAR { Const_char $1 } - | STRING { Const_string $1 } + | STRING { let (s, d) = $1 in Const_string (s, d) } | FLOAT { Const_float $1 } | INT32 { Const_int32 $1 } | INT64 { Const_int64 $1 } @@ -1719,6 +1800,7 @@ operator: | AMPERSAND { "&" } | AMPERAMPER { "&&" } | COLONEQUAL { ":=" } + | PERCENT { "%" } ; constr_ident: UIDENT { $1 } @@ -1770,21 +1852,12 @@ class_longident: LIDENT { Lident $1 } | mod_longident DOT LIDENT { Ldot($1, $3) } ; -any_longident: - val_ident { Lident $1 } - | mod_ext_longident DOT val_ident { Ldot ($1, $3) } - | mod_ext_longident { $1 } - | LBRACKET RBRACKET { Lident "[]" } - | LPAREN RPAREN { Lident "()" } - | FALSE { Lident "false" } - | TRUE { Lident "true" } -; /* Toplevel directives */ toplevel_directive: SHARP ident { Ptop_dir($2, Pdir_none) } - | SHARP ident STRING { Ptop_dir($2, Pdir_string $3) } + | SHARP ident STRING { Ptop_dir($2, Pdir_string (fst $3)) } | SHARP ident INT { Ptop_dir($2, Pdir_int $3) } | SHARP ident val_longident { Ptop_dir($2, Pdir_ident $3) } | SHARP ident FALSE { Ptop_dir($2, Pdir_bool false) } @@ -1816,6 +1889,13 @@ virtual_flag: /* empty */ { Concrete } | VIRTUAL { Virtual } ; +private_virtual_flags: + /* empty */ { Public, Concrete } + | PRIVATE { Private, Concrete } + | VIRTUAL { Public, Virtual } + | PRIVATE VIRTUAL { Private, Virtual } + | VIRTUAL PRIVATE { Private, Virtual } +; override_flag: /* empty */ { Fresh } | BANG { Override } @@ -1836,4 +1916,96 @@ additive: | PLUS { "+" } | PLUSDOT { "+." } ; + +/* Attributes and extensions */ + +single_attr_id: + LIDENT { $1 } + | UIDENT { $1 } + | AND { "and" } + | AS { "as" } + | ASSERT { "assert" } + | BEGIN { "begin" } + | CLASS { "class" } + | CONSTRAINT { "constraint" } + | DO { "do" } + | DONE { "done" } + | DOWNTO { "downto" } + | ELSE { "else" } + | END { "end" } + | EXCEPTION { "exception" } + | EXTERNAL { "external" } + | FALSE { "false" } + | FOR { "for" } + | FUN { "fun" } + | FUNCTION { "function" } + | FUNCTOR { "functor" } + | IF { "if" } + | IN { "in" } + | INCLUDE { "include" } + | INHERIT { "inherit" } + | INITIALIZER { "initializer" } + | LAZY { "lazy" } + | LET { "let" } + | MATCH { "match" } + | METHOD { "method" } + | MODULE { "module" } + | MUTABLE { "mutable" } + | NEW { "new" } + | OBJECT { "object" } + | OF { "of" } + | OPEN { "open" } + | OR { "or" } + | PRIVATE { "private" } + | REC { "rec" } + | SIG { "sig" } + | STRUCT { "struct" } + | THEN { "then" } + | TO { "to" } + | TRUE { "true" } + | TRY { "try" } + | TYPE { "type" } + | VAL { "val" } + | VIRTUAL { "virtual" } + | WHEN { "when" } + | WHILE { "while" } + | WITH { "with" } +/* mod/land/lor/lxor/lsl/lsr/asr are not supported for now */ +; + +attr_id: + single_attr_id { mkloc $1 (symbol_rloc()) } + | single_attr_id DOT attr_id { mkloc ($1 ^ "." ^ $3.txt) (symbol_rloc())} +; +attribute: + LBRACKETAT attr_id payload RBRACKET { ($2, $3) } +; +post_item_attribute: + LBRACKETATAT attr_id payload RBRACKET { ($2, $3) } +; +post_item_attributes: + /* empty */ { [] } + | post_item_attribute post_item_attributes { $1 :: $2 } +; +attributes: + /* empty */{ [] } + | attribute attributes { $1 :: $2 } +; +ext_attributes: + /* empty */ { None, [] } + | attribute attributes { None, $1 :: $2 } + | PERCENT attr_id attributes { Some $2, $3 } +; +extension: + LBRACKETPERCENT attr_id payload RBRACKET { ($2, $3) } +; +item_extension: + LBRACKETPERCENTPERCENT attr_id payload RBRACKET { ($2, $3) } +; +payload: + structure { PStr $1 } + | COLON core_type { PTyp $2 } + | QUESTION pattern { PPat ($2, None) } + | QUESTION pattern WHEN seq_expr { PPat ($2, Some $4) } +; %% |