| 25 | // because it logs using the logging framework in `prqlc`. |
| 26 | |
| 27 | pub fn parse_lr_to_pr(source_id: u16, lr: Vec<lr::Token>) -> (Option<Vec<pr::Stmt>>, Vec<Error>) { |
| 28 | // Filter out comments - we don't want them in the AST |
| 29 | let semantic_tokens: Vec<_> = lr |
| 30 | .into_iter() |
| 31 | .filter(|token| { |
| 32 | !matches!( |
| 33 | token.kind, |
| 34 | lr::TokenKind::Comment(_) | lr::TokenKind::LineWrap(_) |
| 35 | ) |
| 36 | }) |
| 37 | .collect(); |
| 38 | |
| 39 | // Use built-in Input impl for &[Token], then map_span to convert token indices to byte spans |
| 40 | let input = semantic_tokens |
| 41 | .as_slice() |
| 42 | .map_span(|simple_span: SimpleSpan| { |
| 43 | let start_idx = simple_span.start(); |
| 44 | let end_idx = simple_span.end(); |
| 45 | |
| 46 | // Convert token indices to byte offsets in the source file |
| 47 | let start = semantic_tokens |
| 48 | .get(start_idx) |
| 49 | .map(|t| t.span.start) |
| 50 | .unwrap_or(0); |
| 51 | let end = semantic_tokens |
| 52 | .get(end_idx.saturating_sub(1)) |
| 53 | .map(|t| t.span.end) |
| 54 | .unwrap_or(start); |
| 55 | |
| 56 | Span { |
| 57 | start, |
| 58 | end, |
| 59 | source_id, |
| 60 | } |
| 61 | }); |
| 62 | |
| 63 | let parse_result = stmt::source().parse(input); |
| 64 | let (pr, parse_errors) = parse_result.into_output_errors(); |
| 65 | |
| 66 | let errors = parse_errors.into_iter().map(|e| e.into()).collect(); |
| 67 | log::debug!("parse errors: {errors:?}"); |
| 68 | |
| 69 | (pr, errors) |
| 70 | } |
| 71 | |
| 72 | fn ident_part<'a, I>() -> impl Parser<'a, I, String, ParserError<'a>> + Clone |
| 73 | where |