Skip to content

Commit c0d4900

Browse files
committed
fix: make it work
1 parent b4a2fef commit c0d4900

File tree

8 files changed

+225
-100
lines changed

8 files changed

+225
-100
lines changed

crates/parser/src/parser.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub struct Parser {
1414
curr_depth: i32,
1515
errors: Vec<SyntaxError>,
1616
stmts: Vec<RawStmt>,
17+
is_parsing_erronous_node: bool,
1718
}
1819

1920
#[derive(Debug)]
@@ -26,27 +27,33 @@ pub struct Parse {
2627
/// Main parser that controls the cst building process, and collects errors and statements
2728
impl Parser {
2829
pub fn close_until_depth(&mut self, depth: i32) {
29-
while self.curr_depth >= depth {
30-
self.inner.finish_node();
30+
while self.curr_depth >= depth && depth > 0 {
31+
self.finish_node();
3132
self.curr_depth -= 1;
3233
}
3334
}
3435

3536
/// start a new node of `SyntaxKind` at `depth`
3637
/// handles closing previous nodes if necessary
3738
/// and consumes token buffer before starting new node
38-
pub fn start_node(&mut self, kind: SyntaxKind, depth: &i32) {
39+
///
40+
/// if `SyntaxKind` is `SyntaxKind::AnyStatement`, sets `is_parsing_erronous_node` to true
41+
pub fn start_node(&mut self, kind: SyntaxKind, depth: i32) {
3942
// close until target depth
40-
self.close_until_depth(*depth);
43+
self.close_until_depth(depth);
4144

4245
self.consume_token_buffer();
4346

44-
self.curr_depth = *depth;
47+
self.curr_depth = depth;
4548
self.inner.start_node(kind);
49+
if kind == SyntaxKind::AnyStatement {
50+
self.is_parsing_erronous_node = true;
51+
}
4652
}
4753

4854
pub fn finish_node(&mut self) {
4955
self.inner.finish_node();
56+
self.is_parsing_erronous_node = false;
5057
}
5158

5259
/// Drains the token buffer and applies all tokens
@@ -58,10 +65,16 @@ impl Parser {
5865

5966
/// applies token based on its `SyntaxKindType`
6067
/// if `SyntaxKindType::Close`, closes all nodes until depth 1
61-
/// if `SyntaxKindType::Follow`, add token to buffer and wait until next node to apply token at
62-
/// same depth
68+
/// if `SyntaxKindType::Follow`, add token to buffer and wait until next node to apply token at same depth
6369
/// otherwise, applies token immediately
70+
///
71+
/// if `is_parsing_erronous_node` is true, applies token immediately
6472
pub fn token(&mut self, kind: SyntaxKind, text: &str) {
73+
if self.is_parsing_erronous_node {
74+
self.inner.token(kind, text);
75+
return;
76+
}
77+
6578
match kind.get_type() {
6679
Some(SyntaxKindType::Close) => {
6780
// move up to depth 2 and consume buffered tokens before applying closing token

crates/parser/src/source_file.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ impl Parser {
2626
pub fn parse_source_file(&mut self, text: &str) {
2727
let mut lexer = SourceFileToken::lexer(text);
2828

29-
self.start_node(SyntaxKind::SourceFile, &0);
29+
self.start_node(SyntaxKind::SourceFile, 0);
3030
while let Some(token) = lexer.next() {
3131
match token {
3232
Ok(token) => {
@@ -77,4 +77,30 @@ mod tests {
7777
assert_eq!(lex.next(), Some(Ok(SourceFileToken::Statement)));
7878
assert_eq!(lex.slice(), "select id,username from contact\n\nselect id,name\nfrom contact -- test inline comment\nwhere id = '123';");
7979
}
80+
81+
#[test]
82+
fn test_source_file_parser() {
83+
let input = "select id, name from users where id = '1224';
84+
85+
select select;
86+
87+
88+
89+
90+
91+
select 1;
92+
93+
";
94+
95+
let mut parser = Parser::default();
96+
println!("input {:?}", input);
97+
parser.parse_source_file(input);
98+
let parsed = parser.finish();
99+
100+
dbg!(parsed.errors);
101+
102+
dbg!(&parsed.cst);
103+
104+
assert_eq!(parsed.cst.text(), input);
105+
}
80106
}

crates/parser/src/statement.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ impl StatementToken {
103103

104104
impl Parser {
105105
pub fn parse_statement(&mut self, text: &str, at_offset: Option<u32>) {
106+
println!("#### parse_statement: {}", text);
106107
let offset = at_offset.unwrap_or(0);
107108
let range = TextRange::new(
108109
TextSize::from(offset),
@@ -116,6 +117,7 @@ impl Parser {
116117
Vec::new().into_iter().peekable()
117118
}
118119
};
120+
println!("pg_query_tokens: {:?}", pg_query_tokens);
119121

120122
let parsed = pg_query::parse(text);
121123
let proto;
@@ -137,14 +139,18 @@ impl Parser {
137139
Vec::new().into_iter().peekable()
138140
}
139141
};
142+
println!("pg_query_nodes: {:?}", pg_query_nodes);
140143

141144
let mut lexer = StatementToken::lexer(&text);
142145

143146
// parse root node if no syntax errors
144147
if pg_query_nodes.peek().is_some() {
145148
let (node, depth, _) = pg_query_nodes.next().unwrap();
146149
self.stmt(node.to_enum(), range);
147-
self.start_node(SyntaxKind::from_pg_query_node(&node), &depth);
150+
self.start_node(SyntaxKind::from_pg_query_node(&node), depth);
151+
} else {
152+
// fallback to generic node as root
153+
self.start_node(SyntaxKind::AnyStatement, 1);
148154
}
149155

150156
while let Some(token) = lexer.next() {
@@ -160,7 +166,7 @@ impl Parser {
160166
} else {
161167
// node is within span
162168
let (node, depth, _) = pg_query_nodes.next().unwrap();
163-
self.start_node(SyntaxKind::from_pg_query_node(&node), &depth);
169+
self.start_node(SyntaxKind::from_pg_query_node(&node), depth);
164170
}
165171
}
166172

@@ -249,6 +255,21 @@ mod tests {
249255
parser.parse_statement(input, None);
250256
let parsed = parser.finish();
251257

258+
dbg!(&parsed.cst);
259+
260+
assert_eq!(parsed.cst.text(), input);
261+
}
262+
263+
#[test]
264+
fn test_invalid_statement() {
265+
let input = "select select;";
266+
267+
let mut parser = Parser::default();
268+
parser.parse_statement(input, None);
269+
let parsed = parser.finish();
270+
271+
dbg!(&parsed.cst);
272+
252273
assert_eq!(parsed.cst.text(), input);
253274
}
254275
}

0 commit comments

Comments
 (0)