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 10:46:17 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-02-21 10:46:17 +0000
commitd77b5857c2420666e84dcd433f254e000e2843aa (patch)
tree416e333019e349bf4ee369f2548d9e6f6a9c67e9 /crates/ra_parser/src/lib.rs
parent18b0c509f77a8e06141fee6668532cced1ebf5d8 (diff)
parent46179230a05331b1debd4dfa3bb197fa38d92347 (diff)
Merge #867
867: This moves the parser to separate crate r=matklad a=matklad That makes parser independent form both the token and the tree representation. Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_parser/src/lib.rs')
-rw-r--r--crates/ra_parser/src/lib.rs64
1 files changed, 64 insertions, 0 deletions
diff --git a/crates/ra_parser/src/lib.rs b/crates/ra_parser/src/lib.rs
new file mode 100644
index 000000000..7931b5189
--- /dev/null
+++ b/crates/ra_parser/src/lib.rs
@@ -0,0 +1,64 @@
1#[macro_use]
2mod token_set;
3mod syntax_kind;
4mod event;
5mod parser;
6mod grammar;
7
8pub(crate) use token_set::TokenSet;
9
10pub use syntax_kind::SyntaxKind;
11
12#[derive(Debug, Clone, PartialEq, Eq, Hash)]
13pub struct ParseError(pub String);
14
15/// `TreeSink` abstracts details of a particular syntax tree implementation.
16pub trait TreeSink {
17 /// Adds new leaf to the current branch.
18 fn leaf(&mut self, kind: SyntaxKind, n_tokens: u8);
19
20 /// Start new branch and make it current.
21 fn start_branch(&mut self, kind: SyntaxKind, root: bool);
22
23 /// Finish current branch and restore previous
24 /// branch as current.
25 fn finish_branch(&mut self, root: bool);
26
27 fn error(&mut self, error: ParseError);
28}
29
30/// `TokenSource` abstracts the source of the tokens parser operates one.
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) {
40 let mut p = parser::Parser::new(token_source);
41 grammar::root(&mut p);
42 let events = p.finish();
43 event::process(tree_sink, events);
44}
45
46pub struct Reparser(fn(&mut parser::Parser));
47
48impl Reparser {
49 pub fn for_node(
50 node: SyntaxKind,
51 first_child: Option<SyntaxKind>,
52 parent: Option<SyntaxKind>,
53 ) -> Option<Reparser> {
54 grammar::reparser(node, first_child, parent).map(Reparser)
55 }
56
57 pub fn parse(self, token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
58 let Reparser(r) = self;
59 let mut p = parser::Parser::new(token_source);
60 r(&mut p);
61 let events = p.finish();
62 event::process(tree_sink, events);
63 }
64}