diff options
Diffstat (limited to 'gcc/rust/parse')
-rw-r--r-- | gcc/rust/parse/rust-parse-impl.h | 127 | ||||
-rw-r--r-- | gcc/rust/parse/rust-parse.h | 72 |
2 files changed, 141 insertions, 58 deletions
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index 4a9f3a3..437a7b5 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -386,6 +386,8 @@ Parser<ManagedTokenSource>::left_binding_power (const_TokenPtr token) return LBP_MOD_ASSIG; case AMP_EQ: return LBP_AMP_ASSIG; + case PIPE_EQ: + return LBP_PIPE_ASSIG; case CARET_EQ: return LBP_CARET_ASSIG; case LEFT_SHIFT_EQ: @@ -7396,8 +7398,10 @@ Parser<ManagedTokenSource>::parse_return_expr ( } // parse expression to return, if it exists - std::unique_ptr<AST::Expr> returned_expr = parse_expr (); - // FIXME: ensure this doesn't ruin the middle of any expressions or anything + ParseRestrictions restrictions; + restrictions.expr_can_be_null = true; + std::unique_ptr<AST::Expr> returned_expr + = parse_expr (std::vector<AST::Attribute> (), restrictions); return std::unique_ptr<AST::ReturnExpr> ( new AST::ReturnExpr (std::move (returned_expr), std::move (outer_attrs), @@ -7433,7 +7437,10 @@ Parser<ManagedTokenSource>::parse_break_expr ( } // parse break return expression if it exists - std::unique_ptr<AST::Expr> return_expr = parse_expr (); + ParseRestrictions restrictions; + restrictions.expr_can_be_null = true; + std::unique_ptr<AST::Expr> return_expr + = parse_expr (std::vector<AST::Attribute> (), restrictions); return std::unique_ptr<AST::BreakExpr> ( new AST::BreakExpr (std::move (label), std::move (return_expr), @@ -7502,10 +7509,23 @@ Parser<ManagedTokenSource>::parse_loop_label () template <typename ManagedTokenSource> std::unique_ptr<AST::IfExpr> Parser<ManagedTokenSource>::parse_if_expr ( - std::vector<AST::Attribute> outer_attrs) + std::vector<AST::Attribute> outer_attrs, bool pratt_parse) { - Location locus = lexer.peek_token ()->get_locus (); - skip_token (IF); + // TODO: make having outer attributes an error? + Location locus = Linemap::unknown_location (); + if (!pratt_parse) + { + locus = lexer.peek_token ()->get_locus (); + if (!skip_token (IF)) + { + skip_after_end_block (); + return nullptr; + } + } + else + { + locus = lexer.peek_token ()->get_locus () - 1; + } // detect accidental if let if (lexer.peek_token ()->get_id () == LET) @@ -7639,10 +7659,23 @@ Parser<ManagedTokenSource>::parse_if_expr ( template <typename ManagedTokenSource> std::unique_ptr<AST::IfLetExpr> Parser<ManagedTokenSource>::parse_if_let_expr ( - std::vector<AST::Attribute> outer_attrs) + std::vector<AST::Attribute> outer_attrs, bool pratt_parse) { - Location locus = lexer.peek_token ()->get_locus (); - skip_token (IF); + // TODO: make having outer attributes an error? + Location locus = Linemap::unknown_location (); + if (!pratt_parse) + { + locus = lexer.peek_token ()->get_locus (); + if (!skip_token (IF)) + { + skip_after_end_block (); + return nullptr; + } + } + else + { + locus = lexer.peek_token ()->get_locus () - 1; + } // detect accidental if expr parsed as if let expr if (lexer.peek_token ()->get_id () != LET) @@ -7802,14 +7835,30 @@ Parser<ManagedTokenSource>::parse_if_let_expr ( template <typename ManagedTokenSource> std::unique_ptr<AST::LoopExpr> Parser<ManagedTokenSource>::parse_loop_expr ( - std::vector<AST::Attribute> outer_attrs, AST::LoopLabel label) + std::vector<AST::Attribute> outer_attrs, AST::LoopLabel label, + bool pratt_parse) { Location locus = Linemap::unknown_location (); - if (label.is_error ()) - locus = lexer.peek_token ()->get_locus (); + if (!pratt_parse) + { + if (label.is_error ()) + locus = lexer.peek_token ()->get_locus (); + else + locus = label.get_locus (); + + if (!skip_token (LOOP)) + { + skip_after_end_block (); + return nullptr; + } + } else - locus = label.get_locus (); - skip_token (LOOP); + { + if (label.is_error ()) + locus = lexer.peek_token ()->get_locus () - 1; + else + locus = label.get_locus (); + } // parse loop body, which is required std::unique_ptr<AST::BlockExpr> loop_body = parse_block_expr (); @@ -12390,6 +12439,21 @@ Parser<ManagedTokenSource>::null_denotation ( case LEFT_CURLY: // ok - this is an expression with block for once. return parse_block_expr (std::move (outer_attrs), true); + case IF: + // if or if let, so more lookahead to find out + if (lexer.peek_token (1)->get_id () == LET) + { + // if let expr + return parse_if_let_expr (std::move (outer_attrs), true); + } + else + { + // if expr + return parse_if_expr (std::move (outer_attrs), true); + } + case LOOP: + return parse_loop_expr (std::move (outer_attrs), AST::LoopLabel::error (), + true); case MATCH_TOK: // also an expression with block return parse_match_expr (std::move (outer_attrs), true); @@ -12397,9 +12461,10 @@ Parser<ManagedTokenSource>::null_denotation ( // array definition expr (not indexing) return parse_array_expr (std::move (outer_attrs), true); default: - rust_error_at (tok->get_locus (), - "found unexpected token %qs in null denotation", - tok->get_token_description ()); + if (!restrictions.expr_can_be_null) + rust_error_at (tok->get_locus (), + "found unexpected token %qs in null denotation", + tok->get_token_description ()); return nullptr; } } @@ -14415,7 +14480,7 @@ Parser<ManagedTokenSource>::done_end () // Dumps lexer output to stderr. template <typename ManagedTokenSource> void -Parser<ManagedTokenSource>::debug_dump_lex_output () +Parser<ManagedTokenSource>::debug_dump_lex_output (std::ostream &out) { /* TODO: a better implementation of "lexer dump" (as in dump what was actually * tokenised) would actually be to "write" a token to a file every time @@ -14426,6 +14491,9 @@ Parser<ManagedTokenSource>::debug_dump_lex_output () while (true) { + if (tok->get_id () == Rust::END_OF_FILE) + break; + bool has_text = tok->get_id () == Rust::IDENTIFIER || tok->get_id () == Rust::INT_LITERAL || tok->get_id () == Rust::FLOAT_LITERAL @@ -14436,16 +14504,13 @@ Parser<ManagedTokenSource>::debug_dump_lex_output () Location loc = tok->get_locus (); - fprintf (stderr, "<id=%s%s, %s\n", tok->token_id_to_str (), - has_text ? (std::string (", text=") + tok->get_str () - + std::string (", typehint=") - + std::string (tok->get_type_hint_str ())) - .c_str () - : "", - lexer.get_line_map ()->to_string (loc).c_str ()); - - if (tok->get_id () == Rust::END_OF_FILE) - break; + out << "<id="; + out << tok->token_id_to_str (); + out << has_text ? (std::string (", text=") + tok->get_str () + + std::string (", typehint=") + + std::string (tok->get_type_hint_str ())) + : ""; + out << lexer.get_line_map ()->to_string (loc); lexer.skip_token (); tok = lexer.peek_token (); @@ -14455,9 +14520,9 @@ Parser<ManagedTokenSource>::debug_dump_lex_output () // Parses crate and dumps AST to stderr, recursively. template <typename ManagedTokenSource> void -Parser<ManagedTokenSource>::debug_dump_ast_output (AST::Crate &crate) +Parser<ManagedTokenSource>::debug_dump_ast_output (AST::Crate &crate, + std::ostream &out) { - // print crate "as string", which then calls each item as string, etc. - fprintf (stderr, "%s", crate.as_string ().c_str ()); + out << crate.as_string (); } } // namespace Rust diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h index 2778ec7..e691c9e 100644 --- a/gcc/rust/parse/rust-parse.h +++ b/gcc/rust/parse/rust-parse.h @@ -82,6 +82,7 @@ struct ParseRestrictions /* Whether the expression was entered from a unary expression - prevents stuff * like struct exprs being parsed from a dereference. */ bool entered_from_unary = false; + bool expr_can_be_null = false; }; // Parser implementation for gccrs. @@ -166,22 +167,30 @@ private: parse_generic_params_in_angles (); std::vector<std::unique_ptr<AST::GenericParam> > parse_generic_params (); template <typename EndTokenPred> - std::vector<std::unique_ptr<AST::GenericParam> > parse_generic_params (EndTokenPred is_end_token); + std::vector<std::unique_ptr<AST::GenericParam> > + parse_generic_params (EndTokenPred is_end_token); std::vector<std::unique_ptr<AST::LifetimeParam> > parse_lifetime_params (); template <typename EndTokenPred> - std::vector<std::unique_ptr<AST::LifetimeParam> > parse_lifetime_params (EndTokenPred is_end_token); + std::vector<std::unique_ptr<AST::LifetimeParam> > + parse_lifetime_params (EndTokenPred is_end_token); std::vector<AST::LifetimeParam> parse_lifetime_params_objs (); template <typename EndTokenPred> - std::vector<AST::LifetimeParam> parse_lifetime_params_objs (EndTokenPred is_end_token); + std::vector<AST::LifetimeParam> + parse_lifetime_params_objs (EndTokenPred is_end_token); template <typename ParseFunction, typename EndTokenPred> - auto parse_non_ptr_sequence (ParseFunction parsing_function, EndTokenPred is_end_token, std::string error_msg = "failed to parse generic param in generic params") -> std::vector<decltype(parsing_function ())>; + auto parse_non_ptr_sequence ( + ParseFunction parsing_function, EndTokenPred is_end_token, + std::string error_msg = "failed to parse generic param in generic params") + -> std::vector<decltype (parsing_function ())>; AST::LifetimeParam parse_lifetime_param (); std::vector<std::unique_ptr<AST::TypeParam> > parse_type_params (); template <typename EndTokenPred> - std::vector<std::unique_ptr<AST::TypeParam> > parse_type_params (EndTokenPred is_end_token); + std::vector<std::unique_ptr<AST::TypeParam> > + parse_type_params (EndTokenPred is_end_token); std::unique_ptr<AST::TypeParam> parse_type_param (); template <typename EndTokenPred> - std::vector<AST::FunctionParam> parse_function_params (EndTokenPred is_end_token); + std::vector<AST::FunctionParam> + parse_function_params (EndTokenPred is_end_token); AST::FunctionParam parse_function_param (); std::unique_ptr<AST::Type> parse_function_return_type (); AST::WhereClause parse_where_clause (); @@ -192,7 +201,8 @@ private: parse_type_bound_where_clause_item (); std::vector<AST::LifetimeParam> parse_for_lifetimes (); template <typename EndTokenPred> - std::vector<std::unique_ptr<AST::TypeParamBound> > parse_type_param_bounds (EndTokenPred is_end_token); + std::vector<std::unique_ptr<AST::TypeParamBound> > + parse_type_param_bounds (EndTokenPred is_end_token); std::vector<std::unique_ptr<AST::TypeParamBound> > parse_type_param_bounds (); std::unique_ptr<AST::TypeParamBound> parse_type_param_bound (); std::unique_ptr<AST::TraitBound> parse_trait_bound (); @@ -215,7 +225,8 @@ private: parse_enum (AST::Visibility vis, std::vector<AST::Attribute> outer_attrs); std::vector<std::unique_ptr<AST::EnumItem> > parse_enum_items (); template <typename EndTokenPred> - std::vector<std::unique_ptr<AST::EnumItem> > parse_enum_items (EndTokenPred is_end_token); + std::vector<std::unique_ptr<AST::EnumItem> > + parse_enum_items (EndTokenPred is_end_token); std::unique_ptr<AST::EnumItem> parse_enum_item (); std::unique_ptr<AST::Union> parse_union (AST::Visibility vis, std::vector<AST::Attribute> outer_attrs); @@ -247,8 +258,9 @@ private: parse_extern_block (AST::Visibility vis, std::vector<AST::Attribute> outer_attrs); std::unique_ptr<AST::ExternalItem> parse_external_item (); - AST::NamedFunctionParam parse_named_function_param ( - std::vector<AST::Attribute> outer_attrs = std::vector<AST::Attribute> ()); + AST::NamedFunctionParam + parse_named_function_param (std::vector<AST::Attribute> outer_attrs + = std::vector<AST::Attribute> ()); AST::Method parse_method (); // Expression-related (Pratt parsed) @@ -272,9 +284,11 @@ private: = std::vector<AST::Attribute> (), ParseRestrictions restrictions = ParseRestrictions ()); std::unique_ptr<AST::ArithmeticOrLogicalExpr> - parse_arithmetic_or_logical_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left, - std::vector<AST::Attribute> outer_attrs, AST::ArithmeticOrLogicalExpr::ExprType expr_type, - ParseRestrictions restrictions = ParseRestrictions ()); + parse_arithmetic_or_logical_expr ( + const_TokenPtr tok, std::unique_ptr<AST::Expr> left, + std::vector<AST::Attribute> outer_attrs, + AST::ArithmeticOrLogicalExpr::ExprType expr_type, + ParseRestrictions restrictions = ParseRestrictions ()); std::unique_ptr<AST::ArithmeticOrLogicalExpr> parse_binary_plus_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left, std::vector<AST::Attribute> outer_attrs, @@ -368,10 +382,11 @@ private: parse_assig_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left, std::vector<AST::Attribute> outer_attrs, ParseRestrictions restrictions = ParseRestrictions ()); - std::unique_ptr<AST::CompoundAssignmentExpr> - parse_compound_assignment_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left, - std::vector<AST::Attribute> outer_attrs, AST::CompoundAssignmentExpr::ExprType expr_type, - ParseRestrictions restrictions = ParseRestrictions ()); + std::unique_ptr<AST::CompoundAssignmentExpr> parse_compound_assignment_expr ( + const_TokenPtr tok, std::unique_ptr<AST::Expr> left, + std::vector<AST::Attribute> outer_attrs, + AST::CompoundAssignmentExpr::ExprType expr_type, + ParseRestrictions restrictions = ParseRestrictions ()); std::unique_ptr<AST::CompoundAssignmentExpr> parse_plus_assig_expr (const_TokenPtr tok, std::unique_ptr<AST::Expr> left, std::vector<AST::Attribute> outer_attrs, @@ -480,14 +495,15 @@ private: bool pratt_parse = false); std::unique_ptr<AST::IfExpr> parse_if_expr (std::vector<AST::Attribute> outer_attrs - = std::vector<AST::Attribute> ()); + = std::vector<AST::Attribute> (), + bool pratt_parse = false); std::unique_ptr<AST::IfLetExpr> parse_if_let_expr (std::vector<AST::Attribute> outer_attrs - = std::vector<AST::Attribute> ()); - std::unique_ptr<AST::LoopExpr> - parse_loop_expr (std::vector<AST::Attribute> outer_attrs - = std::vector<AST::Attribute> (), - AST::LoopLabel label = AST::LoopLabel::error ()); + = std::vector<AST::Attribute> (), + bool pratt_parse = false); + std::unique_ptr<AST::LoopExpr> parse_loop_expr ( + std::vector<AST::Attribute> outer_attrs = std::vector<AST::Attribute> (), + AST::LoopLabel label = AST::LoopLabel::error (), bool pratt_parse = false); std::unique_ptr<AST::WhileLoopExpr> parse_while_loop_expr (std::vector<AST::Attribute> outer_attrs = std::vector<AST::Attribute> (), @@ -561,7 +577,8 @@ private: std::unique_ptr<AST::Type> parse_paren_prefixed_type (); std::unique_ptr<AST::TypeNoBounds> parse_paren_prefixed_type_no_bounds (); std::unique_ptr<AST::Type> parse_for_prefixed_type (); - AST::MaybeNamedParam parse_maybe_named_param (std::vector<AST::Attribute> outer_attrs); + AST::MaybeNamedParam + parse_maybe_named_param (std::vector<AST::Attribute> outer_attrs); // Statement-related std::unique_ptr<AST::Stmt> parse_stmt (); @@ -591,7 +608,8 @@ private: std::unique_ptr<AST::TupleStructItems> parse_tuple_struct_items (); AST::StructPatternElements parse_struct_pattern_elems (); std::unique_ptr<AST::StructPatternField> parse_struct_pattern_field (); - std::unique_ptr<AST::StructPatternField> parse_struct_pattern_field_partial (std::vector<AST::Attribute> outer_attrs); + std::unique_ptr<AST::StructPatternField> + parse_struct_pattern_field_partial (std::vector<AST::Attribute> outer_attrs); int left_binding_power (const_TokenPtr token); @@ -607,8 +625,8 @@ public: AST::Crate parse_crate (); // Dumps all lexer output. - void debug_dump_lex_output (); - void debug_dump_ast_output (AST::Crate &crate); + void debug_dump_lex_output (std::ostream &out); + void debug_dump_ast_output (AST::Crate &crate, std::ostream &out); private: // The token source (usually lexer) associated with the parser. |