1
+ mod common;
2
+ mod data;
3
+ mod dml;
4
+
5
+ pub use common:: source;
6
+
1
7
use std:: cmp:: min;
2
8
3
9
use pg_lexer:: { SyntaxKind , Token , TokenType , WHITESPACE_TOKENS } ;
@@ -52,7 +58,7 @@ impl Parser {
52
58
. iter ( )
53
59
. map ( |( start, end) | {
54
60
let from = self . tokens . get ( * start) ;
55
- let to = self . tokens . get ( end - 1 ) ;
61
+ let to = self . tokens . get ( * end) ;
56
62
// get text range from token range
57
63
let text_start = from. unwrap ( ) . span . start ( ) ;
58
64
let text_end = to. unwrap ( ) . span . end ( ) ;
@@ -64,13 +70,17 @@ impl Parser {
64
70
}
65
71
}
66
72
67
- /// Start statement at last non-whitespace token
73
+ /// Start statement at next non-whitespace token
68
74
pub fn start_stmt ( & mut self ) {
69
75
assert ! ( self . current_stmt_start. is_none( ) ) ;
70
76
71
77
if let Some ( whitespace_token_buffer) = self . whitespace_token_buffer {
72
78
self . current_stmt_start = Some ( whitespace_token_buffer) ;
73
79
} else {
80
+ while self . nth ( 0 , false ) . token_type == TokenType :: Whitespace {
81
+ self . advance ( false ) ;
82
+ }
83
+
74
84
self . current_stmt_start = Some ( self . pos ) ;
75
85
}
76
86
}
@@ -79,6 +89,13 @@ impl Parser {
79
89
pub fn close_stmt ( & mut self ) {
80
90
assert ! ( self . current_stmt_start. is_some( ) ) ;
81
91
92
+ println ! (
93
+ "Closing statement {:?} / {:?}: {:?}" ,
94
+ self . whitespace_token_buffer,
95
+ self . pos,
96
+ self . tokens. get( self . pos)
97
+ ) ;
98
+
82
99
self . ranges . push ( (
83
100
self . current_stmt_start . unwrap ( ) ,
84
101
self . whitespace_token_buffer . unwrap_or ( self . pos ) ,
@@ -88,71 +105,66 @@ impl Parser {
88
105
}
89
106
90
107
/// applies token and advances
91
- pub fn advance ( & mut self ) {
92
- assert ! ( !self . eof( ) ) ;
108
+ ///
109
+ /// if `ignore_whitespace` is true, it will advance the next non-whitespace token
110
+ pub fn advance ( & mut self , ignore_whitespace : bool ) {
111
+ assert ! ( !self . eof( ignore_whitespace) ) ;
112
+
113
+ loop {
114
+ let whitespace = match self . nth ( 0 , false ) . kind {
115
+ SyntaxKind :: Whitespace => {
116
+ if self . whitespace_token_buffer . is_none ( ) {
117
+ self . whitespace_token_buffer = Some ( self . pos ) ;
118
+ }
93
119
94
- if self . nth ( 0 ) . kind == SyntaxKind :: Whitespace {
95
- if self . whitespace_token_buffer . is_none ( ) {
96
- self . whitespace_token_buffer = Some ( self . pos ) ;
120
+ true
121
+ }
122
+ _ => {
123
+ self . whitespace_token_buffer = None ;
124
+
125
+ false
126
+ }
127
+ } ;
128
+
129
+ self . pos += 1 ;
130
+
131
+ if !whitespace || !ignore_whitespace {
132
+ break ;
97
133
}
98
- } else {
99
- self . flush_token_buffer ( ) ;
100
134
}
101
- self . pos += 1 ;
102
135
}
103
136
104
137
/// checks if the current token is of `kind` and advances if true
105
138
/// returns true if the current token is of `kind`
106
- pub fn eat ( & mut self , kind : SyntaxKind ) -> bool {
107
- if self . nth ( 0 ) . kind == kind {
108
- self . advance ( ) ;
139
+ pub fn eat ( & mut self , kind : SyntaxKind , ignore_whitespace : bool ) -> bool {
140
+ if self . nth ( 1 , ignore_whitespace) . kind == kind {
141
+ println ! ( "Eating {:?}" , kind) ;
142
+ self . advance ( ignore_whitespace) ;
109
143
true
110
144
} else {
111
145
false
112
146
}
113
147
}
114
148
115
149
pub fn at_whitespace ( & self ) -> bool {
116
- self . nth ( 0 ) . kind == SyntaxKind :: Whitespace
150
+ self . nth ( 0 , false ) . kind == SyntaxKind :: Whitespace
117
151
}
118
152
119
- pub fn peek ( & self ) -> & Token {
120
- self . nth ( 1 )
153
+ pub fn peek ( & self , ignore_whitespace : bool ) -> & Token {
154
+ self . nth ( 1 , ignore_whitespace )
121
155
}
122
156
123
- pub fn expect ( & mut self , kind : SyntaxKind ) {
124
- if self . nth ( 0 ) . kind == kind {
157
+ pub fn expect ( & mut self , kind : SyntaxKind , ignore_whitespace : bool ) {
158
+ println ! ( "Expecting {:?}" , kind) ;
159
+ if self . eat ( kind, ignore_whitespace) {
125
160
return ;
126
161
}
127
162
128
163
self . error_at ( format ! ( "Expected {:#?}" , kind) ) ;
129
164
}
130
165
131
- pub fn eof ( & self ) -> bool {
132
- self . pos == self . tokens . len ( )
133
- }
134
-
135
- /// flush token buffer and applies all tokens
136
- fn flush_token_buffer ( & mut self ) {
137
- if self . whitespace_token_buffer . is_none ( ) {
138
- return ;
139
- }
140
- while self . whitespace_token_buffer . unwrap ( ) < self . pos {
141
- self . whitespace_token_buffer = Some ( self . whitespace_token_buffer . unwrap ( ) + 1 ) ;
142
- }
143
- self . whitespace_token_buffer = None ;
144
- }
145
-
146
- pub fn next ( & mut self ) -> & Token {
147
- loop {
148
- if self . at_whitespace ( ) {
149
- self . advance ( ) ;
150
- continue ;
151
- }
152
- break ;
153
- }
154
-
155
- self . nth ( 0 )
166
+ pub fn eof ( & self , ignore_whitespace : bool ) -> bool {
167
+ self . peek ( ignore_whitespace) . kind == SyntaxKind :: Eof
156
168
}
157
169
158
170
/// collects an SyntaxError with an `error` message at the current position
@@ -171,11 +183,33 @@ impl Parser {
171
183
}
172
184
173
185
/// lookahead method.
174
- fn nth ( & self , lookahead : usize ) -> & Token {
175
- match self . tokens . get ( self . pos + lookahead) {
176
- Some ( token) => token,
177
- None => & self . eof_token ,
186
+ ///
187
+ /// if `ignore_whitespace` is true, it will skip all whitespace tokens
188
+ pub fn nth ( & self , lookahead : usize , ignore_whitespace : bool ) -> & Token {
189
+ if ignore_whitespace {
190
+ let mut idx = 0 ;
191
+ let mut non_whitespace_token_ctr = 0 ;
192
+ loop {
193
+ match self . tokens . get ( self . pos + idx) {
194
+ Some ( token) => {
195
+ if !WHITESPACE_TOKENS . contains ( & token. kind ) {
196
+ if non_whitespace_token_ctr == lookahead {
197
+ return token;
198
+ }
199
+ non_whitespace_token_ctr += 1 ;
200
+ }
201
+ idx += 1 ;
202
+ }
203
+ None => {
204
+ return & self . eof_token ;
205
+ }
206
+ }
207
+ }
208
+ } else {
209
+ match self . tokens . get ( self . pos + lookahead) {
210
+ Some ( token) => token,
211
+ None => & self . eof_token ,
212
+ }
178
213
}
179
214
}
180
215
}
181
-
0 commit comments