#ifndef RUST_PARSE_H #define RUST_PARSE_H #include "rust-lex.h" #include "rust-ast-full.h" namespace Rust { /* HACK: used to resolve the expression-or-statement problem at the end of a * block by allowing either to be returned (technically). Tagged union would * probably take up the same amount of space. */ struct ExprOrStmt { ::std::unique_ptr expr; ::std::unique_ptr stmt; /* I was going to resist the urge to make this a real class and make it POD, * but construction in steps is too difficult. So it'll just also have a * constructor. */ // expression constructor ExprOrStmt (::std::unique_ptr expr) : expr (::std::move (expr)) {} // statement constructor ExprOrStmt (::std::unique_ptr stmt) : stmt (::std::move (stmt)) {} // Returns whether this object is in an error state. inline bool is_error () const { return (expr == NULL && stmt == NULL) || (expr != NULL && stmt != NULL); } // Returns an error state object. static ExprOrStmt create_error () { return ExprOrStmt (NULL, NULL); } ~ExprOrStmt () = default; // no copy constructors/assignment copy as simple object like this shouldn't // require it // move constructors ExprOrStmt (ExprOrStmt &&other) = default; ExprOrStmt &operator= (ExprOrStmt &&other) = default; private: // private constructor only used for creating error state expr or stmt objects ExprOrStmt (AST::ExprWithoutBlock *expr, AST::Stmt *stmt) : expr (expr), stmt (stmt) {} // make this work: have a disambiguation specifically for known statements // (i.e. ';' and 'let'). then, have a special "parse expr or stmt" function // that returns this type. inside it, it parses an expression, and then // determines whether to return expr or stmt via whether the next token is a // semicolon. should be able to disambiguate inside that function between // stmts with blocks and without blocks. }; /* Restrictions on parsing used to signal that certain ambiguous grammar * features should be parsed in a certain way.*/ struct ParseRestrictions { bool can_be_struct_expr = true; /* Whether the expression was entered from a unary expression - prevents stuff * like struct exprs being parsed from a dereference. */ bool entered_from_unary = false; }; // Parser implementation for gccrs. class Parser { private: void skip_after_semicolon (); void skip_after_end (); void skip_after_end_block (); void skip_after_next_block (); void skip_after_end_attribute (); bool skip_token (TokenId t); const_TokenPtr expect_token (TokenId t); void unexpected_token (const_TokenPtr t); bool skip_generics_right_angle (); void parse_statement_seq (bool (Parser::*done) ()); // AST-related stuff - maybe move or something? ::std::vector parse_inner_attributes (); AST::Attribute parse_inner_attribute (); ::std::vector parse_outer_attributes (); AST::Attribute parse_outer_attribute (); AST::Attribute parse_attribute_body (); ::std::unique_ptr parse_attr_input (); // Path-related AST::SimplePath parse_simple_path (); AST::SimplePathSegment parse_simple_path_segment (); AST::TypePath parse_type_path (); ::std::unique_ptr parse_type_path_segment (); AST::PathIdentSegment parse_path_ident_segment (); AST::GenericArgs parse_path_generic_args (); AST::GenericArgsBinding parse_generic_args_binding (); AST::TypePathFunction parse_type_path_function (); AST::PathInExpression parse_path_in_expression (); AST::PathExprSegment parse_path_expr_segment (); AST::QualifiedPathInExpression parse_qualified_path_in_expression (bool pratt_parse = false); AST::QualifiedPathType parse_qualified_path_type (bool pratt_parse = false); AST::QualifiedPathInType parse_qualified_path_in_type (); // Token tree or macro related AST::DelimTokenTree parse_delim_token_tree (); ::std::unique_ptr parse_token_tree (); ::std::unique_ptr parse_macro_rules_def (::std::vector outer_attrs); ::std::unique_ptr parse_macro_invocation_semi (::std::vector outer_attrs); ::std::unique_ptr parse_macro_invocation (::std::vector outer_attrs); AST::MacroRule parse_macro_rule (); AST::MacroMatcher parse_macro_matcher (); ::std::unique_ptr parse_macro_match (); ::std::unique_ptr parse_macro_match_fragment (); ::std::unique_ptr parse_macro_match_repetition (); // Top-level item-related ::std::vector< ::std::unique_ptr > parse_items (); ::std::unique_ptr parse_item (bool called_from_statement); ::std::unique_ptr parse_vis_item (::std::vector outer_attrs); ::std::unique_ptr parse_macro_item (::std::vector outer_attrs); AST::Visibility parse_visibility (); // VisItem subclass-related ::std::unique_ptr parse_module (AST::Visibility vis, ::std::vector outer_attrs); ::std::unique_ptr parse_extern_crate (AST::Visibility vis, ::std::vector outer_attrs); ::std::unique_ptr parse_use_decl (AST::Visibility vis, ::std::vector outer_attrs); ::std::unique_ptr parse_use_tree (); ::std::unique_ptr parse_function (AST::Visibility vis, ::std::vector outer_attrs); AST::FunctionQualifiers parse_function_qualifiers (); ::std::vector< ::std::unique_ptr > parse_generic_params_in_angles (); ::std::vector< ::std::unique_ptr > parse_generic_params (); ::std::vector< ::std::unique_ptr > parse_lifetime_params (); ::std::vector parse_lifetime_params_objs (); AST::LifetimeParam parse_lifetime_param (); ::std::vector< ::std::unique_ptr > parse_type_params (); ::std::unique_ptr parse_type_param (); ::std::vector parse_function_params (); AST::FunctionParam parse_function_param (); ::std::unique_ptr parse_function_return_type (); AST::WhereClause parse_where_clause (); ::std::unique_ptr parse_where_clause_item (); ::std::unique_ptr parse_lifetime_where_clause_item (); ::std::unique_ptr parse_type_bound_where_clause_item (); ::std::vector parse_for_lifetimes (); ::std::vector< ::std::unique_ptr > parse_type_param_bounds (); ::std::unique_ptr parse_type_param_bound (); ::std::unique_ptr parse_trait_bound (); ::std::vector parse_lifetime_bounds (); AST::Lifetime parse_lifetime (); ::std::unique_ptr parse_type_alias (AST::Visibility vis, ::std::vector outer_attrs); ::std::unique_ptr parse_struct (AST::Visibility vis, ::std::vector outer_attrs); ::std::vector parse_struct_fields (); AST::StructField parse_struct_field (); ::std::vector parse_tuple_fields (); AST::TupleField parse_tuple_field (); ::std::unique_ptr parse_enum (AST::Visibility vis, ::std::vector outer_attrs); ::std::vector< ::std::unique_ptr > parse_enum_items (); ::std::unique_ptr parse_enum_item (); ::std::unique_ptr parse_union (AST::Visibility vis, ::std::vector outer_attrs); ::std::unique_ptr parse_const_item (AST::Visibility vis, ::std::vector outer_attrs); ::std::unique_ptr parse_static_item (AST::Visibility vis, ::std::vector outer_attrs); ::std::unique_ptr parse_trait (AST::Visibility vis, ::std::vector outer_attrs); ::std::unique_ptr parse_trait_item (); ::std::unique_ptr parse_trait_type (::std::vector outer_attrs); ::std::unique_ptr parse_trait_const (::std::vector outer_attrs); AST::SelfParam parse_self_param (); ::std::unique_ptr parse_impl (AST::Visibility vis, ::std::vector outer_attrs); ::std::unique_ptr parse_inherent_impl_item (); ::std::unique_ptr parse_inherent_impl_function_or_method ( AST::Visibility vis, ::std::vector outer_attrs); ::std::unique_ptr parse_trait_impl_item (); ::std::unique_ptr parse_trait_impl_function_or_method ( AST::Visibility vis, ::std::vector outer_attrs); ::std::unique_ptr parse_extern_block (AST::Visibility vis, ::std::vector outer_attrs); ::std::unique_ptr parse_external_item (); AST::NamedFunctionParam parse_named_function_param (); AST::Method parse_method (); // Expression-related (Pratt parsed) ::std::unique_ptr parse_expr (::std::vector outer_attrs = ::std::vector (), ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_expr (int right_binding_power, ::std::vector outer_attrs = ::std::vector (), ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr null_denotation_NEW (const_TokenPtr t, ::std::vector outer_attrs = ::std::vector (), ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr left_denotation (const_TokenPtr t, ::std::unique_ptr left, ::std::vector outer_attrs = ::std::vector (), ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_binary_plus_expr (const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_binary_minus_expr ( const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_binary_mult_expr (const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_binary_div_expr (const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_binary_mod_expr (const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_bitwise_and_expr (const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_bitwise_or_expr (const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_bitwise_xor_expr (const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_left_shift_expr (const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_right_shift_expr (const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_binary_equal_expr ( const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_binary_not_equal_expr ( const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_binary_greater_than_expr ( const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_binary_less_than_expr ( const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_binary_greater_equal_expr ( const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_binary_less_equal_expr ( const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_lazy_or_expr (const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_lazy_and_expr (const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_type_cast_expr (const_TokenPtr tok, ::std::unique_ptr expr_to_cast, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_assig_expr (const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_plus_assig_expr (const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_minus_assig_expr (const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_mult_assig_expr (const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_div_assig_expr (const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_mod_assig_expr (const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_and_assig_expr (const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_or_assig_expr (const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_xor_assig_expr (const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_left_shift_assig_expr ( const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_right_shift_assig_expr ( const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_await_expr (const_TokenPtr tok, ::std::unique_ptr expr_to_await, ::std::vector outer_attrs); ::std::unique_ptr parse_method_call_expr ( const_TokenPtr tok, ::std::unique_ptr receiver_expr, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_function_call_expr ( const_TokenPtr tok, ::std::unique_ptr function_expr, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_led_range_exclusive_expr ( const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_nud_range_exclusive_expr (const_TokenPtr tok, ::std::vector outer_attrs); ::std::unique_ptr parse_range_inclusive_expr ( const_TokenPtr tok, ::std::unique_ptr left, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_range_to_inclusive_expr (const_TokenPtr tok, ::std::vector outer_attrs); ::std::unique_ptr parse_tuple_index_expr ( const_TokenPtr tok, ::std::unique_ptr tuple_expr, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_field_access_expr ( const_TokenPtr tok, ::std::unique_ptr struct_expr, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_index_expr (const_TokenPtr tok, ::std::unique_ptr array_expr, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); ::std::unique_ptr parse_macro_invocation_partial (AST::PathInExpression path, ::std::vector outer_attrs); ::std::unique_ptr parse_struct_expr_struct_partial (AST::PathInExpression path, ::std::vector outer_attrs); ::std::unique_ptr parse_struct_expr_tuple_partial (AST::PathInExpression path, ::std::vector outer_attrs); AST::PathInExpression parse_path_in_expression_pratt (const_TokenPtr tok); ::std::unique_ptr parse_closure_expr_pratt (const_TokenPtr tok, ::std::vector outer_attrs = ::std::vector ()); ::std::unique_ptr parse_tuple_index_expr_float ( const_TokenPtr tok, ::std::unique_ptr tuple_expr, ::std::vector outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); // Expression-related (non-Pratt parsed) ::std::unique_ptr parse_expr_without_block (::std::vector outer_attrs = ::std::vector ()); ::std::unique_ptr parse_block_expr (::std::vector outer_attrs = ::std::vector (), bool pratt_parse = false); ::std::unique_ptr parse_if_expr (::std::vector outer_attrs = ::std::vector ()); ::std::unique_ptr parse_if_let_expr (::std::vector outer_attrs = ::std::vector ()); ::std::unique_ptr parse_loop_expr (::std::vector outer_attrs = ::std::vector (), AST::LoopLabel label = AST::LoopLabel::error ()); ::std::unique_ptr parse_while_loop_expr (::std::vector outer_attrs = ::std::vector (), AST::LoopLabel label = AST::LoopLabel::error ()); ::std::unique_ptr parse_while_let_loop_expr (::std::vector outer_attrs = ::std::vector (), AST::LoopLabel label = AST::LoopLabel::error ()); ::std::unique_ptr parse_for_loop_expr (::std::vector outer_attrs = ::std::vector (), AST::LoopLabel label = AST::LoopLabel::error ()); ::std::unique_ptr parse_match_expr (::std::vector outer_attrs = ::std::vector (), bool pratt_parse = false); AST::MatchArm parse_match_arm (); ::std::vector< ::std::unique_ptr > parse_match_arm_patterns (TokenId end_token_id); ::std::unique_ptr parse_labelled_loop_expr (::std::vector outer_attrs = ::std::vector ()); AST::LoopLabel parse_loop_label (); ::std::unique_ptr parse_async_block_expr (::std::vector outer_attrs = ::std::vector ()); ::std::unique_ptr parse_unsafe_block_expr (::std::vector outer_attrs = ::std::vector ()); ::std::unique_ptr parse_grouped_expr (::std::vector outer_attrs = ::std::vector ()); ::std::unique_ptr parse_closure_expr (::std::vector outer_attrs = ::std::vector ()); AST::ClosureParam parse_closure_param (); ::std::unique_ptr parse_literal_expr (::std::vector outer_attrs = ::std::vector ()); ::std::unique_ptr parse_return_expr (::std::vector outer_attrs = ::std::vector (), bool pratt_parse = false); ::std::unique_ptr parse_break_expr (::std::vector outer_attrs = ::std::vector (), bool pratt_parse = false); ::std::unique_ptr parse_continue_expr (::std::vector outer_attrs = ::std::vector (), bool pratt_parse = false); ::std::unique_ptr parse_array_expr (::std::vector outer_attrs = ::std::vector (), bool pratt_parse = false); ::std::unique_ptr parse_grouped_or_tuple_expr (::std::vector outer_attrs = ::std::vector (), bool pratt_parse = false); ::std::unique_ptr parse_struct_expr_field (); // Type-related ::std::unique_ptr parse_type (); ::std::unique_ptr parse_type_no_bounds (); ::std::unique_ptr parse_slice_or_array_type (); ::std::unique_ptr parse_raw_pointer_type (); ::std::unique_ptr parse_reference_type (); ::std::unique_ptr parse_bare_function_type (::std::vector for_lifetimes); ::std::unique_ptr parse_paren_prefixed_type (); ::std::unique_ptr parse_paren_prefixed_type_no_bounds (); ::std::unique_ptr parse_for_prefixed_type (); AST::MaybeNamedParam parse_maybe_named_param (); // Statement-related ::std::unique_ptr parse_stmt (); ::std::unique_ptr parse_let_stmt (::std::vector outer_attrs); ::std::unique_ptr parse_expr_stmt (::std::vector outer_attrs); ::std::unique_ptr parse_expr_stmt_with_block (::std::vector outer_attrs); ::std::unique_ptr parse_expr_stmt_without_block (::std::vector outer_attrs); ExprOrStmt parse_stmt_or_expr_without_block (); ExprOrStmt parse_macro_invocation_maybe_semi (::std::vector outer_attrs); ExprOrStmt parse_path_based_stmt_or_expr (::std::vector outer_attrs); // Pattern-related ::std::unique_ptr parse_pattern (); ::std::unique_ptr parse_literal_or_range_pattern (); ::std::unique_ptr parse_range_pattern_bound (); ::std::unique_ptr parse_reference_pattern (); ::std::unique_ptr parse_grouped_or_tuple_pattern (); ::std::unique_ptr parse_slice_pattern (); ::std::unique_ptr parse_identifier_pattern (); ::std::unique_ptr parse_ident_leading_pattern (); ::std::unique_ptr parse_tuple_struct_items (); AST::StructPatternElements parse_struct_pattern_elems (); ::std::unique_ptr parse_struct_pattern_field (); int left_binding_power (const_TokenPtr token); bool done_end (); bool done_end_or_else (); bool done_end_of_file (); public: // Construct parser with specified lexer reference. Parser (Lexer &parLexer) : lexer (parLexer) {} // Main entry point for parser. AST::Crate parse_crate (); // Dumps all lexer output. void debug_dump_lex_output (); void debug_dump_ast_output (AST::Crate &crate); private: // The lexer associated with the parser. Lexer &lexer; }; } // namespace Rust #endif // RUST_PARSE_H