aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/lib.rs
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-02-21 12:25:32 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-02-21 12:25:32 +0000
commit782cb43c148ff400818af4daed96a6841916031c (patch)
tree945fd6597aa73ec1b887f0d60b5bc9d7ac59f2cb /crates/ra_parser/src/lib.rs
parent2fa2805887e734647aabebc1f533ec76c48f538a (diff)
parent412ac63ff517c7eab5e1cfe0bf239616bd2c13a1 (diff)
Merge #870
870: docs r=matklad a=matklad Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_parser/src/lib.rs')
-rw-r--r--crates/ra_parser/src/lib.rs46
1 files changed, 35 insertions, 11 deletions
diff --git a/crates/ra_parser/src/lib.rs b/crates/ra_parser/src/lib.rs
index 7931b5189..ddc08e462 100644
--- a/crates/ra_parser/src/lib.rs
+++ b/crates/ra_parser/src/lib.rs
@@ -1,3 +1,17 @@
1//! The Rust parser.
2//!
3//! The parser doesn't know about concrete representation of tokens and syntax
4//! trees. Abstract `TokenSource` and `TreeSink` traits are used instead. As a
5//! consequence, this crates does not contain a lexer.
6//!
7//! The `Parser` struct from the `parser` module is a cursor into the sequence
8//! of tokens. Parsing routines use `Parser` to inspect current state and
9//! advance the parsing.
10//!
11//! The actual parsing happens in the `grammar` module.
12//!
13//! Tests for this crate live in `ra_syntax` crate.
14
1#[macro_use] 15#[macro_use]
2mod token_set; 16mod token_set;
3mod syntax_kind; 17mod syntax_kind;
@@ -12,30 +26,34 @@ pub use syntax_kind::SyntaxKind;
12#[derive(Debug, Clone, PartialEq, Eq, Hash)] 26#[derive(Debug, Clone, PartialEq, Eq, Hash)]
13pub struct ParseError(pub String); 27pub struct ParseError(pub String);
14 28
29/// `TokenSource` abstracts the source of the tokens parser operates one.
30///
31/// Hopefully this will allow us to treat text and token trees in the same way!
32pub trait TokenSource {
33 /// What is the current token?
34 fn token_kind(&self, pos: usize) -> SyntaxKind;
35 /// Is the current token joined to the next one (`> >` vs `>>`).
36 fn is_token_joint_to_next(&self, pos: usize) -> bool;
37 /// Is the current token a specified keyword?
38 fn is_keyword(&self, pos: usize, kw: &str) -> bool;
39}
40
15/// `TreeSink` abstracts details of a particular syntax tree implementation. 41/// `TreeSink` abstracts details of a particular syntax tree implementation.
16pub trait TreeSink { 42pub trait TreeSink {
17 /// Adds new leaf to the current branch. 43 /// Adds new leaf to the current branch.
18 fn leaf(&mut self, kind: SyntaxKind, n_tokens: u8); 44 fn leaf(&mut self, kind: SyntaxKind, n_tokens: u8);
19 45
20 /// Start new branch and make it current. 46 /// Start new branch and make it current.
21 fn start_branch(&mut self, kind: SyntaxKind, root: bool); 47 fn start_branch(&mut self, kind: SyntaxKind);
22 48
23 /// Finish current branch and restore previous 49 /// Finish current branch and restore previous
24 /// branch as current. 50 /// branch as current.
25 fn finish_branch(&mut self, root: bool); 51 fn finish_branch(&mut self);
26 52
27 fn error(&mut self, error: ParseError); 53 fn error(&mut self, error: ParseError);
28} 54}
29 55
30/// `TokenSource` abstracts the source of the tokens parser operates one. 56/// Parse given tokens into the given sink as a rust file.
31///
32/// Hopefully this will allow us to treat text and token trees in the same way!
33pub trait TokenSource {
34 fn token_kind(&self, pos: usize) -> SyntaxKind;
35 fn is_token_joint_to_next(&self, pos: usize) -> bool;
36 fn is_keyword(&self, pos: usize, kw: &str) -> bool;
37}
38
39pub fn parse(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { 57pub fn parse(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
40 let mut p = parser::Parser::new(token_source); 58 let mut p = parser::Parser::new(token_source);
41 grammar::root(&mut p); 59 grammar::root(&mut p);
@@ -43,9 +61,11 @@ pub fn parse(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
43 event::process(tree_sink, events); 61 event::process(tree_sink, events);
44} 62}
45 63
64/// A parsing function for a specific braced-block.
46pub struct Reparser(fn(&mut parser::Parser)); 65pub struct Reparser(fn(&mut parser::Parser));
47 66
48impl Reparser { 67impl Reparser {
68 /// If the node is a braced block, return the corresponding `Reparser`.
49 pub fn for_node( 69 pub fn for_node(
50 node: SyntaxKind, 70 node: SyntaxKind,
51 first_child: Option<SyntaxKind>, 71 first_child: Option<SyntaxKind>,
@@ -54,6 +74,10 @@ impl Reparser {
54 grammar::reparser(node, first_child, parent).map(Reparser) 74 grammar::reparser(node, first_child, parent).map(Reparser)
55 } 75 }
56 76
77 /// Re-parse given tokens using this `Reparser`.
78 ///
79 /// Tokens must start with `{`, end with `}` and form a valid brace
80 /// sequence.
57 pub fn parse(self, token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { 81 pub fn parse(self, token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
58 let Reparser(r) = self; 82 let Reparser(r) = self;
59 let mut p = parser::Parser::new(token_source); 83 let mut p = parser::Parser::new(token_source);