partiql_parser/
lib.rs

1#![deny(rust_2018_idioms)]
2#![deny(clippy::all)]
3// Copyright Amazon.com, Inc. or its affiliates.
4
5//! Provides a parser for the [PartiQL][partiql] query language.
6//!
7//! # Usage
8//!
9//! ```
10//! use partiql_parser::{Parser, ParserError, ParserResult};
11//!
12//! let parser = Parser::default();
13//!
14//! let parsed = parser.parse("SELECT g FROM data GROUP BY a").expect("successful parse");
15//!
16//! let errs: ParserError = parser.parse("SELECT").expect_err("expected error");
17//!
18//! let errs_at: ParserError =
19//!     parser.parse("SELECT * FROM a AY a CROSS JOIN c AS c AT q").unwrap_err();
20//! assert_eq!(errs_at.errors[0].to_string(), "Unexpected token `<a:UNQUOTED_IDENT>` at `(b19..b20)`");
21//! ```
22//!
23//! [partiql]: https://partiql.org
24
25mod error;
26mod lexer;
27mod parse;
28mod preprocessor;
29mod token_parser;
30
31use parse::{parse_partiql, AstData, ErrorData};
32use partiql_ast::ast;
33use partiql_common::syntax::line_offset_tracker::LineOffsetTracker;
34use partiql_common::syntax::location::BytePosition;
35use partiql_common::syntax::metadata::LocationMap;
36#[cfg(feature = "serde")]
37use serde::{Deserialize, Serialize};
38
39/// [`std::error::Error`] type for errors in the lexical structure for the `PartiQL` parser.
40pub type LexicalError<'input> = error::LexError<'input>;
41
42/// [`std::error::Error`] type for errors in the syntactic structure for the `PartiQL` parser.
43pub type ParseError<'input> = error::ParseError<'input, BytePosition>;
44
45/// General [`Result`] type for the `PartiQL` [`Parser`].
46pub type ParserResult<'input> = Result<Parsed<'input>, ParserError<'input>>;
47
48/// A `PartiQL` parser from statement strings to AST.
49#[non_exhaustive]
50#[derive(Debug, Default)]
51pub struct Parser {}
52
53impl Parser {
54    /// Parse a `PartiQL` statement into an AST.
55    pub fn parse<'input>(&self, text: &'input str) -> ParserResult<'input> {
56        match parse_partiql(text) {
57            Ok(AstData {
58                ast,
59                locations,
60                offsets,
61            }) => Ok(Parsed {
62                text,
63                offsets,
64                ast,
65                locations,
66            }),
67            Err(ErrorData { errors, offsets }) => Err(ParserError {
68                text,
69                offsets,
70                errors,
71            }),
72        }
73    }
74}
75
76/// The output of parsing `PartiQL` statement strings: an AST and auxiliary data.
77#[non_exhaustive]
78#[derive(Debug)]
79#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
80#[allow(dead_code)]
81pub struct Parsed<'input> {
82    pub text: &'input str,
83    pub offsets: LineOffsetTracker,
84    pub ast: ast::AstNode<ast::TopLevelQuery>,
85    pub locations: LocationMap,
86}
87
88/// The output of errors when parsing `PartiQL` statement strings: an errors and auxiliary data.
89#[non_exhaustive]
90#[allow(dead_code)]
91#[derive(Debug)]
92#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
93pub struct ParserError<'input> {
94    pub text: &'input str,
95    pub offsets: LineOffsetTracker,
96    pub errors: Vec<ParseError<'input>>,
97}