Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
209 changes: 44 additions & 165 deletions gcc/rust/ast/rust-ast.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3531,9 +3531,9 @@ std::unique_ptr<MetaItemInner>
AttributeParser::parse_meta_item_inner ()
{
// if first tok not identifier, not a "special" case one
if (peek_token ()->get_id () != IDENTIFIER)
if (lexer->peek_token ()->get_id () != IDENTIFIER)
{
switch (peek_token ()->get_id ())
switch (lexer->peek_token ()->get_id ())
{
case CHAR_LITERAL:
case STRING_LITERAL:
Expand All @@ -3554,42 +3554,43 @@ AttributeParser::parse_meta_item_inner ()
return parse_path_meta_item ();

default:
rust_error_at (peek_token ()->get_locus (),
rust_error_at (lexer->peek_token ()->get_locus (),
"unrecognised token '%s' in meta item",
get_token_description (peek_token ()->get_id ()));
get_token_description (
lexer->peek_token ()->get_id ()));
return nullptr;
}
}

// else, check for path
if (peek_token (1)->get_id () == SCOPE_RESOLUTION)
if (lexer->peek_token (1)->get_id () == SCOPE_RESOLUTION)
{
// path
return parse_path_meta_item ();
}

auto ident = peek_token ()->get_str ();
auto ident_locus = peek_token ()->get_locus ();
auto ident = lexer->peek_token ()->get_str ();
auto ident_locus = lexer->peek_token ()->get_locus ();

if (is_end_meta_item_tok (peek_token (1)->get_id ()))
if (is_end_meta_item_tok (lexer->peek_token (1)->get_id ()))
{
// meta word syntax
skip_token ();
lexer->skip_token ();
return std::unique_ptr<MetaWord> (new MetaWord (ident, ident_locus));
}

if (peek_token (1)->get_id () == EQUAL)
if (lexer->peek_token (1)->get_id () == EQUAL)
{
// maybe meta name value str syntax - check next 2 tokens
if (peek_token (2)->get_id () == STRING_LITERAL
&& is_end_meta_item_tok (peek_token (3)->get_id ()))
if (lexer->peek_token (2)->get_id () == STRING_LITERAL
&& is_end_meta_item_tok (lexer->peek_token (3)->get_id ()))
{
// meta name value str syntax
const_TokenPtr value_tok = peek_token (2);
const_TokenPtr value_tok = lexer->peek_token (2);
auto value = value_tok->get_str ();
auto locus = value_tok->get_locus ();

skip_token (2);
lexer->skip_token (2);

return std::unique_ptr<MetaNameValueStr> (
new MetaNameValueStr (ident, ident_locus, std::move (value),
Expand All @@ -3602,16 +3603,16 @@ AttributeParser::parse_meta_item_inner ()
}
}

if (peek_token (1)->get_id () != LEFT_PAREN)
if (lexer->peek_token (1)->get_id () != LEFT_PAREN)
{
rust_error_at (peek_token (1)->get_locus (),
rust_error_at (lexer->peek_token (1)->get_locus (),
"unexpected token '%s' after identifier in attribute",
get_token_description (peek_token (1)->get_id ()));
get_token_description (lexer->peek_token (1)->get_id ()));
return nullptr;
}

// is it one of those special cases like not?
if (peek_token ()->get_id () == IDENTIFIER)
if (lexer->peek_token ()->get_id () == IDENTIFIER)
{
return parse_path_meta_item ();
}
Expand Down Expand Up @@ -3690,15 +3691,15 @@ AttributeParser::is_end_meta_item_tok (TokenId id) const
std::unique_ptr<MetaItem>
AttributeParser::parse_path_meta_item ()
{
SimplePath path = parse_simple_path ();
SimplePath path = parser->parse_simple_path ();
if (path.is_empty ())
{
rust_error_at (peek_token ()->get_locus (),
rust_error_at (lexer->peek_token ()->get_locus (),
"failed to parse simple path in attribute");
return nullptr;
}

switch (peek_token ()->get_id ())
switch (lexer->peek_token ()->get_id ())
{
case LEFT_PAREN:
{
Expand All @@ -3710,7 +3711,7 @@ AttributeParser::parse_path_meta_item ()
}
case EQUAL:
{
skip_token ();
lexer->skip_token ();

std::unique_ptr<Expr> expr = parser->parse_expr ();
// stream_pos++;
Expand All @@ -3724,9 +3725,9 @@ AttributeParser::parse_path_meta_item ()
return std::unique_ptr<MetaItemPath> (
new MetaItemPath (std::move (path)));
default:
rust_error_at (peek_token ()->get_locus (),
rust_error_at (lexer->peek_token ()->get_locus (),
"unrecognised token '%s' in meta item",
get_token_description (peek_token ()->get_id ()));
get_token_description (lexer->peek_token ()->get_id ()));
return nullptr;
}
}
Expand All @@ -3738,39 +3739,39 @@ AttributeParser::parse_meta_item_seq ()
{
std::vector<std::unique_ptr<MetaItemInner>> meta_items;

if (peek_token ()->get_id () != LEFT_PAREN)
if (lexer->peek_token ()->get_id () != LEFT_PAREN)
{
rust_error_at (peek_token ()->get_locus (),
rust_error_at (lexer->peek_token ()->get_locus (),
"missing left paren in delim token tree");
return {};
}
skip_token ();
lexer->skip_token ();

while (peek_token ()->get_id () != END_OF_FILE
&& peek_token ()->get_id () != RIGHT_PAREN)
while (lexer->peek_token ()->get_id () != END_OF_FILE
&& lexer->peek_token ()->get_id () != RIGHT_PAREN)
{
std::unique_ptr<MetaItemInner> inner = parse_meta_item_inner ();
if (inner == nullptr)
{
rust_error_at (peek_token ()->get_locus (),
rust_error_at (lexer->peek_token ()->get_locus (),
"failed to parse inner meta item in attribute");
return {};
}
meta_items.push_back (std::move (inner));

if (peek_token ()->get_id () != COMMA)
if (lexer->peek_token ()->get_id () != COMMA)
break;

skip_token ();
lexer->skip_token ();
}

if (peek_token ()->get_id () != RIGHT_PAREN)
if (lexer->peek_token ()->get_id () != RIGHT_PAREN)
{
rust_error_at (peek_token ()->get_locus (),
rust_error_at (lexer->peek_token ()->get_locus (),
"missing right paren in delim token tree");
return {};
}
skip_token ();
lexer->skip_token ();

return meta_items;
}
Expand All @@ -3793,141 +3794,19 @@ DelimTokenTree::to_token_stream () const
return tokens;
}

Literal
AttributeParser::parse_literal ()
{
const_TokenPtr tok = peek_token ();
switch (tok->get_id ())
{
case CHAR_LITERAL:
skip_token ();
return Literal (tok->get_str (), Literal::CHAR, tok->get_type_hint ());
case STRING_LITERAL:
skip_token ();
return Literal (tok->get_str (), Literal::STRING, tok->get_type_hint ());
case BYTE_CHAR_LITERAL:
skip_token ();
return Literal (tok->get_str (), Literal::BYTE, tok->get_type_hint ());
case BYTE_STRING_LITERAL:
skip_token ();
return Literal (tok->get_str (), Literal::BYTE_STRING,
tok->get_type_hint ());
case RAW_STRING_LITERAL:
skip_token ();
return Literal (tok->get_str (), Literal::RAW_STRING,
tok->get_type_hint ());
case INT_LITERAL:
skip_token ();
return Literal (tok->get_str (), Literal::INT, tok->get_type_hint ());
case FLOAT_LITERAL:
skip_token ();
return Literal (tok->get_str (), Literal::FLOAT, tok->get_type_hint ());
case TRUE_LITERAL:
skip_token ();
return Literal ("true", Literal::BOOL, tok->get_type_hint ());
case FALSE_LITERAL:
skip_token ();
return Literal ("false", Literal::BOOL, tok->get_type_hint ());
default:
rust_error_at (tok->get_locus (), "expected literal - found '%s'",
get_token_description (tok->get_id ()));
return Literal::create_error ();
}
}

SimplePath
AttributeParser::parse_simple_path ()
{
bool has_opening_scope_res = false;
if (peek_token ()->get_id () == SCOPE_RESOLUTION)
{
has_opening_scope_res = true;
skip_token ();
}

std::vector<SimplePathSegment> segments;

SimplePathSegment segment = parse_simple_path_segment ();
if (segment.is_error ())
{
rust_error_at (
peek_token ()->get_locus (),
"failed to parse simple path segment in attribute simple path");
return SimplePath::create_empty ();
}
segments.push_back (std::move (segment));

while (peek_token ()->get_id () == SCOPE_RESOLUTION)
{
skip_token ();

SimplePathSegment segment = parse_simple_path_segment ();
if (segment.is_error ())
{
rust_error_at (
peek_token ()->get_locus (),
"failed to parse simple path segment in attribute simple path");
return SimplePath::create_empty ();
}
segments.push_back (std::move (segment));
}
segments.shrink_to_fit ();

return SimplePath (std::move (segments), has_opening_scope_res);
}

SimplePathSegment
AttributeParser::parse_simple_path_segment ()
{
const_TokenPtr tok = peek_token ();
switch (tok->get_id ())
{
case IDENTIFIER:
skip_token ();
return SimplePathSegment (tok->get_str (), tok->get_locus ());
case SUPER:
skip_token ();
return SimplePathSegment ("super", tok->get_locus ());
case SELF:
skip_token ();
return SimplePathSegment ("self", tok->get_locus ());
case CRATE:
skip_token ();
return SimplePathSegment ("crate", tok->get_locus ());
case DOLLAR_SIGN:
if (peek_token (1)->get_id () == CRATE)
{
skip_token (1);
return SimplePathSegment ("$crate", tok->get_locus ());
}
gcc_fallthrough ();
default:
rust_error_at (tok->get_locus (),
"unexpected token '%s' in simple path segment",
get_token_description (tok->get_id ()));
return SimplePathSegment::create_error ();
}
}

std::unique_ptr<MetaItemLitExpr>
AttributeParser::parse_meta_item_lit ()
{
location_t locus = peek_token ()->get_locus ();
LiteralExpr lit_expr (parse_literal (), {}, locus);
return std::unique_ptr<MetaItemLitExpr> (
new MetaItemLitExpr (std::move (lit_expr)));
}
std::unique_ptr<LiteralExpr> lit_expr = parser->parse_literal_expr ({});

const_TokenPtr
AttributeParser::peek_token (int i)
{
return lexer->peek_token (i);
}
// TODO: return nullptr instead?
if (!lit_expr)
lit_expr = std::unique_ptr<LiteralExpr> (
new LiteralExpr (Literal::create_error (), {},
lexer->peek_token ()->get_locus ()));

void
AttributeParser::skip_token (int i)
{
lexer->skip_token (i);
return std::unique_ptr<MetaItemLitExpr> (
new MetaItemLitExpr (std::move (*lit_expr)));
}

bool
Expand Down
11 changes: 0 additions & 11 deletions gcc/rust/ast/rust-macro.h
Original file line number Diff line number Diff line change
Expand Up @@ -1137,21 +1137,10 @@ struct AttributeParser
std::unique_ptr<MetaItemInner> parse_meta_item_inner ();
// Returns whether token can end a meta item.
bool is_end_meta_item_tok (TokenId id) const;
// Parses a simple path.
SimplePath parse_simple_path ();
// Parses a segment of a simple path (but not scope resolution operator).
SimplePathSegment parse_simple_path_segment ();
// Parses a MetaItemLitExpr.
std::unique_ptr<MetaItemLitExpr> parse_meta_item_lit ();
// Parses a literal.
Literal parse_literal ();
// Parses a meta item that begins with a simple path.
std::unique_ptr<MetaItem> parse_path_meta_item ();

// TODO: should this be const?
const_TokenPtr peek_token (int i = 0);

void skip_token (int i = 0);
};
} // namespace AST
} // namespace Rust
Expand Down
4 changes: 4 additions & 0 deletions gcc/rust/parse/rust-parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,10 @@ template <typename ManagedTokenSource> class Parser
}
~InlineModuleStackScope () { parser.inline_module_stack.pop_back (); }
};

// don't want to make things *only* AttributeParser uses public
// TODO: fold more of AttributeParser into Parser?
friend class ::Rust::AST::AttributeParser;
};

std::string extract_module_path (const AST::AttrVec &inner_attrs,
Expand Down
Loading