aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/parse
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/parse')
-rw-r--r--gcc/rust/parse/rust-parse-impl.h127
-rw-r--r--gcc/rust/parse/rust-parse.h72
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.