aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/lib.rs
diff options
context:
space:
mode:
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..fbbac4c69
--- /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
58pub fn reparse(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink, reparser: Reparser) {
59 let Reparser(r) = reparser;
60 let mut p = parser::Parser::new(token_source);
61 r(&mut p);
62 let events = p.finish();
63 event::process(tree_sink, events);
64}