1 //! This is the actual "grammar" of the Rust language.
3 //! Each function in this module and its children corresponds
4 //! to a production of the formal grammar. Submodules roughly
5 //! correspond to different *areas* of the grammar. By convention,
6 //! each submodule starts with `use super::*` import and exports
7 //! "public" productions via `pub(super)`.
9 //! See docs for [`Parser`](super::parser::Parser) to learn about API,
10 //! available to the grammar, and see docs for [`Event`](super::event::Event)
11 //! to learn how this actually manages to produce parse trees.
13 //! Code in this module also contains inline tests, which start with
14 //! `// test name-of-the-test` comment and look like this:
17 //! // test function_with_zero_parameters
21 //! After adding a new inline-test, run `cargo test -p xtask` to
22 //! extract it as a standalone text-fixture into
23 //! `crates/syntax/test_data/parser/`, and run `cargo test` once to
24 //! create the "gold" value.
26 //! Coding convention: rules like `where_clause` always produce either a
27 //! node or an error, rules like `opt_where_clause` may produce nothing.
28 //! Non-opt rules typically start with `assert!(p.at(FIRST_TOKEN))`, the
29 //! caller is responsible for branching on the first token.
42 parser
::{CompletedMarker, Marker, Parser}
,
43 SyntaxKind
::{self, *}
,
47 pub(crate) mod entry
{
50 pub(crate) mod prefix
{
53 pub(crate) fn vis(p
: &mut Parser
<'_
>) {
54 let _
= opt_visibility(p
, false);
57 pub(crate) fn block(p
: &mut Parser
<'_
>) {
58 expressions
::block_expr(p
);
61 pub(crate) fn stmt(p
: &mut Parser
<'_
>) {
62 expressions
::stmt(p
, expressions
::Semicolon
::Forbidden
);
65 pub(crate) fn pat(p
: &mut Parser
<'_
>) {
66 patterns
::pattern_single(p
);
69 pub(crate) fn ty(p
: &mut Parser
<'_
>) {
72 pub(crate) fn expr(p
: &mut Parser
<'_
>) {
73 let _
= expressions
::expr(p
);
75 pub(crate) fn path(p
: &mut Parser
<'_
>) {
76 let _
= paths
::type_path(p
);
78 pub(crate) fn item(p
: &mut Parser
<'_
>) {
79 items
::item_or_macro(p
, true);
81 // Parse a meta item , which excluded [], e.g : #[ MetaItem ]
82 pub(crate) fn meta_item(p
: &mut Parser
<'_
>) {
90 pub(crate) fn source_file(p
: &mut Parser
<'_
>) {
93 items
::mod_contents(p
, false);
94 m
.complete(p
, SOURCE_FILE
);
97 pub(crate) fn macro_stmts(p
: &mut Parser
<'_
>) {
101 expressions
::stmt(p
, expressions
::Semicolon
::Optional
);
104 m
.complete(p
, MACRO_STMTS
);
107 pub(crate) fn macro_items(p
: &mut Parser
<'_
>) {
109 items
::mod_contents(p
, false);
110 m
.complete(p
, MACRO_ITEMS
);
113 pub(crate) fn pattern(p
: &mut Parser
<'_
>) {
115 patterns
::pattern_top(p
);
123 m
.complete(p
, ERROR
);
126 pub(crate) fn type_(p
: &mut Parser
<'_
>) {
136 m
.complete(p
, ERROR
);
139 pub(crate) fn expr(p
: &mut Parser
<'_
>) {
141 expressions
::expr(p
);
149 m
.complete(p
, ERROR
);
152 pub(crate) fn meta_item(p
: &mut Parser
<'_
>) {
162 m
.complete(p
, ERROR
);
167 pub(crate) fn reparser(
169 first_child
: Option
<SyntaxKind
>,
170 parent
: Option
<SyntaxKind
>,
171 ) -> Option
<fn(&mut Parser
<'_
>)> {
172 let res
= match node
{
173 BLOCK_EXPR
=> expressions
::block_expr
,
174 RECORD_FIELD_LIST
=> items
::record_field_list
,
175 RECORD_EXPR_FIELD_LIST
=> items
::record_expr_field_list
,
176 VARIANT_LIST
=> items
::variant_list
,
177 MATCH_ARM_LIST
=> items
::match_arm_list
,
178 USE_TREE_LIST
=> items
::use_tree_list
,
179 EXTERN_ITEM_LIST
=> items
::extern_item_list
,
180 TOKEN_TREE
if first_child?
== T
!['
{'
] => items
::token_tree
,
181 ASSOC_ITEM_LIST
=> match parent?
{
182 IMPL
| TRAIT
=> items
::assoc_item_list
,
185 ITEM_LIST
=> items
::item_list
,
191 #[derive(Clone, Copy, PartialEq, Eq)]
198 fn is_block(self) -> bool
{
199 self == BlockLike
::Block
203 fn opt_visibility(p
: &mut Parser
<'_
>, in_tuple_field
: bool
) -> bool
{
210 // test crate_visibility
211 // pub(crate) struct S;
212 // pub(self) struct S;
213 // pub(super) struct S;
215 // test pub_parens_typepath
216 // struct B(pub (super::A));
217 // struct B(pub (crate::A,));
218 T
![crate] | T
![self] | T
![super] | T
![ident
] if p
.nth(2) != T
![:] => {
219 // If we are in a tuple struct, then the parens following `pub`
220 // might be an tuple field, not part of the visibility. So in that
221 // case we don't want to consume an identifier.
223 // test pub_tuple_field
224 // struct MyStruct(pub (u32, u32));
225 if !(in_tuple_field
&& matches
!(p
.nth(1), T
![ident
])) {
231 // test crate_visibility_in
232 // pub(in super::A) struct S;
233 // pub(in crate) struct S;
243 m
.complete(p
, VISIBILITY
);
246 // test crate_keyword_vis
247 // crate fn main() { }
248 // struct S { crate field: u32 }
249 // struct T(crate u32);
251 if p
.nth_at(1, T
![::]) {
252 // test crate_keyword_path
253 // fn foo() { crate::foo(); }
258 m
.complete(p
, VISIBILITY
);
265 fn opt_rename(p
: &mut Parser
<'_
>) {
272 m
.complete(p
, RENAME
);
276 fn abi(p
: &mut Parser
<'_
>) {
277 assert
!(p
.at(T
![extern]));
281 abi
.complete(p
, ABI
);
284 fn opt_ret_type(p
: &mut Parser
<'_
>) -> bool
{
288 types
::type_no_bounds(p
);
289 m
.complete(p
, RET_TYPE
);
296 fn name_r(p
: &mut Parser
<'_
>, recovery
: TokenSet
) {
302 p
.err_recover("expected a name", recovery
);
306 fn name(p
: &mut Parser
<'_
>) {
307 name_r(p
, TokenSet
::EMPTY
);
310 fn name_ref(p
: &mut Parser
<'_
>) {
314 m
.complete(p
, NAME_REF
);
316 p
.err_and_bump("expected identifier");
320 fn name_ref_or_index(p
: &mut Parser
<'_
>) {
321 assert
!(p
.at(IDENT
) || p
.at(INT_NUMBER
));
324 m
.complete(p
, NAME_REF
);
327 fn lifetime(p
: &mut Parser
<'_
>) {
328 assert
!(p
.at(LIFETIME_IDENT
));
330 p
.bump(LIFETIME_IDENT
);
331 m
.complete(p
, LIFETIME
);
334 fn error_block(p
: &mut Parser
<'_
>, message
: &str) {
335 assert
!(p
.at(T
!['
{'
]));
339 expressions
::expr_block_contents(p
);
341 m
.complete(p
, ERROR
);