diff options
Diffstat (limited to 'gcc/rust/parse')
| -rw-r--r-- | gcc/rust/parse/rust-parse-impl.h | 274 | ||||
| -rw-r--r-- | gcc/rust/parse/rust-parse.h | 13 |
2 files changed, 72 insertions, 215 deletions
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index 14bccbd..ec4c1c1 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -1053,6 +1053,7 @@ Parser<ManagedTokenSource>::parse_identifier_or_keyword_token () } else { + add_error (Error (t->get_locus (), "expected keyword or identifier")); return nullptr; } } @@ -1716,10 +1717,9 @@ Parser<ManagedTokenSource>::parse_decl_macro_def (AST::Visibility vis, return nullptr; } - AST::MacroRule macro_rule - = AST::MacroRule (std::move (matcher), std::move (transcriber), locus); std::vector<AST::MacroRule> macro_rules; - macro_rules.push_back (macro_rule); + macro_rules.emplace_back (std::move (matcher), std::move (transcriber), + locus); return std::unique_ptr<AST::MacroRulesDefinition> ( AST::MacroRulesDefinition::decl_macro (std::move (rule_name), @@ -3316,8 +3316,8 @@ Parser<ManagedTokenSource>::parse_lifetime_params () break; } - lifetime_params.push_back (std::unique_ptr<AST::LifetimeParam> ( - new AST::LifetimeParam (std::move (lifetime_param.value ())))); + lifetime_params.emplace_back ( + new AST::LifetimeParam (std::move (lifetime_param.value ()))); if (lexer.peek_token ()->get_id () != COMMA) break; @@ -3356,8 +3356,8 @@ Parser<ManagedTokenSource>::parse_lifetime_params (EndTokenPred is_end_token) return {}; } - lifetime_params.push_back (std::unique_ptr<AST::LifetimeParam> ( - new AST::LifetimeParam (std::move (lifetime_param)))); + lifetime_params.emplace_back ( + new AST::LifetimeParam (std::move (lifetime_param))); if (lexer.peek_token ()->get_id () != COMMA) break; @@ -5219,7 +5219,7 @@ Parser<ManagedTokenSource>::parse_trait_type (AST::AttrVec outer_attrs, // Parses a constant trait item. template <typename ManagedTokenSource> -std::unique_ptr<AST::TraitItemConst> +std::unique_ptr<AST::ConstantItem> Parser<ManagedTokenSource>::parse_trait_const (AST::AttrVec outer_attrs) { location_t locus = lexer.peek_token ()->get_locus (); @@ -5257,10 +5257,9 @@ Parser<ManagedTokenSource>::parse_trait_const (AST::AttrVec outer_attrs) return nullptr; } - return std::unique_ptr<AST::TraitItemConst> ( - new AST::TraitItemConst (std::move (ident), std::move (type), - std::move (const_body), std::move (outer_attrs), - locus)); + return std::unique_ptr<AST::ConstantItem> (new AST::ConstantItem ( + std::move (ident), AST::Visibility::create_private (), std::move (type), + std::move (const_body), std::move (outer_attrs), locus)); } /* Parses a struct "impl" item (both inherent impl and trait impl can be @@ -10484,16 +10483,22 @@ Parser<ManagedTokenSource>::parse_pattern () return first; std::vector<std::unique_ptr<AST::Pattern>> alts; - alts.push_back (std::move (first)); + if (first != nullptr) + alts.push_back (std::move (first)); do { lexer.skip_token (); - alts.push_back (parse_pattern_no_alt ()); + auto follow = parse_pattern_no_alt (); + if (follow != nullptr) + alts.push_back (std::move (follow)); } while (lexer.peek_token ()->get_id () == PIPE); + if (alts.empty ()) + return nullptr; + /* alternates */ return std::unique_ptr<AST::Pattern> ( new AST::AltPattern (std::move (alts), start_locus)); @@ -10812,9 +10817,9 @@ Parser<ManagedTokenSource>::parse_grouped_or_tuple_pattern () return nullptr; } - // create ranged tuple pattern items with only upper items - std::unique_ptr<AST::TuplePatternItemsRanged> items ( - new AST::TuplePatternItemsRanged ( + // create tuple pattern items with only upper pattern items + std::unique_ptr<AST::TuplePatternItemsHasRest> items ( + new AST::TuplePatternItemsHasRest ( std::vector<std::unique_ptr<AST::Pattern>> (), std::move (patterns))); return std::unique_ptr<AST::TuplePattern> ( new AST::TuplePattern (std::move (items), paren_locus)); @@ -10822,8 +10827,8 @@ Parser<ManagedTokenSource>::parse_grouped_or_tuple_pattern () else if (lexer.peek_token ()->get_id () == RIGHT_PAREN) { skip_token (RIGHT_PAREN); - auto items = std::unique_ptr<AST::TuplePatternItemsMultiple> ( - new AST::TuplePatternItemsMultiple ( + auto items = std::unique_ptr<AST::TuplePatternItemsNoRest> ( + new AST::TuplePatternItemsNoRest ( std::vector<std::unique_ptr<AST::Pattern>> ())); return std::unique_ptr<AST::TuplePattern> ( new AST::TuplePattern (std::move (items), paren_locus)); @@ -10887,8 +10892,8 @@ Parser<ManagedTokenSource>::parse_grouped_or_tuple_pattern () // non-ranged tuple pattern lexer.skip_token (); - std::unique_ptr<AST::TuplePatternItemsMultiple> items ( - new AST::TuplePatternItemsMultiple (std::move (patterns))); + std::unique_ptr<AST::TuplePatternItemsNoRest> items ( + new AST::TuplePatternItemsNoRest (std::move (patterns))); return std::unique_ptr<AST::TuplePattern> ( new AST::TuplePattern (std::move (items), paren_locus)); } @@ -10928,9 +10933,9 @@ Parser<ManagedTokenSource>::parse_grouped_or_tuple_pattern () return nullptr; } - std::unique_ptr<AST::TuplePatternItemsRanged> items ( - new AST::TuplePatternItemsRanged (std::move (patterns), - std::move (upper_patterns))); + std::unique_ptr<AST::TuplePatternItemsHasRest> items ( + new AST::TuplePatternItemsHasRest (std::move (patterns), + std::move (upper_patterns))); return std::unique_ptr<AST::TuplePattern> ( new AST::TuplePattern (std::move (items), paren_locus)); } @@ -11113,7 +11118,7 @@ Parser<ManagedTokenSource>::parse_identifier_pattern () lexer.skip_token (); // parse required pattern to bind - bind_pattern = parse_pattern (); + bind_pattern = parse_pattern_no_alt (); if (bind_pattern == nullptr) { Error error (lexer.peek_token ()->get_locus (), @@ -11240,7 +11245,8 @@ Parser<ManagedTokenSource>::parse_ident_leading_pattern () // identifier with pattern bind lexer.skip_token (); - std::unique_ptr<AST::Pattern> bind_pattern = parse_pattern (); + std::unique_ptr<AST::Pattern> bind_pattern + = parse_pattern_no_alt (); if (bind_pattern == nullptr) { Error error ( @@ -11325,9 +11331,9 @@ Parser<ManagedTokenSource>::parse_tuple_struct_items () rust_debug ( "finished parsing tuple struct items ranged (upper/none only)"); - return std::unique_ptr<AST::TupleStructItemsRange> ( - new AST::TupleStructItemsRange (std::move (lower_patterns), - std::move (upper_patterns))); + return std::unique_ptr<AST::TupleStructItemsHasRest> ( + new AST::TupleStructItemsHasRest (std::move (lower_patterns), + std::move (upper_patterns))); } // has at least some lower patterns @@ -11369,8 +11375,8 @@ Parser<ManagedTokenSource>::parse_tuple_struct_items () switch (t->get_id ()) { case RIGHT_PAREN: - return std::unique_ptr<AST::TupleStructItemsNoRange> ( - new AST::TupleStructItemsNoRange (std::move (lower_patterns))); + return std::unique_ptr<AST::TupleStructItemsNoRest> ( + new AST::TupleStructItemsNoRest (std::move (lower_patterns))); case DOT_DOT: { // has an upper range that must be parsed separately @@ -11402,9 +11408,9 @@ Parser<ManagedTokenSource>::parse_tuple_struct_items () t = lexer.peek_token (); } - return std::unique_ptr<AST::TupleStructItemsRange> ( - new AST::TupleStructItemsRange (std::move (lower_patterns), - std::move (upper_patterns))); + return std::unique_ptr<AST::TupleStructItemsHasRest> ( + new AST::TupleStructItemsHasRest (std::move (lower_patterns), + std::move (upper_patterns))); } default: // error @@ -11424,7 +11430,7 @@ Parser<ManagedTokenSource>::parse_struct_pattern_elems () std::vector<std::unique_ptr<AST::StructPatternField>> fields; AST::AttrVec etc_attrs; - bool has_etc = false; + bool has_rest = false; // try parsing struct pattern fields const_TokenPtr t = lexer.peek_token (); @@ -11437,7 +11443,7 @@ Parser<ManagedTokenSource>::parse_struct_pattern_elems () { lexer.skip_token (); etc_attrs = std::move (outer_attrs); - has_etc = true; + has_rest = true; break; } @@ -11462,7 +11468,7 @@ Parser<ManagedTokenSource>::parse_struct_pattern_elems () t = lexer.peek_token (); } - if (has_etc) + if (has_rest) return AST::StructPatternElements (std::move (fields), std::move (etc_attrs)); else @@ -11761,6 +11767,8 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr () std::unique_ptr<AST::MacroInvocation> invoc = parse_macro_invocation_partial (std::move (path), std::move (outer_attrs)); + if (invoc == nullptr) + return ExprOrStmt::create_error (); if (restrictions.consume_semi && maybe_skip_token (SEMICOLON)) { @@ -11772,9 +11780,12 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr () TokenId after_macro = lexer.peek_token ()->get_id (); - if (invoc->get_invoc_data ().get_delim_tok_tree ().get_delim_type () - == AST::CURLY - && after_macro != DOT && after_macro != QUESTION_MARK) + AST::DelimType delim_type = invoc->get_invoc_data () + .get_delim_tok_tree () + .get_delim_type (); + + if (delim_type == AST::CURLY && after_macro != DOT + && after_macro != QUESTION_MARK) { rust_debug ("braced macro statement"); return ExprOrStmt ( @@ -12149,20 +12160,12 @@ Parser<ManagedTokenSource>::parse_expr (int right_binding_power, return nullptr; } - if (current_token->get_id () == LEFT_SHIFT) - { - lexer.split_current_token (LEFT_ANGLE, LEFT_ANGLE); - current_token = lexer.peek_token (); - } - - lexer.skip_token (); - ParseRestrictions null_denotation_restrictions = restrictions; null_denotation_restrictions.expr_can_be_stmt = false; // parse null denotation (unary part of expression) std::unique_ptr<AST::Expr> expr - = null_denotation (current_token, {}, null_denotation_restrictions); + = null_denotation ({}, null_denotation_restrictions); return left_denotations (std::move (expr), right_binding_power, std::move (outer_attrs), restrictions); @@ -12230,8 +12233,7 @@ Parser<ManagedTokenSource>::parse_expr (AST::AttrVec outer_attrs, /* Determines action to take when finding token at beginning of expression. */ template <typename ManagedTokenSource> std::unique_ptr<AST::Expr> -Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok, - AST::AttrVec outer_attrs, +Parser<ManagedTokenSource>::null_denotation (AST::AttrVec outer_attrs, ParseRestrictions restrictions) { /* note: tok is previous character in input stream, not current one, as @@ -12241,6 +12243,8 @@ Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok, * denotation and then a left denotation), null denotations handle primaries * and unary operands (but only prefix unary operands) */ + auto tok = lexer.peek_token (); + switch (tok->get_id ()) { case IDENTIFIER: @@ -12249,28 +12253,26 @@ Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok, case DOLLAR_SIGN: case CRATE: case SUPER: + case SCOPE_RESOLUTION: { // DEBUG rust_debug ("beginning null denotation identifier handling"); /* best option: parse as path, then extract identifier, macro, * struct/enum, or just path info from it */ - AST::PathInExpression path = parse_path_in_expression_pratt (tok); + AST::PathInExpression path = parse_path_in_expression (); return null_denotation_path (std::move (path), std::move (outer_attrs), restrictions); } - case SCOPE_RESOLUTION: - { - // TODO: fix: this is for global paths, i.e. std::string::whatever - Error error (tok->get_locus (), - "found null denotation scope resolution operator, and " - "have not written handling for it"); - add_error (std::move (error)); - - return nullptr; - } default: + if (tok->get_id () == LEFT_SHIFT) + { + lexer.split_current_token (LEFT_ANGLE, LEFT_ANGLE); + tok = lexer.peek_token (); + } + + lexer.skip_token (); return null_denotation_not_path (std::move (tok), std::move (outer_attrs), restrictions); } @@ -13035,12 +13037,6 @@ Parser<ManagedTokenSource>::left_denotation (const_TokenPtr tok, // array or slice index expression (pseudo binary infix) return parse_index_expr (tok, std::move (left), std::move (outer_attrs), restrictions); - case FLOAT_LITERAL: - /* HACK: get around lexer mis-identifying '.0' or '.1' or whatever as a - * float literal - TODO does this happen anymore? It shouldn't. */ - return parse_tuple_index_expr_float (tok, std::move (left), - std::move (outer_attrs), - restrictions); default: add_error (Error (tok->get_locus (), "found unexpected token %qs in left denotation", @@ -14436,119 +14432,6 @@ Parser<ManagedTokenSource>::parse_struct_expr_tuple_partial ( std::move (outer_attrs), path_locus)); } -/* Parses a path in expression with the first token passed as a parameter (as - * it is skipped in token stream). Note that this only parses segment-first - * paths, not global ones. */ -template <typename ManagedTokenSource> -AST::PathInExpression -Parser<ManagedTokenSource>::parse_path_in_expression_pratt (const_TokenPtr tok) -{ - // HACK-y way of making up for pratt-parsing consuming first token - - // DEBUG - rust_debug ("current peek token when starting path pratt parse: '%s'", - lexer.peek_token ()->get_token_description ()); - - // create segment vector - std::vector<AST::PathExprSegment> segments; - - std::string initial_str; - - switch (tok->get_id ()) - { - case IDENTIFIER: - initial_str = tok->get_str (); - break; - case SUPER: - initial_str = Values::Keywords::SUPER; - break; - case SELF: - initial_str = Values::Keywords::SELF; - break; - case SELF_ALIAS: - initial_str = Values::Keywords::SELF_ALIAS; - break; - case CRATE: - initial_str = Values::Keywords::CRATE; - break; - case DOLLAR_SIGN: - if (lexer.peek_token ()->get_id () == CRATE) - { - initial_str = "$crate"; - break; - } - gcc_fallthrough (); - default: - add_error (Error (tok->get_locus (), - "unrecognised token %qs in path in expression", - tok->get_token_description ())); - - return AST::PathInExpression::create_error (); - } - - // parse required initial segment - AST::PathExprSegment initial_segment (initial_str, tok->get_locus ()); - // parse generic args (and turbofish), if they exist - /* use lookahead to determine if they actually exist (don't want to - * accidently parse over next ident segment) */ - if (lexer.peek_token ()->get_id () == SCOPE_RESOLUTION - && lexer.peek_token (1)->get_id () == LEFT_ANGLE) - { - // skip scope resolution - lexer.skip_token (); - - AST::GenericArgs generic_args = parse_path_generic_args (); - - initial_segment - = AST::PathExprSegment (AST::PathIdentSegment (initial_str, - tok->get_locus ()), - tok->get_locus (), std::move (generic_args)); - } - if (initial_segment.is_error ()) - { - // skip after somewhere? - // don't necessarily throw error but yeah - - // DEBUG - rust_debug ("initial segment is error - returning null"); - - return AST::PathInExpression::create_error (); - } - segments.push_back (std::move (initial_segment)); - - // parse optional segments (as long as scope resolution operator exists) - const_TokenPtr t = lexer.peek_token (); - while (t->get_id () == SCOPE_RESOLUTION) - { - // skip scope resolution operator - lexer.skip_token (); - - // parse the actual segment - it is an error if it doesn't exist now - AST::PathExprSegment segment = parse_path_expr_segment (); - if (segment.is_error ()) - { - // skip after somewhere? - Error error (t->get_locus (), - "could not parse path expression segment"); - add_error (std::move (error)); - - return AST::PathInExpression::create_error (); - } - - segments.push_back (std::move (segment)); - - t = lexer.peek_token (); - } - - // DEBUG: - rust_debug ( - "current token (just about to return path to null denotation): '%s'", - lexer.peek_token ()->get_token_description ()); - - return AST::PathInExpression (std::move (segments), {}, tok->get_locus (), - false); -} - // Parses a closure expression with pratt parsing (from null denotation). template <typename ManagedTokenSource> std::unique_ptr<AST::ClosureExpr> @@ -14686,35 +14569,6 @@ Parser<ManagedTokenSource>::parse_closure_expr_pratt (const_TokenPtr tok, } } -/* Parses a tuple index expression (pratt-parsed) from a 'float' token as a - * result of lexer misidentification. */ -template <typename ManagedTokenSource> -std::unique_ptr<AST::TupleIndexExpr> -Parser<ManagedTokenSource>::parse_tuple_index_expr_float ( - const_TokenPtr tok, std::unique_ptr<AST::Expr> tuple_expr, - AST::AttrVec outer_attrs, ParseRestrictions restrictions ATTRIBUTE_UNUSED) -{ - // only works on float literals - if (tok->get_id () != FLOAT_LITERAL) - return nullptr; - - // DEBUG: - rust_debug ("exact string form of float: '%s'", tok->get_str ().c_str ()); - - // get float string and remove dot and initial 0 - std::string index_str = tok->get_str (); - index_str.erase (index_str.begin ()); - - // get int from string - int index = atoi (index_str.c_str ()); - - location_t locus = tuple_expr->get_locus (); - - return std::unique_ptr<AST::TupleIndexExpr> ( - new AST::TupleIndexExpr (std::move (tuple_expr), index, - std::move (outer_attrs), locus)); -} - // Returns true if the next token is END, ELSE, or EOF; template <typename ManagedTokenSource> bool diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h index 8253885..7b40463 100644 --- a/gcc/rust/parse/rust-parse.h +++ b/gcc/rust/parse/rust-parse.h @@ -212,6 +212,11 @@ public: std::unique_ptr<AST::MacroInvocation> parse_macro_invocation (AST::AttrVec outer_attrs); + /* + * This has to be public for parsing expressions with outer attributes + */ + AST::AttrVec parse_outer_attributes (); + private: void skip_after_semicolon (); void skip_after_end (); @@ -228,7 +233,6 @@ private: // AST-related stuff - maybe move or something? AST::Attribute parse_inner_attribute (); - AST::AttrVec parse_outer_attributes (); AST::Attribute parse_outer_attribute (); std::unique_ptr<AST::AttrInput> parse_attr_input (); std::tuple<AST::SimplePath, std::unique_ptr<AST::AttrInput>, location_t> @@ -368,7 +372,7 @@ private: AST::AttrVec outer_attrs); std::unique_ptr<AST::TraitItemType> parse_trait_type (AST::AttrVec outer_attrs, AST::Visibility); - std::unique_ptr<AST::TraitItemConst> + std::unique_ptr<AST::ConstantItem> parse_trait_const (AST::AttrVec outer_attrs); tl::expected<std::unique_ptr<AST::Param>, ParseSelfError> parse_self_param (); @@ -393,7 +397,7 @@ private: AST::AttrVec outer_attrs = AST::AttrVec (), ParseRestrictions restrictions = ParseRestrictions ()); std::unique_ptr<AST::Expr> - null_denotation (const_TokenPtr t, AST::AttrVec outer_attrs = AST::AttrVec (), + null_denotation (AST::AttrVec outer_attrs = AST::AttrVec (), ParseRestrictions restrictions = ParseRestrictions ()); std::unique_ptr<AST::Expr> null_denotation_path (AST::PathInExpression path, AST::AttrVec outer_attrs, @@ -598,7 +602,6 @@ private: std::unique_ptr<AST::CallExpr> parse_struct_expr_tuple_partial (AST::PathInExpression path, AST::AttrVec outer_attrs); - AST::PathInExpression parse_path_in_expression_pratt (const_TokenPtr tok); std::unique_ptr<AST::ClosureExpr> parse_closure_expr_pratt (const_TokenPtr tok, AST::AttrVec outer_attrs = AST::AttrVec ()); @@ -782,7 +785,7 @@ private: // don't want to make things *only* AttributeParser uses public // TODO: fold more of AttributeParser into Parser? - friend class ::Rust::AST::AttributeParser; + friend struct ::Rust::AST::AttributeParser; }; std::string extract_module_path (const AST::AttrVec &inner_attrs, |
