aboutsummaryrefslogtreecommitdiff
path: root/src/parser/grammar/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser/grammar/mod.rs')
-rw-r--r--src/parser/grammar/mod.rs130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/parser/grammar/mod.rs b/src/parser/grammar/mod.rs
new file mode 100644
index 000000000..afce308d0
--- /dev/null
+++ b/src/parser/grammar/mod.rs
@@ -0,0 +1,130 @@
1use super::parser::{Parser, TokenSet};
2use SyntaxKind;
3use syntax_kinds::*;
4
5mod items;
6mod attributes;
7mod expressions;
8mod types;
9mod paths;
10mod type_params;
11
12pub(crate) fn file(p: &mut Parser) {
13 let file = p.start();
14 p.eat(SHEBANG);
15 items::mod_contents(p, false);
16 file.complete(p, FILE);
17}
18
19fn visibility(p: &mut Parser) {
20 if p.at(PUB_KW) {
21 let vis = p.start();
22 p.bump();
23 if p.at(L_PAREN) {
24 match p.nth(1) {
25 CRATE_KW | SELF_KW | SUPER_KW => {
26 p.bump();
27 p.bump();
28 p.expect(R_PAREN);
29 }
30 IN_KW => {
31 p.bump();
32 p.bump();
33 paths::use_path(p);
34 p.expect(R_PAREN);
35 }
36 _ => (),
37 }
38 }
39 vis.complete(p, VISIBILITY);
40 }
41}
42
43fn alias(p: &mut Parser) -> bool {
44 if p.at(AS_KW) {
45 let alias = p.start();
46 p.bump();
47 p.expect(IDENT);
48 alias.complete(p, ALIAS);
49 }
50 true //FIXME: return false if three are errors
51}
52
53fn error_block(p: &mut Parser, message: &str) {
54 assert!(p.at(L_CURLY));
55 let err = p.start();
56 p.error().message(message).emit();
57 p.bump();
58 let mut level: u32 = 1;
59 while level > 0 && !p.at(EOF) {
60 match p.current() {
61 L_CURLY => level += 1,
62 R_CURLY => level -= 1,
63 _ => (),
64 }
65 p.bump();
66 }
67 err.complete(p, ERROR);
68}
69
70impl<'p> Parser<'p> {
71 fn at<L: Lookahead>(&self, l: L) -> bool {
72 l.is_ahead(self)
73 }
74
75 fn err_and_bump(&mut self, message: &str) {
76 let err = self.start();
77 self.error().message(message).emit();
78 self.bump();
79 err.complete(self, ERROR);
80 }
81
82 fn expect(&mut self, kind: SyntaxKind) -> bool {
83 if self.at(kind) {
84 self.bump();
85 true
86 } else {
87 self.error().message(format!("expected {:?}", kind)).emit();
88 false
89 }
90 }
91
92 fn eat(&mut self, kind: SyntaxKind) -> bool {
93 self.current() == kind && {
94 self.bump();
95 true
96 }
97 }
98}
99
100trait Lookahead: Copy {
101 fn is_ahead(self, p: &Parser) -> bool;
102}
103
104impl Lookahead for SyntaxKind {
105 fn is_ahead(self, p: &Parser) -> bool {
106 p.current() == self
107 }
108}
109
110impl Lookahead for [SyntaxKind; 2] {
111 fn is_ahead(self, p: &Parser) -> bool {
112 p.current() == self[0] && p.nth(1) == self[1]
113 }
114}
115
116impl Lookahead for [SyntaxKind; 3] {
117 fn is_ahead(self, p: &Parser) -> bool {
118 p.current() == self[0] && p.nth(1) == self[1] && p.nth(2) == self[2]
119 }
120}
121
122#[derive(Clone, Copy)]
123struct AnyOf<'a>(&'a [SyntaxKind]);
124
125impl<'a> Lookahead for AnyOf<'a> {
126 fn is_ahead(self, p: &Parser) -> bool {
127 let curr = p.current();
128 self.0.iter().any(|&k| k == curr)
129 }
130}