aboutsummaryrefslogtreecommitdiff
path: root/src/parser
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-02-04 13:46:26 +0000
committerAleksey Kladov <[email protected]>2018-02-04 13:46:26 +0000
commit85c42fba1291f1cc41fb7bfec63117895b394fc5 (patch)
treecda942a62d244f6352dd870cf4c4e68f739909b5 /src/parser
parent852543212ba5c68b3428a80187087cc641de612c (diff)
Support contextual tokens
Diffstat (limited to 'src/parser')
-rw-r--r--src/parser/event.rs27
-rw-r--r--src/parser/grammar/items/mod.rs22
-rw-r--r--src/parser/input.rs7
-rw-r--r--src/parser/parser.rs19
4 files changed, 59 insertions, 16 deletions
diff --git a/src/parser/event.rs b/src/parser/event.rs
index fd6bdc086..64d751d63 100644
--- a/src/parser/event.rs
+++ b/src/parser/event.rs
@@ -1,4 +1,4 @@
1use {File, FileBuilder, Sink, SyntaxKind, Token}; 1use {File, FileBuilder, Sink, SyntaxKind, Token, TextUnit};
2use syntax_kinds::TOMBSTONE; 2use syntax_kinds::TOMBSTONE;
3use super::is_insignificant; 3use super::is_insignificant;
4 4
@@ -120,18 +120,25 @@ pub(super) fn to_file(text: String, tokens: &[Token], events: Vec<Event>) -> Fil
120 builder.finish_internal() 120 builder.finish_internal()
121 } 121 }
122 &Event::Token { 122 &Event::Token {
123 kind: _, 123 kind,
124 mut n_raw_tokens, 124 mut n_raw_tokens,
125 } => loop { 125 } => {
126 let token = tokens[idx]; 126 // FIXME: currently, we attach whitespace to some random node
127 if !is_insignificant(token.kind) { 127 // this should be done in a sensible manner instead
128 n_raw_tokens -= 1; 128 loop {
129 let token = tokens[idx];
130 if !is_insignificant(token.kind) {
131 break;
132 }
133 builder.leaf(token.kind, token.len);
134 idx += 1
129 } 135 }
130 idx += 1; 136 let mut len = TextUnit::new(0);
131 builder.leaf(token.kind, token.len); 137 for _ in 0..n_raw_tokens {
132 if n_raw_tokens == 0 { 138 len += tokens[idx].len;
133 break; 139 idx += 1;
134 } 140 }
141 builder.leaf(kind, len);
135 }, 142 },
136 &Event::Error { ref message } => builder.error().message(message.clone()).emit(), 143 &Event::Error { ref message } => builder.error().message(message.clone()).emit(),
137 } 144 }
diff --git a/src/parser/grammar/items/mod.rs b/src/parser/grammar/items/mod.rs
index 3612802e1..4afe2e418 100644
--- a/src/parser/grammar/items/mod.rs
+++ b/src/parser/grammar/items/mod.rs
@@ -81,7 +81,6 @@ fn item(p: &mut Parser) {
81 CONST_ITEM 81 CONST_ITEM
82 } 82 }
83 }, 83 },
84 // TODO: auto trait
85 // test unsafe_trait 84 // test unsafe_trait
86 // unsafe trait T {} 85 // unsafe trait T {}
87 UNSAFE_KW if la == TRAIT_KW => { 86 UNSAFE_KW if la == TRAIT_KW => {
@@ -89,7 +88,16 @@ fn item(p: &mut Parser) {
89 traits::trait_item(p); 88 traits::trait_item(p);
90 TRAIT_ITEM 89 TRAIT_ITEM
91 } 90 }
92 // TODO: default impl 91
92 // test unsafe_auto_trait
93 // unsafe auto trait T {}
94 UNSAFE_KW if p.at_kw(1, "auto") && p.nth(2) == TRAIT_KW => {
95 p.bump();
96 p.bump_remap(AUTO_KW);
97 traits::trait_item(p);
98 TRAIT_ITEM
99 }
100
93 // test unsafe_impl 101 // test unsafe_impl
94 // unsafe impl Foo {} 102 // unsafe impl Foo {}
95 UNSAFE_KW if la == IMPL_KW => { 103 UNSAFE_KW if la == IMPL_KW => {
@@ -97,6 +105,16 @@ fn item(p: &mut Parser) {
97 traits::impl_item(p); 105 traits::impl_item(p);
98 IMPL_ITEM 106 IMPL_ITEM
99 } 107 }
108
109 // test unsafe_default_impl
110 // unsafe default impl Foo {}
111 UNSAFE_KW if p.at_kw(1, "default") && p.nth(2) == IMPL_KW => {
112 p.bump();
113 p.bump_remap(DEFAULT_KW);
114 traits::impl_item(p);
115 IMPL_ITEM
116 }
117
100 MOD_KW => { 118 MOD_KW => {
101 mod_item(p); 119 mod_item(p);
102 MOD_ITEM 120 MOD_ITEM
diff --git a/src/parser/input.rs b/src/parser/input.rs
index 162b9ef5f..2ad621166 100644
--- a/src/parser/input.rs
+++ b/src/parser/input.rs
@@ -46,9 +46,10 @@ impl<'t> ParserInput<'t> {
46 if !(idx < self.tokens.len()) { 46 if !(idx < self.tokens.len()) {
47 return ""; 47 return "";
48 } 48 }
49 let start_offset = self.start_offsets[idx]; 49 let range = TextRange::from_len(
50 let end_offset = self.tokens[idx].len; 50 self.start_offsets[idx],
51 let range = TextRange::from_to(start_offset, end_offset); 51 self.tokens[idx].len
52 );
52 &self.text[range] 53 &self.text[range]
53 } 54 }
54} 55}
diff --git a/src/parser/parser.rs b/src/parser/parser.rs
index bb775c4a5..7e1b22ee5 100644
--- a/src/parser/parser.rs
+++ b/src/parser/parser.rs
@@ -1,6 +1,6 @@
1use super::Event; 1use super::Event;
2use super::input::{InputPosition, ParserInput}; 2use super::input::{InputPosition, ParserInput};
3use SyntaxKind::{self, EOF, TOMBSTONE}; 3use SyntaxKind::{self, EOF, TOMBSTONE, IDENT};
4 4
5pub(crate) struct Marker { 5pub(crate) struct Marker {
6 pos: u32, 6 pos: u32,
@@ -145,14 +145,31 @@ impl<'t> Parser<'t> {
145 }); 145 });
146 } 146 }
147 147
148 pub(crate) fn bump_remap(&mut self, kind: SyntaxKind) {
149 if self.current() == EOF {
150 // TODO: panic!?
151 return;
152 }
153 self.pos += 1;
154 self.event(Event::Token {
155 kind,
156 n_raw_tokens: 1,
157 });
158 }
159
148 pub(crate) fn nth(&self, n: u32) -> SyntaxKind { 160 pub(crate) fn nth(&self, n: u32) -> SyntaxKind {
149 self.inp.kind(self.pos + n) 161 self.inp.kind(self.pos + n)
150 } 162 }
151 163
164 pub(crate) fn at_kw(&self, n: u32, t: &str) -> bool {
165 self.nth(n) == IDENT && self.inp.text(self.pos + n) == t
166 }
167
152 pub(crate) fn current(&self) -> SyntaxKind { 168 pub(crate) fn current(&self) -> SyntaxKind {
153 self.nth(0) 169 self.nth(0)
154 } 170 }
155 171
172
156 fn event(&mut self, event: Event) { 173 fn event(&mut self, event: Event) {
157 self.events.push(event) 174 self.events.push(event)
158 } 175 }