1
+ use std:: collections:: { HashMap , HashSet } ;
2
+
1
3
use cstree:: {
2
4
build:: GreenNodeBuilder , green:: GreenNode , interning:: Resolver , RawSyntaxKind , Syntax ,
3
5
} ;
@@ -56,7 +58,16 @@ impl Parser {
56
58
& mut self ,
57
59
node : & Node ,
58
60
peekable : & mut std:: iter:: Peekable < std:: vec:: IntoIter < ( SyntaxKind , usize , usize , & str ) > > ,
61
+ complement_node_or_token : & HashSet < usize > ,
59
62
) {
63
+ if cfg ! ( feature = "remove-empty-node" ) {
64
+ if node. start_byte_pos == node. end_byte_pos
65
+ && !complement_node_or_token. contains ( & node. start_byte_pos )
66
+ {
67
+ return ;
68
+ }
69
+ }
70
+
60
71
while let Some ( ( kind, start, _, text) ) = peekable. peek ( ) {
61
72
// TODO: Consider whether the presence or absence of an equals sign changes the position of comments. Determine which option is preferable
62
73
if * start >= node. start_byte_pos {
@@ -74,7 +85,7 @@ impl Parser {
74
85
self . builder . start_node ( kind) ;
75
86
node. children
76
87
. iter ( )
77
- . for_each ( |c| self . parse_rec ( c, peekable) ) ;
88
+ . for_each ( |c| self . parse_rec ( c, peekable, complement_node_or_token ) ) ;
78
89
self . builder . finish_node ( ) ;
79
90
}
80
91
}
@@ -83,13 +94,14 @@ impl Parser {
83
94
mut self ,
84
95
nodes : & Vec < & Node > ,
85
96
extras : Vec < ( SyntaxKind , usize , usize , & str ) > ,
97
+ complement_node_or_token : & HashSet < usize > ,
86
98
) -> ( GreenNode , impl Resolver ) {
87
99
let mut peekable = extras. into_iter ( ) . peekable ( ) ;
88
100
89
101
self . builder . start_node ( SyntaxKind :: Root ) ;
90
102
91
103
for node in nodes {
92
- self . parse_rec ( node, & mut peekable) ;
104
+ self . parse_rec ( node, & mut peekable, complement_node_or_token ) ;
93
105
}
94
106
95
107
while let Some ( ( kind, _, _, text) ) = peekable. peek ( ) {
@@ -177,30 +189,54 @@ fn init_tokens(tokens: &mut [Token]) {
177
189
}
178
190
179
191
#[ inline]
180
- fn is_bind_variable_comment ( s : impl AsRef < str > ) -> bool {
192
+ fn is_replacement_value_comment ( s : impl AsRef < str > ) -> bool {
181
193
let s = s. as_ref ( ) ;
182
- s. starts_with ( "/*" ) && s. ends_with ( "*/" ) && !s. contains ( '\n' )
194
+ s. starts_with ( "/*# " ) && s. ends_with ( "*/" ) && !s. contains ( '\n' )
183
195
}
184
196
185
197
#[ inline]
186
- fn is_missing_bind_variable (
198
+ fn is_missing_from_replacement_value (
199
+ stack : & [ ( u32 , Node ) ] ,
187
200
extras : & [ ( SyntaxKind , usize , usize , & str ) ] ,
188
201
action_table : & [ i16 ] ,
189
202
state : u32 ,
190
203
) -> bool {
191
204
match extras. last ( ) {
192
- Some ( ( _, _, _, s) ) => {
193
- dbg ! ( s, is_bind_variable_comment( s) ) ;
205
+ Some ( ( _, _, _, s) )
206
+ if is_replacement_value_comment ( s)
207
+ && stack. last ( ) . unwrap ( ) . 1 . component_id == SyntaxKind :: FROM as u32 =>
208
+ {
209
+ let action_index =
210
+ ( state * num_terminal_symbol ( ) ) as usize + SyntaxKind :: IDENT as usize ;
211
+
212
+ let a = action_table[ action_index] ;
213
+ a != 0x7FFF
194
214
}
195
- _ => ( ) ,
215
+ _ => false ,
196
216
}
217
+ }
218
+
219
+ #[ inline]
220
+ fn is_bind_variable_comment ( s : impl AsRef < str > ) -> bool {
221
+ let s = s. as_ref ( ) ;
222
+ s. starts_with ( "/*" )
223
+ && s. ends_with ( "*/" )
224
+ && !s. contains ( '\n' )
225
+ && !matches ! ( s. chars( ) . nth( 2 ) . unwrap( ) , '$' | '#' )
226
+ }
227
+
228
+ #[ inline]
229
+ fn is_missing_bind_variable (
230
+ extras : & [ ( SyntaxKind , usize , usize , & str ) ] ,
231
+ action_table : & [ i16 ] ,
232
+ state : u32 ,
233
+ ) -> bool {
197
234
match extras. last ( ) {
198
235
Some ( ( _, _, _, s) ) if is_bind_variable_comment ( s) => {
199
236
let action_index =
200
237
( state * num_terminal_symbol ( ) ) as usize + SyntaxKind :: SCONST as usize ;
201
238
202
239
let a = action_table[ action_index] ;
203
- dbg ! ( a) ;
204
240
a != 0x7FFF
205
241
}
206
242
_ => false ,
@@ -266,6 +302,7 @@ pub fn parse(input: &str) -> Result<ResolvedNode, ParseError> {
266
302
267
303
let mut last_pos = 0 ;
268
304
let mut extras: Vec < ( SyntaxKind , usize , usize , & str ) > = Vec :: new ( ) ;
305
+ let mut complement_node_or_token = HashSet :: new ( ) ;
269
306
270
307
loop {
271
308
let state = stack. last ( ) . unwrap ( ) . 0 ;
@@ -313,44 +350,38 @@ pub fn parse(input: &str) -> Result<ResolvedNode, ParseError> {
313
350
v if v < 0 => Action :: Reduce ( ( -v - 1 ) as usize ) ,
314
351
_ => Action :: Accept ,
315
352
} ;
316
- // dbg!(&action);
317
-
318
- dbg ! (
319
- & token. value,
320
- is_missing_bind_variable( & extras, action_table, state) ,
321
- ) ;
322
- // if action == Action::Error {
323
- // dbg!(
324
- // token.start_byte_pos,
325
- // &token.value,
326
- // is_missing_bind_variable(&extras, action_table, state),
327
- // extras.last()
328
- // );
329
- if is_missing_bind_variable ( & extras, action_table, state) {
330
- let last_extra = extras. last ( ) . unwrap ( ) ;
331
- if token. start_byte_pos != last_extra. 2 {
353
+
354
+ if Some ( token. start_byte_pos ) != extras. last ( ) . map ( |e| e. 2 ) {
355
+ if is_missing_from_replacement_value ( & stack, & extras, action_table, state) {
356
+ let last_extra = extras. last ( ) . unwrap ( ) ;
357
+ token = Token {
358
+ start_byte_pos : last_extra. 2 ,
359
+ end_byte_pos : last_extra. 2 ,
360
+ kind : TokenKind :: IDENT , // とりあえず識別子としておく
361
+ value : String :: new ( ) ,
362
+ } ;
363
+ cid = SyntaxKind :: IDENT as u32 ;
364
+ complement_node_or_token. insert ( token. start_byte_pos ) ;
365
+
366
+ action = match action_table[ ( state * num_terminal_symbol ( ) + cid) as usize ] {
367
+ 0x7FFF => Action :: Error ,
368
+ v if v > 0 => Action :: Shift ( ( v - 1 ) as usize ) ,
369
+ v if v < 0 => Action :: Reduce ( ( -v - 1 ) as usize ) ,
370
+ _ => Action :: Accept ,
371
+ } ;
372
+ insert_dummy_token = true ;
373
+ }
374
+
375
+ if is_missing_bind_variable ( & extras, action_table, state) {
376
+ let last_extra = extras. last ( ) . unwrap ( ) ;
332
377
token = Token {
333
378
start_byte_pos : last_extra. 2 ,
334
379
end_byte_pos : last_extra. 2 ,
335
380
kind : TokenKind :: SCONST , // とりあえず文字列としておく
336
381
value : String :: new ( ) ,
337
382
} ;
338
383
cid = SyntaxKind :: SCONST as u32 ;
339
-
340
- // let node = Node {
341
- // token: Some(Token {
342
- // start_byte_pos: token.start_byte_pos,
343
- // end_byte_pos: token.start_byte_pos,
344
- // kind: TokenKind::SCONST, // とりあえず文字列としておく
345
- // value: String::new(),
346
- // }),
347
- // component_id: SyntaxKind::SCONST as u32,
348
- // children: Vec::new(),
349
- // start_byte_pos: token.start_byte_pos,
350
- // end_byte_pos: token.end_byte_pos,
351
- // };
352
-
353
- // stack.push((next_state as u32, node));
384
+ complement_node_or_token. insert ( token. start_byte_pos ) ;
354
385
355
386
action = match action_table[ ( state * num_terminal_symbol ( ) + cid) as usize ] {
356
387
0x7FFF => Action :: Error ,
@@ -361,8 +392,6 @@ pub fn parse(input: &str) -> Result<ResolvedNode, ParseError> {
361
392
insert_dummy_token = true ;
362
393
}
363
394
}
364
- // dbg!(&action, &token);
365
- // }
366
395
367
396
match action {
368
397
Action :: Shift ( next_state) => {
@@ -494,7 +523,7 @@ pub fn parse(input: &str) -> Result<ResolvedNode, ParseError> {
494
523
builder : GreenNodeBuilder :: new ( ) ,
495
524
} ;
496
525
let root: Vec < & Node > = stack[ 1 ..] . iter ( ) . map ( |s| & s. 1 ) . collect ( ) ;
497
- let ( ast, resolver) = parser. parse ( & root, extras) ;
526
+ let ( ast, resolver) = parser. parse ( & root, extras, & complement_node_or_token ) ;
498
527
499
528
Ok ( SyntaxNode :: new_root_with_resolver ( ast, resolver) )
500
529
}
@@ -512,7 +541,7 @@ select
512
541
, /*fuga*/ * 1
513
542
, /*fuga*/ || 'hoge'
514
543
from
515
- tbl t
544
+ /*# tbl*/ t
516
545
where
517
546
/*val*/ = 1;
518
547
"# ;
0 commit comments