aboutsummaryrefslogtreecommitdiff
path: root/src/grammar/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/grammar/mod.rs')
-rw-r--r--src/grammar/mod.rs141
1 files changed, 141 insertions, 0 deletions
diff --git a/src/grammar/mod.rs b/src/grammar/mod.rs
new file mode 100644
index 000000000..b558da477
--- /dev/null
+++ b/src/grammar/mod.rs
@@ -0,0 +1,141 @@
1//! This is the actual "grammar" of the Rust language.
2//!
3//! Each function in this module and its children corresponds
4//! to a production of the format 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)`.
8//!
9//! See docs for `Parser` to learn about API, available to the grammar,
10//! and see docs for `Event` to learn how this actually manages to
11//! produce parse trees.
12//!
13//! Code in this module also contains inline tests, which start with
14//! `// test name-of-the-test` comment and look like this:
15//!
16//! ```
17//! // test fn_item_with_zero_parameters
18//! // fn foo() {}
19//! ```
20//!
21//! After adding a new inline-test, run `cargo collect-tests` to extract
22//! it as a standalone text-fixture into `tests/data/parser/inline`, and
23//! run `cargo test` once to create the "gold" value.
24mod attributes;
25mod expressions;
26mod items;
27mod params;
28mod paths;
29mod patterns;
30mod type_args;
31mod type_params;
32mod types;
33
34use {
35 parser_api::{CompletedMarker, Parser, TokenSet},
36 SyntaxKind::{self, *},
37};
38
39pub(crate) fn file(p: &mut Parser) {
40 let file = p.start();
41 p.eat(SHEBANG);
42 items::mod_contents(p, false);
43 file.complete(p, FILE);
44}
45
46fn visibility(p: &mut Parser) {
47 if p.at(PUB_KW) {
48 let vis = p.start();
49 p.bump();
50 if p.at(L_PAREN) {
51 match p.nth(1) {
52 // test crate_visibility
53 // pub(crate) struct S;
54 // pub(self) struct S;
55 // pub(self) struct S;
56 // pub(self) struct S;
57 CRATE_KW | SELF_KW | SUPER_KW => {
58 p.bump();
59 p.bump();
60 p.expect(R_PAREN);
61 }
62 IN_KW => {
63 p.bump();
64 p.bump();
65 paths::use_path(p);
66 p.expect(R_PAREN);
67 }
68 _ => (),
69 }
70 }
71 vis.complete(p, VISIBILITY);
72 }
73}
74
75fn alias(p: &mut Parser) -> bool {
76 if p.at(AS_KW) {
77 let alias = p.start();
78 p.bump();
79 name(p);
80 alias.complete(p, ALIAS);
81 }
82 true //FIXME: return false if three are errors
83}
84
85fn abi(p: &mut Parser) {
86 assert!(p.at(EXTERN_KW));
87 let abi = p.start();
88 p.bump();
89 match p.current() {
90 STRING | RAW_STRING => p.bump(),
91 _ => (),
92 }
93 abi.complete(p, ABI);
94}
95
96fn fn_ret_type(p: &mut Parser) -> bool {
97 if p.at(THIN_ARROW) {
98 p.bump();
99 types::type_(p);
100 true
101 } else {
102 false
103 }
104}
105
106fn name(p: &mut Parser) {
107 if p.at(IDENT) {
108 let m = p.start();
109 p.bump();
110 m.complete(p, NAME);
111 } else {
112 p.error("expected a name");
113 }
114}
115
116fn name_ref(p: &mut Parser) {
117 if p.at(IDENT) {
118 let m = p.start();
119 p.bump();
120 m.complete(p, NAME_REF);
121 } else {
122 p.error("expected identifier");
123 }
124}
125
126fn error_block(p: &mut Parser, message: &str) {
127 assert!(p.at(L_CURLY));
128 let err = p.start();
129 p.error(message);
130 p.bump();
131 let mut level: u32 = 1;
132 while level > 0 && !p.at(EOF) {
133 match p.current() {
134 L_CURLY => level += 1,
135 R_CURLY => level -= 1,
136 _ => (),
137 }
138 p.bump();
139 }
140 err.complete(p, ERROR);
141}