1- use pgt_lexer:: { SyntaxKind , Token , TokenType } ;
1+ use pgt_lexer:: { SyntaxKind , Token , TokenType , WHITESPACE_TOKENS } ;
22
33use super :: {
44 Parser ,
@@ -24,6 +24,13 @@ pub fn source(p: &mut Parser) {
2424 } => {
2525 p. advance ( ) ;
2626 }
27+ Token {
28+ kind : SyntaxKind :: Ascii92 ,
29+ ..
30+ } => {
31+ println ! ( "current {:?}" , p. current( ) ) ;
32+ plpgsql_command ( p) ;
33+ }
2734 _ => {
2835 statement ( p) ;
2936 }
@@ -87,6 +94,24 @@ pub(crate) fn parenthesis(p: &mut Parser) {
8794 }
8895}
8996
97+ pub ( crate ) fn plpgsql_command ( p : & mut Parser ) {
98+ p. expect ( SyntaxKind :: Ascii92 ) ;
99+
100+ loop {
101+ match p. current ( ) . kind {
102+ SyntaxKind :: Newline => {
103+ p. advance ( ) ;
104+ break ;
105+ }
106+ _ => {
107+ // advance the parser to the next token without ignoring irrelevant tokens
108+ // we would skip a newline with `advance()`
109+ p. current_pos += 1 ;
110+ }
111+ }
112+ }
113+ }
114+
90115pub ( crate ) fn case ( p : & mut Parser ) {
91116 p. expect ( SyntaxKind :: Case ) ;
92117
@@ -125,6 +150,36 @@ pub(crate) fn unknown(p: &mut Parser, exclude: &[SyntaxKind]) {
125150 } => {
126151 case ( p) ;
127152 }
153+ Token {
154+ kind : SyntaxKind :: Ascii92 ,
155+ ..
156+ } => {
157+ // pgsql commands e.g.
158+ //
159+ // ```
160+ // \if test
161+ // ```
162+ //
163+ // we wait for "\" and check if the previous token is a newline
164+
165+ // newline is a whitespace, but we do not want to ignore it here
166+ let irrelevant = WHITESPACE_TOKENS
167+ . iter ( )
168+ . filter ( |t| * * t != SyntaxKind :: Newline )
169+ . collect :: < Vec < _ > > ( ) ;
170+
171+ // go back from the current position without ignoring irrelevant tokens
172+ if p. tokens
173+ . iter ( )
174+ . take ( p. current_pos )
175+ . rev ( )
176+ . find ( |t| !irrelevant. contains ( & & t. kind ) )
177+ . is_some_and ( |t| t. kind == SyntaxKind :: Newline )
178+ {
179+ break ;
180+ }
181+ p. advance ( ) ;
182+ }
128183 Token {
129184 kind : SyntaxKind :: Ascii40 ,
130185 ..
0 commit comments