aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/parsing.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/parsing.rs')
-rw-r--r--crates/ra_syntax/src/parsing.rs67
1 files changed, 60 insertions, 7 deletions
diff --git a/crates/ra_syntax/src/parsing.rs b/crates/ra_syntax/src/parsing.rs
index 761accd7b..138d1394a 100644
--- a/crates/ra_syntax/src/parsing.rs
+++ b/crates/ra_syntax/src/parsing.rs
@@ -2,24 +2,77 @@
2mod token_set; 2mod token_set;
3mod builder; 3mod builder;
4mod lexer; 4mod lexer;
5mod parser_impl; 5mod event;
6mod parser_api; 6mod input;
7mod parser;
7mod grammar; 8mod grammar;
8mod reparsing; 9mod reparsing;
9 10
10use crate::{ 11use crate::{
11 SyntaxError, 12 SyntaxKind, SmolStr, SyntaxError,
12 parsing::builder::GreenBuilder, 13 parsing::{
14 builder::GreenBuilder,
15 input::ParserInput,
16 event::EventProcessor,
17 parser::Parser,
18 },
13 syntax_node::GreenNode, 19 syntax_node::GreenNode,
14}; 20};
15 21
16pub use self::lexer::{tokenize, Token}; 22pub use self::lexer::{tokenize, Token};
17 23
24#[derive(Debug, Clone, PartialEq, Eq, Hash)]
25pub struct ParseError(pub String);
26
18pub(crate) use self::reparsing::incremental_reparse; 27pub(crate) use self::reparsing::incremental_reparse;
19 28
20pub(crate) fn parse_text(text: &str) -> (GreenNode, Vec<SyntaxError>) { 29pub(crate) fn parse_text(text: &str) -> (GreenNode, Vec<SyntaxError>) {
21 let tokens = tokenize(&text); 30 let tokens = tokenize(&text);
22 let (green, errors) = 31 parse_with(GreenBuilder::default(), text, &tokens, grammar::root)
23 parser_impl::parse_with(GreenBuilder::new(), text, &tokens, grammar::root); 32}
24 (green, errors) 33
34fn parse_with<S: TreeSink>(
35 tree_sink: S,
36 text: &str,
37 tokens: &[Token],
38 f: fn(&mut Parser),
39) -> S::Tree {
40 let mut events = {
41 let input = ParserInput::new(text, &tokens);
42 let mut p = Parser::new(&input);
43 f(&mut p);
44 p.finish()
45 };
46 EventProcessor::new(tree_sink, text, tokens, &mut events).process().finish()
47}
48
49/// `TreeSink` abstracts details of a particular syntax tree implementation.
50trait TreeSink {
51 type Tree;
52
53 /// Adds new leaf to the current branch.
54 fn leaf(&mut self, kind: SyntaxKind, text: SmolStr);
55
56 /// Start new branch and make it current.
57 fn start_branch(&mut self, kind: SyntaxKind);
58
59 /// Finish current branch and restore previous
60 /// branch as current.
61 fn finish_branch(&mut self);
62
63 fn error(&mut self, error: ParseError);
64
65 /// Complete tree building. Make sure that
66 /// `start_branch` and `finish_branch` calls
67 /// are paired!
68 fn finish(self) -> Self::Tree;
69}
70
71/// `TokenSource` abstracts the source of the tokens parser operates one.
72///
73/// Hopefully this will allow us to treat text and token trees in the same way!
74trait TokenSource {
75 fn token_kind(&self, pos: usize) -> SyntaxKind;
76 fn is_token_joint_to_next(&self, pos: usize) -> bool;
77 fn is_keyword(&self, pos: usize, kw: &str) -> bool;
25} 78}