@@ -3531,9 +3531,9 @@ std::unique_ptr<MetaItemInner>
3531
3531
AttributeParser::parse_meta_item_inner ()
3532
3532
{
3533
3533
// if first tok not identifier, not a "special" case one
3534
- if (peek_token ()->get_id () != IDENTIFIER)
3534
+ if (lexer-> peek_token ()->get_id () != IDENTIFIER)
3535
3535
{
3536
- switch (peek_token ()->get_id ())
3536
+ switch (lexer-> peek_token ()->get_id ())
3537
3537
{
3538
3538
case CHAR_LITERAL:
3539
3539
case STRING_LITERAL:
@@ -3554,42 +3554,43 @@ AttributeParser::parse_meta_item_inner ()
3554
3554
return parse_path_meta_item ();
3555
3555
3556
3556
default :
3557
- rust_error_at (peek_token ()->get_locus (),
3557
+ rust_error_at (lexer-> peek_token ()->get_locus (),
3558
3558
" unrecognised token '%s' in meta item" ,
3559
- get_token_description (peek_token ()->get_id ()));
3559
+ get_token_description (
3560
+ lexer->peek_token ()->get_id ()));
3560
3561
return nullptr ;
3561
3562
}
3562
3563
}
3563
3564
3564
3565
// else, check for path
3565
- if (peek_token (1 )->get_id () == SCOPE_RESOLUTION)
3566
+ if (lexer-> peek_token (1 )->get_id () == SCOPE_RESOLUTION)
3566
3567
{
3567
3568
// path
3568
3569
return parse_path_meta_item ();
3569
3570
}
3570
3571
3571
- auto ident = peek_token ()->get_str ();
3572
- auto ident_locus = peek_token ()->get_locus ();
3572
+ auto ident = lexer-> peek_token ()->get_str ();
3573
+ auto ident_locus = lexer-> peek_token ()->get_locus ();
3573
3574
3574
- if (is_end_meta_item_tok (peek_token (1 )->get_id ()))
3575
+ if (is_end_meta_item_tok (lexer-> peek_token (1 )->get_id ()))
3575
3576
{
3576
3577
// meta word syntax
3577
- skip_token ();
3578
+ lexer-> skip_token ();
3578
3579
return std::unique_ptr<MetaWord> (new MetaWord (ident, ident_locus));
3579
3580
}
3580
3581
3581
- if (peek_token (1 )->get_id () == EQUAL)
3582
+ if (lexer-> peek_token (1 )->get_id () == EQUAL)
3582
3583
{
3583
3584
// maybe meta name value str syntax - check next 2 tokens
3584
- if (peek_token (2 )->get_id () == STRING_LITERAL
3585
- && is_end_meta_item_tok (peek_token (3 )->get_id ()))
3585
+ if (lexer-> peek_token (2 )->get_id () == STRING_LITERAL
3586
+ && is_end_meta_item_tok (lexer-> peek_token (3 )->get_id ()))
3586
3587
{
3587
3588
// meta name value str syntax
3588
- const_TokenPtr value_tok = peek_token (2 );
3589
+ const_TokenPtr value_tok = lexer-> peek_token (2 );
3589
3590
auto value = value_tok->get_str ();
3590
3591
auto locus = value_tok->get_locus ();
3591
3592
3592
- skip_token (2 );
3593
+ lexer-> skip_token (2 );
3593
3594
3594
3595
return std::unique_ptr<MetaNameValueStr> (
3595
3596
new MetaNameValueStr (ident, ident_locus, std::move (value),
@@ -3602,16 +3603,16 @@ AttributeParser::parse_meta_item_inner ()
3602
3603
}
3603
3604
}
3604
3605
3605
- if (peek_token (1 )->get_id () != LEFT_PAREN)
3606
+ if (lexer-> peek_token (1 )->get_id () != LEFT_PAREN)
3606
3607
{
3607
- rust_error_at (peek_token (1 )->get_locus (),
3608
+ rust_error_at (lexer-> peek_token (1 )->get_locus (),
3608
3609
" unexpected token '%s' after identifier in attribute" ,
3609
- get_token_description (peek_token (1 )->get_id ()));
3610
+ get_token_description (lexer-> peek_token (1 )->get_id ()));
3610
3611
return nullptr ;
3611
3612
}
3612
3613
3613
3614
// is it one of those special cases like not?
3614
- if (peek_token ()->get_id () == IDENTIFIER)
3615
+ if (lexer-> peek_token ()->get_id () == IDENTIFIER)
3615
3616
{
3616
3617
return parse_path_meta_item ();
3617
3618
}
@@ -3690,15 +3691,15 @@ AttributeParser::is_end_meta_item_tok (TokenId id) const
3690
3691
std::unique_ptr<MetaItem>
3691
3692
AttributeParser::parse_path_meta_item ()
3692
3693
{
3693
- SimplePath path = parse_simple_path ();
3694
+ SimplePath path = parser-> parse_simple_path ();
3694
3695
if (path.is_empty ())
3695
3696
{
3696
- rust_error_at (peek_token ()->get_locus (),
3697
+ rust_error_at (lexer-> peek_token ()->get_locus (),
3697
3698
" failed to parse simple path in attribute" );
3698
3699
return nullptr ;
3699
3700
}
3700
3701
3701
- switch (peek_token ()->get_id ())
3702
+ switch (lexer-> peek_token ()->get_id ())
3702
3703
{
3703
3704
case LEFT_PAREN:
3704
3705
{
@@ -3710,31 +3711,26 @@ AttributeParser::parse_path_meta_item ()
3710
3711
}
3711
3712
case EQUAL:
3712
3713
{
3713
- skip_token ();
3714
+ lexer->skip_token ();
3715
+
3716
+ std::unique_ptr<LiteralExpr> expr = parser->parse_literal_expr ({});
3717
+
3718
+ // handle error
3719
+ // parse_literal_expr should already emit an error and return nullptr
3720
+ if (!expr)
3721
+ return nullptr ;
3714
3722
3715
- location_t locus = peek_token ()->get_locus ();
3716
- Literal lit = parse_literal ();
3717
- if (lit.is_error ())
3718
- {
3719
- rust_error_at (peek_token ()->get_locus (),
3720
- " failed to parse literal in attribute" );
3721
- return nullptr ;
3722
- }
3723
- LiteralExpr expr (std::move (lit), {}, locus);
3724
- // stream_pos++;
3725
- /* shouldn't be required anymore due to parsing literal actually
3726
- * skipping the token */
3727
3723
return std::unique_ptr<MetaItemPathLit> (
3728
- new MetaItemPathLit (std::move (path), std::move (expr)));
3724
+ new MetaItemPathLit (std::move (path), std::move (* expr)));
3729
3725
}
3730
3726
case COMMA:
3731
3727
// just simple path
3732
3728
return std::unique_ptr<MetaItemPath> (
3733
3729
new MetaItemPath (std::move (path)));
3734
3730
default :
3735
- rust_error_at (peek_token ()->get_locus (),
3731
+ rust_error_at (lexer-> peek_token ()->get_locus (),
3736
3732
" unrecognised token '%s' in meta item" ,
3737
- get_token_description (peek_token ()->get_id ()));
3733
+ get_token_description (lexer-> peek_token ()->get_id ()));
3738
3734
return nullptr ;
3739
3735
}
3740
3736
}
@@ -3746,39 +3742,39 @@ AttributeParser::parse_meta_item_seq ()
3746
3742
{
3747
3743
std::vector<std::unique_ptr<MetaItemInner>> meta_items;
3748
3744
3749
- if (peek_token ()->get_id () != LEFT_PAREN)
3745
+ if (lexer-> peek_token ()->get_id () != LEFT_PAREN)
3750
3746
{
3751
- rust_error_at (peek_token ()->get_locus (),
3747
+ rust_error_at (lexer-> peek_token ()->get_locus (),
3752
3748
" missing left paren in delim token tree" );
3753
3749
return {};
3754
3750
}
3755
- skip_token ();
3751
+ lexer-> skip_token ();
3756
3752
3757
- while (peek_token ()->get_id () != END_OF_FILE
3758
- && peek_token ()->get_id () != RIGHT_PAREN)
3753
+ while (lexer-> peek_token ()->get_id () != END_OF_FILE
3754
+ && lexer-> peek_token ()->get_id () != RIGHT_PAREN)
3759
3755
{
3760
3756
std::unique_ptr<MetaItemInner> inner = parse_meta_item_inner ();
3761
3757
if (inner == nullptr )
3762
3758
{
3763
- rust_error_at (peek_token ()->get_locus (),
3759
+ rust_error_at (lexer-> peek_token ()->get_locus (),
3764
3760
" failed to parse inner meta item in attribute" );
3765
3761
return {};
3766
3762
}
3767
3763
meta_items.push_back (std::move (inner));
3768
3764
3769
- if (peek_token ()->get_id () != COMMA)
3765
+ if (lexer-> peek_token ()->get_id () != COMMA)
3770
3766
break ;
3771
3767
3772
- skip_token ();
3768
+ lexer-> skip_token ();
3773
3769
}
3774
3770
3775
- if (peek_token ()->get_id () != RIGHT_PAREN)
3771
+ if (lexer-> peek_token ()->get_id () != RIGHT_PAREN)
3776
3772
{
3777
- rust_error_at (peek_token ()->get_locus (),
3773
+ rust_error_at (lexer-> peek_token ()->get_locus (),
3778
3774
" missing right paren in delim token tree" );
3779
3775
return {};
3780
3776
}
3781
- skip_token ();
3777
+ lexer-> skip_token ();
3782
3778
3783
3779
return meta_items;
3784
3780
}
@@ -3801,141 +3797,19 @@ DelimTokenTree::to_token_stream () const
3801
3797
return tokens;
3802
3798
}
3803
3799
3804
- Literal
3805
- AttributeParser::parse_literal ()
3806
- {
3807
- const_TokenPtr tok = peek_token ();
3808
- switch (tok->get_id ())
3809
- {
3810
- case CHAR_LITERAL:
3811
- skip_token ();
3812
- return Literal (tok->get_str (), Literal::CHAR, tok->get_type_hint ());
3813
- case STRING_LITERAL:
3814
- skip_token ();
3815
- return Literal (tok->get_str (), Literal::STRING, tok->get_type_hint ());
3816
- case BYTE_CHAR_LITERAL:
3817
- skip_token ();
3818
- return Literal (tok->get_str (), Literal::BYTE, tok->get_type_hint ());
3819
- case BYTE_STRING_LITERAL:
3820
- skip_token ();
3821
- return Literal (tok->get_str (), Literal::BYTE_STRING,
3822
- tok->get_type_hint ());
3823
- case RAW_STRING_LITERAL:
3824
- skip_token ();
3825
- return Literal (tok->get_str (), Literal::RAW_STRING,
3826
- tok->get_type_hint ());
3827
- case INT_LITERAL:
3828
- skip_token ();
3829
- return Literal (tok->get_str (), Literal::INT, tok->get_type_hint ());
3830
- case FLOAT_LITERAL:
3831
- skip_token ();
3832
- return Literal (tok->get_str (), Literal::FLOAT, tok->get_type_hint ());
3833
- case TRUE_LITERAL:
3834
- skip_token ();
3835
- return Literal (" true" , Literal::BOOL, tok->get_type_hint ());
3836
- case FALSE_LITERAL:
3837
- skip_token ();
3838
- return Literal (" false" , Literal::BOOL, tok->get_type_hint ());
3839
- default :
3840
- rust_error_at (tok->get_locus (), " expected literal - found '%s'" ,
3841
- get_token_description (tok->get_id ()));
3842
- return Literal::create_error ();
3843
- }
3844
- }
3845
-
3846
- SimplePath
3847
- AttributeParser::parse_simple_path ()
3848
- {
3849
- bool has_opening_scope_res = false ;
3850
- if (peek_token ()->get_id () == SCOPE_RESOLUTION)
3851
- {
3852
- has_opening_scope_res = true ;
3853
- skip_token ();
3854
- }
3855
-
3856
- std::vector<SimplePathSegment> segments;
3857
-
3858
- SimplePathSegment segment = parse_simple_path_segment ();
3859
- if (segment.is_error ())
3860
- {
3861
- rust_error_at (
3862
- peek_token ()->get_locus (),
3863
- " failed to parse simple path segment in attribute simple path" );
3864
- return SimplePath::create_empty ();
3865
- }
3866
- segments.push_back (std::move (segment));
3867
-
3868
- while (peek_token ()->get_id () == SCOPE_RESOLUTION)
3869
- {
3870
- skip_token ();
3871
-
3872
- SimplePathSegment segment = parse_simple_path_segment ();
3873
- if (segment.is_error ())
3874
- {
3875
- rust_error_at (
3876
- peek_token ()->get_locus (),
3877
- " failed to parse simple path segment in attribute simple path" );
3878
- return SimplePath::create_empty ();
3879
- }
3880
- segments.push_back (std::move (segment));
3881
- }
3882
- segments.shrink_to_fit ();
3883
-
3884
- return SimplePath (std::move (segments), has_opening_scope_res);
3885
- }
3886
-
3887
- SimplePathSegment
3888
- AttributeParser::parse_simple_path_segment ()
3889
- {
3890
- const_TokenPtr tok = peek_token ();
3891
- switch (tok->get_id ())
3892
- {
3893
- case IDENTIFIER:
3894
- skip_token ();
3895
- return SimplePathSegment (tok->get_str (), tok->get_locus ());
3896
- case SUPER:
3897
- skip_token ();
3898
- return SimplePathSegment (" super" , tok->get_locus ());
3899
- case SELF:
3900
- skip_token ();
3901
- return SimplePathSegment (" self" , tok->get_locus ());
3902
- case CRATE:
3903
- skip_token ();
3904
- return SimplePathSegment (" crate" , tok->get_locus ());
3905
- case DOLLAR_SIGN:
3906
- if (peek_token (1 )->get_id () == CRATE)
3907
- {
3908
- skip_token (1 );
3909
- return SimplePathSegment (" $crate" , tok->get_locus ());
3910
- }
3911
- gcc_fallthrough ();
3912
- default :
3913
- rust_error_at (tok->get_locus (),
3914
- " unexpected token '%s' in simple path segment" ,
3915
- get_token_description (tok->get_id ()));
3916
- return SimplePathSegment::create_error ();
3917
- }
3918
- }
3919
-
3920
3800
std::unique_ptr<MetaItemLitExpr>
3921
3801
AttributeParser::parse_meta_item_lit ()
3922
3802
{
3923
- location_t locus = peek_token ()->get_locus ();
3924
- LiteralExpr lit_expr (parse_literal (), {}, locus);
3925
- return std::unique_ptr<MetaItemLitExpr> (
3926
- new MetaItemLitExpr (std::move (lit_expr)));
3927
- }
3803
+ std::unique_ptr<LiteralExpr> lit_expr = parser->parse_literal_expr ({});
3928
3804
3929
- const_TokenPtr
3930
- AttributeParser::peek_token ( int i )
3931
- {
3932
- return lexer-> peek_token (i);
3933
- }
3805
+ // TODO: return nullptr instead?
3806
+ if (!lit_expr )
3807
+ lit_expr = std::unique_ptr<LiteralExpr> (
3808
+ new LiteralExpr ( Literal::create_error (), {},
3809
+ lexer-> peek_token ()-> get_locus ()));
3934
3810
3935
- void
3936
- AttributeParser::skip_token (int i)
3937
- {
3938
- lexer->skip_token (i);
3811
+ return std::unique_ptr<MetaItemLitExpr> (
3812
+ new MetaItemLitExpr (std::move (*lit_expr)));
3939
3813
}
3940
3814
3941
3815
bool
0 commit comments