Skip to main content

mical_cli_parser/
lib.rs

1use std::borrow::Cow;
2
3use mical_cli_syntax::{GreenNode, SyntaxError, SyntaxKind, token::TokenStream};
4use rowan::{GreenNodeBuilder, TextRange};
5
6mod event;
7mod grammar;
8mod parser;
9mod token_set;
10
11use event::Event;
12use parser::Parser;
13
14pub fn parse<'s>(token_stream: impl TokenStream<'s>) -> (GreenNode, Vec<SyntaxError>) {
15    let source = token_stream.source();
16    let events = {
17        let mut parser = Parser::new(token_stream);
18        grammar::source_file(&mut parser);
19        parser.finish()
20    };
21    let mut builder = NodeBuilder::new(source);
22    // let mut forward_parents = Vec::new();
23    // for i in 0..events.len() {
24    //     match events.take(i) {
25    //         Event::StartNode { kind, forward_parent } => {
26    //             if forward_parent.is_none() {
27    //                 builder.start_node(kind);
28    //                 continue;
29    //             }
30    //             forward_parents.push(kind);
31    //             let mut idx = i;
32    //             let mut fp = forward_parent;
33    //             while let Some(fpi) = fp {
34    //                 idx += fpi.get() as usize;
35    //                 fp = match events.take(idx) {
36    //                     Event::StartNode { kind, forward_parent } => {
37    //                         forward_parents.push(kind);
38    //                         forward_parent
39    //                     }
40    //                     _ => unreachable!(),
41    //                 };
42    //             }
43    //             for kind in forward_parents.drain(..).rev() {
44    //                 builder.start_node(kind);
45    //             }
46    //         }
47    //         Event::FinishNode => builder.finish_node(),
48    //         Event::Token { kind, len } => builder.token(kind, len),
49    //         Event::Error { message } => builder.error(message),
50    //     }
51    // }
52    // let mut builder = GreenNodeBuilder::new();
53    // let mut errors = Vec::new();
54    // let mut offset = 0;
55    for event in events {
56        match event {
57            Event::StartNode { kind } => builder.start_node(kind),
58            Event::FinishNode => builder.finish_node(),
59            Event::Token { kind, len } => builder.token(kind, len),
60            Event::Error { message } => builder.error(message),
61        }
62    }
63    builder.finish()
64}
65
66struct NodeBuilder<'s> {
67    source: &'s str,
68    builder: GreenNodeBuilder<'s>,
69    errors: Vec<SyntaxError>,
70    offset: u32,
71}
72
73impl<'s> NodeBuilder<'s> {
74    fn new(source: &'s str) -> Self {
75        NodeBuilder { source, builder: GreenNodeBuilder::new(), errors: Vec::new(), offset: 0 }
76    }
77
78    fn start_node(&mut self, kind: SyntaxKind) {
79        self.builder.start_node(kind.into());
80    }
81
82    fn finish_node(&mut self) {
83        self.builder.finish_node();
84    }
85
86    fn token(&mut self, kind: SyntaxKind, len: u32) {
87        let text = &self.source[(self.offset as usize)..(self.offset + len) as usize];
88        self.builder.token(kind.into(), text);
89        self.offset += len;
90    }
91
92    fn error(&mut self, message: impl Into<Cow<'static, str>>) {
93        let range = TextRange::empty(self.offset.into());
94        self.errors.push(SyntaxError::new(message, range));
95    }
96
97    fn finish(self) -> (GreenNode, Vec<SyntaxError>) {
98        (self.builder.finish(), self.errors)
99    }
100}