From 46a600a554abf653a42bac6814176c6f3c84427d Mon Sep 17 00:00:00 2001 From: Milan Lustig Date: Tue, 2 Jul 2024 14:29:12 -0400 Subject: [PATCH] Final changes to rust grammar - fixed the conflict issue with the modules types --- src/rust/Grammar.re | 651 ++++++++++++++++++++++---------------------- 1 file changed, 320 insertions(+), 331 deletions(-) diff --git a/src/rust/Grammar.re b/src/rust/Grammar.re index 19e8be31..1962a7b0 100644 --- a/src/rust/Grammar.re +++ b/src/rust/Grammar.re @@ -85,329 +85,245 @@ let qualified_path_in_exp = seq([qualified_path_typ, plus(seq([c("::"), path_exp_segment]))]); let path_exp = alt([path_in_exp, qualified_path_in_exp]); -module Pat = { - let sort = Sort.of_str("Pat"); - let atom = nt(sort); +module type SORT = { + let atom: unit => Regex.t; + let sort: unit => Sort.t; + let tbl: unit => Prec.Table.t(Regex.t); +}; - let ident_pat = +module rec Stat: SORT = { + let sort = () => Sort.of_str("Stat"); + let atom = () => nt(sort()); + + let block_exp = seq([c("{"), plus(atom()), c("}")]); + + let let_stat = seq([ - opt(c("ref")), - opt(c("mut")), - t(Id_lower), - opt(seq([c("@"), atom])), + c("let"), + Pat.atom(), + opt(seq([c(":"), Typ.atom()])), + opt(seq([c("="), Exp.atom(), opt(seq([c("else"), block_exp]))])), + c(";"), ]); - //NOTE: actual rust grammar has a star(outer_attr) then c(..) but since we don't have metaprogramming or attrs, struct_pat_et_cetera is just .. for us - let struct_pat_et_cetera = c(".."); + let operand = alt([let_stat, Item.atom()]); + let tbl = () => [p(seq([Exp.atom(), c(";")])), p(operand)]; +} +and Item: SORT = { + let sort = () => Sort.of_str("Item"); + let atom = () => nt(sort()); - let struct_pat_field = + [@warning "-32"] + let comma_sep = seq([atom(), star(seq([c(","), atom()]))]); + let block_exp = seq([c("{"), plus(atom()), c("}")]); + + //Functions! + let func_qualifier = alt([c("const"), c("async"), c("unsafe")]); + + let self_param = alt([ - seq([t(Int_lit), c(":"), atom]), - seq([t(Id_lower), c("l"), atom]), - seq([opt(c("ref")), opt(c("mut")), t(Id_lower)]), + //Shorthand self + seq([c("&"), opt(c("mut")), c("self")]), + //Typed self + seq([opt(c("mut")), c("self"), c(":"), Typ.atom()]), ]); - let struct_pat_fields = - seq([struct_pat_field, star(seq([c(","), struct_pat_field]))]); - let struct_pat_elements = + let func_param = + alt([ + seq([t(Id_lower), c(":"), alt([Typ.atom(), c("...")])]), + c("..."), + ]); + let func_params = alt([ + self_param, seq([ - struct_pat_fields, - opt(alt([c(","), seq([c(","), struct_pat_et_cetera])])), + opt(seq([self_param, c(",")])), + func_param, + star(seq([c(","), func_param])), + opt(c(",")), ]), - struct_pat_et_cetera, ]); - let struct_pat = - seq([path_in_exp, c("{"), opt(struct_pat_elements), c("}")]); - - let tuple_struct_items = - seq([atom, star(seq([c(","), atom])), opt(c(","))]); - let tuple_struct_pat = - seq([path_in_exp, c("("), opt(tuple_struct_items), c(")")]); + let func_return_typ = seq([c("->"), Typ.atom()]); - let rest_pat = c(".."); - let tuple_pat_items = - alt([ - seq([atom, c(",")]), - rest_pat, - seq([atom, star(seq([c(","), atom, opt(c(","))]))]), + let func = + seq([ + opt(func_qualifier), + c("fn"), + t(Id_lower), + c("("), + opt(func_params), + c(")"), + func_return_typ, + alt([block_exp, c(";")]), ]); - let tuple_pat = seq([c("("), tuple_pat_items, c(")")]); + //End functions - let group_pat = seq([c("("), atom, c(")")]); + //Crates + let extern_crate = + seq([ + c("extern"), + c("crate"), + alt([t(Id_lower), c("self")]), + opt(seq([c("as"), alt([t(Id_lower), c("_")])])), + c(";"), + ]); - let slice_pat_items = - seq([atom, star(seq([c(","), atom])), opt(c(","))]); - let slice_pat = seq([c("["), opt(slice_pat_items), c("]")]); + //Module + let _module = + alt([ + seq([opt(c("unsafe")), c("mod"), t(Id_lower), c("l")]), + seq([ + opt(c("unsafe")), + c("mod"), + t(Id_lower), + c("{"), + star(atom()), + c("}"), + ]), + ]); - let path_pat = path_exp; + let typ_alias = + seq([ + c("type"), + t(Id_lower), + opt(seq([c("="), Typ.atom()])), + c(";"), + ]); - let operand = - alt([ - c("true"), - c("false"), - //TODO: char literal, string literal - seq([opt(c("-")), t(Int_lit)]), - seq([opt(c("-")), t(Float_lit)]), - //Wild - c("_"), - //Rest - rest_pat, - //Reference - seq([alt([c("&"), c("&&")]), opt(c("mut")), atom]), - ident_pat, - struct_pat, - tuple_struct_pat, - tuple_pat, - group_pat, - slice_pat, - path_pat, + //Struct + let struct_field = seq([t(Id_lower), c(":"), Typ.atom()]); + let struct_fields = + seq([struct_field, star(seq([c(","), struct_field])), opt(c(","))]); + let struct_struct = + seq([ + c("struct"), + t(Id_lower), + alt([seq([c("{"), opt(struct_fields), c("}")]), c(";")]), ]); - let tbl = [p(operand)]; -}; + let tuple_field = Typ.atom(); + let tuple_fields = + seq([tuple_field, star(seq([c(","), tuple_field])), opt(c(","))]); + let tuple_struct = + seq([ + c("struct"), + t(Id_lower), + c("("), + opt(tuple_fields), + c(")"), + c(";"), + ]); + let _struct = alt([struct_struct, tuple_struct]); -module type SORT = { - let atom: Regex.t; - let sort: Sort.t; - let tbl: Prec.Table.t(Regex.t); -}; + //Enums + let enum_item_tuple = seq([c("("), opt(tuple_fields), c(")")]); + let enum_item_struct = seq([c("{"), opt(struct_fields), c("}")]); + let enum_item = + seq([ + t(Id_lower), + opt(alt([enum_item_tuple, enum_item_struct])), + opt(seq([c("="), Exp.atom()])), + ]); + let enum_items = + seq([enum_item, star(seq([c(","), enum_item])), opt(c(","))]); + let enum = + seq([c("enum"), t(Id_lower), c("{"), opt(enum_items), c("}")]); -module rec Stat: SORT = { - let sort = Sort.of_str("Stat"); - let atom = nt(sort); + //Unions + let union = + seq([c("union"), t(Id_lower), c("{"), struct_fields, c("}")]); - let block_exp = seq([c("{"), plus(Stat.atom), c("}")]); + //Consts + let const = + seq([ + c("const"), + alt([t(Id_lower), c("_")]), + c(":"), + Typ.atom(), + opt(seq([c("="), Exp.atom()])), + c(";"), + ]); - let let_stat = + //static + let static_item = seq([ - c("let"), - Pat.atom, - opt(seq([c(":"), Typ.atom])), - opt(seq([c("="), Exp.atom, opt(seq([c("else"), block_exp]))])), + c("static"), + opt(c("mut")), + t(Id_lower), + c(":"), + opt(seq([c("="), Exp.atom()])), c(";"), ]); - module Item = { - let sort = Sort.of_str("Item"); - let atom = nt(sort); - - [@warning "-32"] - let comma_sep = seq([atom, star(seq([c(","), atom]))]); - let block_exp = seq([c("{"), plus(Stat.atom), c("}")]); - - //Functions! - let func_qualifier = alt([c("const"), c("async"), c("unsafe")]); - - let self_param = - alt([ - //Shorthand self - seq([c("&"), opt(c("mut")), c("self")]), - //Typed self - seq([opt(c("mut")), c("self"), c(":"), Typ.atom]), - ]); - let func_param = - alt([ - seq([t(Id_lower), c(":"), alt([Typ.atom, c("...")])]), - c("..."), - ]); - let func_params = - alt([ - self_param, - seq([ - opt(seq([self_param, c(",")])), - func_param, - star(seq([c(","), func_param])), - opt(c(",")), - ]), - ]); - let func_return_typ = seq([c("->"), Typ.atom]); - - let func = - seq([ - opt(func_qualifier), - c("fn"), - t(Id_lower), - c("("), - opt(func_params), - c(")"), - func_return_typ, - alt([block_exp, c(";")]), - ]); - //End functions - - //Crates - let extern_crate = - seq([ - c("extern"), - c("crate"), - alt([t(Id_lower), c("self")]), - opt(seq([c("as"), alt([t(Id_lower), c("_")])])), - c(";"), - ]); - - //Module - let _module = - alt([ - seq([opt(c("unsafe")), c("mod"), t(Id_lower), c("l")]), - seq([ - opt(c("unsafe")), - c("mod"), - t(Id_lower), - c("{"), - star(atom), - c("}"), - ]), - ]); - - let typ_alias = - seq([ - c("type"), - t(Id_lower), - opt(seq([c("="), Typ.atom])), - c(";"), - ]); + //Traits + let associated_item = alt([typ_alias, const, func]); + let trait = + seq([ + opt(c("unsafe")), + c("trait"), + t(Id_lower), + c("{"), + star(associated_item), + c("}"), + ]); - //Struct - let struct_field = seq([t(Id_lower), c(":"), Typ.atom]); - let struct_fields = - seq([ - struct_field, - star(seq([c(","), struct_field])), - opt(c(",")), - ]); - let struct_struct = - seq([ - c("struct"), - t(Id_lower), - alt([seq([c("{"), opt(struct_fields), c("}")]), c(";")]), - ]); + //Implementations + let inherent_impl = + seq([c("impl"), c("{"), star(associated_item), c("}")]); - let tuple_field = Typ.atom; - let tuple_fields = - seq([tuple_field, star(seq([c(","), tuple_field])), opt(c(","))]); - let tuple_struct = - seq([ - c("struct"), - t(Id_lower), - c("("), - opt(tuple_fields), - c(")"), - c(";"), - ]); - let _struct = alt([struct_struct, tuple_struct]); - - //Enums - let enum_item_tuple = seq([c("("), opt(tuple_fields), c(")")]); - let enum_item_struct = seq([c("{"), opt(struct_fields), c("}")]); - let enum_item = - seq([ - t(Id_lower), - opt(alt([enum_item_tuple, enum_item_struct])), - opt(seq([c("="), Exp.atom])), - ]); - let enum_items = - seq([enum_item, star(seq([c(","), enum_item])), opt(c(","))]); - let enum = - seq([c("enum"), t(Id_lower), c("{"), opt(enum_items), c("}")]); - - //Unions - let union = - seq([c("union"), t(Id_lower), c("{"), struct_fields, c("}")]); - - //Consts - let const = - seq([ - c("const"), - alt([t(Id_lower), c("_")]), - c(":"), - Typ.atom, - opt(seq([c("="), Exp.atom])), - c(";"), - ]); - - //static - let static_item = - seq([ - c("static"), - opt(c("mut")), - t(Id_lower), - c(":"), - opt(seq([c("="), Exp.atom])), - c(";"), - ]); - - //Traits - let associated_item = alt([typ_alias, const, func]); - let trait = - seq([ - opt(c("unsafe")), - c("trait"), - t(Id_lower), - c("{"), - star(associated_item), - c("}"), - ]); + let trait_impl = + seq([ + opt(c("unsafe")), + c("impl"), + opt(c("!")), + typ_path, + c("for"), + Typ.atom(), + ]); - //Implementations - let inherent_impl = - seq([c("impl"), c("{"), star(associated_item), c("}")]); + let impl = alt([inherent_impl, trait_impl]); - let trait_impl = - seq([ - opt(c("unsafe")), - c("impl"), - opt(c("!")), - typ_path, - c("for"), - Typ.atom, - ]); - - let impl = alt([inherent_impl, trait_impl]); - - //Externs - let extern_item = alt([static_item, func]); - let extern_block = - seq([ - opt(c("unsafe")), - c("extern"), - opt(abi), - c("{"), - star(extern_item), - c("}"), - ]); - - let operand = - alt([ - impl, - trait, - static_item, - const, - union, - enum, - _struct, - typ_alias, - func, - extern_crate, - _module, - ]); - let tbl = []; - }; - - let operand = alt([let_stat, Item.operand]); - let tbl = [p(seq([Exp.atom, c(";")])), p(operand)]; + //Externs + let extern_item = alt([static_item, func]); + let extern_block = + seq([ + opt(c("unsafe")), + c("extern"), + opt(abi), + c("{"), + star(extern_item), + c("}"), + ]); + + let operand = + alt([ + extern_block, + impl, + trait, + static_item, + const, + union, + enum, + _struct, + typ_alias, + func, + extern_crate, + _module, + ]); + + let tbl = () => [p(operand)]; } and Typ: SORT = { - let sort = Sort.of_str("Typ"); - let atom = nt(sort); + let sort = () => Sort.of_str("Typ"); + let atom = () => nt(sort()); let typ_path_fn_inputs = - seq([Typ.atom, star(seq([c(","), Typ.atom])), opt(c(","))]); + seq([atom(), star(seq([c(","), atom()])), opt(c(","))]); let typ_path_fn = seq([ c("("), opt(typ_path_fn_inputs), c(")"), - opt(seq([c("->"), Typ.atom])), + opt(seq([c("->"), atom()])), ]); let typ_path_segment = seq([path_ident_segment, opt(seq([c("::"), typ_path_fn]))]); @@ -418,7 +334,7 @@ and Typ: SORT = { star(seq([c("::"), typ_path_segment])), ]); - let paren_typ = seq([c("("), atom, c(")")]); + let paren_typ = seq([c("("), atom(), c(")")]); let trait_bound = seq([opt(c("?")), typ_path]); //TODO: lifetimes @@ -440,29 +356,24 @@ and Typ: SORT = { let tuple_typ = alt([ seq([c("("), c(")")]), - seq([ - c("("), - plus(seq([Typ.atom, c(",")])), - opt(Typ.atom), - c(")"), - ]), + seq([c("("), plus(seq([atom(), c(",")])), opt(atom()), c(")")]), ]); let never_typ = c("!"); let raw_pointer_typ = - seq([c("*"), alt([c("mut"), c("const")]), Typ.atom]); + seq([c("*"), alt([c("mut"), c("const")]), atom()]); //TODO: lifetimes - let reference_typ = seq([c("&"), opt(c("mut")), Typ.atom]); + let reference_typ = seq([c("&"), opt(c("mut")), atom()]); - let array_typ = seq([c("["), Typ.atom, c(";"), Exp.atom, c("]")]); - let slice_typ = seq([c("["), Typ.atom, c("]")]); + let array_typ = seq([c("["), atom(), c(";"), Exp.atom(), c("]")]); + let slice_typ = seq([c("["), atom(), c("]")]); let inferred_typ = c("_"); let qualified_path_typ = - seq([c("<"), Typ.atom, opt(seq([c("as"), typ_path])), c(">")]); + seq([c("<"), atom(), opt(seq([c("as"), typ_path])), c(">")]); let qualified_path_in_typ = seq([qualified_path_typ, plus(seq([c("::"), typ_path_segment]))]); @@ -470,7 +381,7 @@ and Typ: SORT = { seq([opt(c("unsafe")), opt(seq([c("extern"), opt(abi)]))]); let maybe_named_param = - seq([opt(seq([alt([t(Id_lower), c("_")]), c(":")])), Typ.atom]); + seq([opt(seq([alt([t(Id_lower), c("_")]), c(":")])), atom()]); let maybe_named_fun_params_variadic = seq([ star(seq([maybe_named_param, c(",")])), @@ -487,7 +398,7 @@ and Typ: SORT = { let fun_params_maybe_named_variadic = alt([maybe_named_fun_params, maybe_named_fun_params_variadic]); - let bare_fun_return_typ = seq([c("->"), Typ.atom]); + let bare_fun_return_typ = seq([c("->"), atom()]); let bare_fun_typ = seq([ @@ -517,20 +428,18 @@ and Typ: SORT = { bare_fun_typ, ]); - let tbl = [p(operand)]; + let tbl = () => [p(operand)]; } -// and Item: SORT = { -// } and Exp: SORT = { - let sort = Sort.of_str("Exp"); - let atom = nt(sort); + let sort = () => Sort.of_str("Exp"); + let atom = () => nt(sort()); [@warning "-32"] - let comma_sep = seq([atom, star(seq([c(","), atom]))]); + let comma_sep = seq([atom(), star(seq([c(","), atom()]))]); - let block_exp = seq([c("{"), Stat.atom, c("}")]); + let block_exp = seq([c("{"), Stat.atom(), c("}")]); - let lone_if_exp = seq([c("if"), atom, block_exp]); + let lone_if_exp = seq([c("if"), atom(), block_exp]); let if_exp = seq([ lone_if_exp, @@ -546,26 +455,26 @@ and Exp: SORT = { //Infinite loop seq([c("loop"), block_exp]), //Predicate (while) loops - seq([c("while"), atom, block_exp]), + seq([c("while"), atom(), block_exp]), //Predicate pattern (while let) loops - seq([c("while"), c("let"), Pat.atom, c("="), Exp.atom, block_exp]), + seq([c("while"), c("let"), Pat.atom(), c("="), Exp.atom(), block_exp]), //iterator (for) loops - seq([c("for"), Pat.atom, c("in"), atom, block_exp]), + seq([c("for"), Pat.atom(), c("in"), atom(), block_exp]), ]; - let match_arm = seq([Pat.atom, opt(seq([c("if"), atom]))]); + let match_arm = seq([Pat.atom(), opt(seq([c("if"), atom()]))]); let match_arms = seq([ - star(seq([match_arm, c("=>"), atom, c(",")])), + star(seq([match_arm, c("=>"), atom(), c(",")])), match_arm, c("=>"), - atom, + atom(), opt(c(",")), ]); let match_exp = - seq([c("match"), atom, c("{"), opt(match_arms), c("}")]); + seq([c("match"), atom(), c("{"), opt(match_arms), c("}")]); let exp_with_block = [match_exp] @ loop_exp @ [if_exp, block_exp]; @@ -578,11 +487,11 @@ and Exp: SORT = { c("break"), c("continue"), //Function call - seq([atom, c("("), opt(comma_sep), c(")")]), + seq([atom(), c("("), opt(comma_sep), c(")")]), //Parenthetical expression - seq([c("("), atom, c(")")]), + seq([c("("), atom(), c(")")]), //Arrays - seq([c("["), atom, opt(star(atom)), c("]")]), + seq([c("["), atom(), opt(star(atom())), c("]")]), ] @ exp_with_block, ); @@ -611,40 +520,120 @@ and Exp: SORT = { //NOTE: tbl goes from weak -> strong precedence //NOTE: exp without block > exp with block (prec) - let tbl = [ + let tbl = () => [ //return - p(seq([c("return"), atom])), + p(seq([c("return"), atom()])), //assignment ops - p(seq([atom, assignment_ops, atom])), + p(seq([atom(), assignment_ops, atom()])), //bool or - p(seq([atom, c("||"), atom])), + p(seq([atom(), c("||"), atom()])), //bool and - p(seq([atom, c("&&"), atom])), + p(seq([atom(), c("&&"), atom()])), //comparison ops - p(seq([atom, compare_ops, atom])), + p(seq([atom(), compare_ops, atom()])), //add - p(~a=L, seq([atom, add_ops, atom])), + p(~a=L, seq([atom(), add_ops, atom()])), //mult - p(~a=L, seq([atom, mult_ops, atom])), + p(~a=L, seq([atom(), mult_ops, atom()])), //type cast exp - p(~a=L, seq([atom, c("as"), Typ.atom])), + p(~a=L, seq([atom(), c("as"), Typ.atom()])), //unary operators - p(seq([unary_op, atom])), + p(seq([unary_op, atom()])), //question mark op - p(seq([c("?"), atom])), + p(seq([c("?"), atom()])), p(operand), ]; +} +and Pat: SORT = { + let sort = () => Sort.of_str("Pat"); + let atom = () => nt(sort()); + + let ident_pat = + seq([ + opt(c("ref")), + opt(c("mut")), + t(Id_lower), + opt(seq([c("@"), atom()])), + ]); + + //NOTE: actual rust grammar has a star(outer_attr) then c(..) but since we don't have metaprogramming or attrs, struct_pat_et_cetera is just .. for us + let struct_pat_et_cetera = c(".."); + + let struct_pat_field = + alt([ + seq([t(Int_lit), c(":"), atom()]), + seq([t(Id_lower), c("l"), atom()]), + seq([opt(c("ref")), opt(c("mut")), t(Id_lower)]), + ]); + let struct_pat_fields = + seq([struct_pat_field, star(seq([c(","), struct_pat_field]))]); + let struct_pat_elements = + alt([ + seq([ + struct_pat_fields, + opt(alt([c(","), seq([c(","), struct_pat_et_cetera])])), + ]), + struct_pat_et_cetera, + ]); + let struct_pat = + seq([path_in_exp, c("{"), opt(struct_pat_elements), c("}")]); + + let tuple_struct_items = + seq([atom(), star(seq([c(","), atom()])), opt(c(","))]); + let tuple_struct_pat = + seq([path_in_exp, c("("), opt(tuple_struct_items), c(")")]); + + let rest_pat = c(".."); + let tuple_pat_items = + alt([ + seq([atom(), c(",")]), + rest_pat, + seq([atom(), star(seq([c(","), atom(), opt(c(","))]))]), + ]); + let tuple_pat = seq([c("("), tuple_pat_items, c(")")]); + + let group_pat = seq([c("("), atom(), c(")")]); + + let slice_pat_items = + seq([atom(), star(seq([c(","), atom()])), opt(c(","))]); + let slice_pat = seq([c("["), opt(slice_pat_items), c("]")]); + + let path_pat = path_exp; + + let operand = + alt([ + c("true"), + c("false"), + //TODO: char literal, string literal + seq([opt(c("-")), t(Int_lit)]), + seq([opt(c("-")), t(Float_lit)]), + //Wild + c("_"), + //Rest + rest_pat, + //Reference + seq([alt([c("&"), c("&&")]), opt(c("mut")), atom()]), + ident_pat, + struct_pat, + tuple_struct_pat, + tuple_pat, + group_pat, + slice_pat, + path_pat, + ]); + + let tbl = () => [p(operand)]; }; type t = Sort.Map.t(Prec.Table.t(Regex.t)); let v = //TODO: ask david is this a valid way to do the item? [ - Typ.(sort, tbl), - Pat.(sort, tbl), - Exp.(sort, tbl), - Stat.(sort, tbl), - (Sort.of_str("Item"), []), + Typ.(sort(), tbl()), + Pat.(sort(), tbl()), + Exp.(sort(), tbl()), + Stat.(sort(), tbl()), + Item.(sort(), tbl()), ] |> List.to_seq |> Sort.Map.of_seq;