risingwave_sqlparser/parser_v2/
mod.rsuse winnow::combinator::{separated, trace, Context};
use winnow::error::{AddContext, ContextError, StrContext};
use winnow::stream::{Stream, StreamIsPartial};
use winnow::token::any;
use winnow::{PResult, Parser, Stateful};
use crate::ast::{Ident, ObjectName};
use crate::keywords::{self, Keyword};
use crate::tokenizer::{Token, TokenWithLocation};
mod compact;
mod data_type;
mod expr;
mod impl_;
mod number;
pub(crate) use data_type::*;
pub(crate) use expr::*;
pub(crate) use number::*;
pub trait TokenStream:
Stream<Token = TokenWithLocation> + StreamIsPartial + Default + compact::ParseV1
{
}
impl<S> TokenStream for S where
S: Stream<Token = TokenWithLocation> + StreamIsPartial + Default + compact::ParseV1
{
}
fn token<S>(input: &mut S) -> PResult<TokenWithLocation>
where
S: TokenStream,
{
any(input)
}
pub fn keyword<S>(input: &mut S) -> PResult<Keyword>
where
S: TokenStream,
{
trace(
"keyword",
token.verify_map(|t| match &t.token {
Token::Word(w) if w.keyword != Keyword::NoKeyword => Some(w.keyword),
_ => None,
}),
)
.context(StrContext::Label("keyword"))
.parse_next(input)
}
impl<I> Parser<I, TokenWithLocation, ContextError> for Token
where
I: TokenStream,
{
fn parse_next(&mut self, input: &mut I) -> PResult<TokenWithLocation, ContextError> {
trace(
format_args!("token {}", self.clone()),
token.verify(move |t: &TokenWithLocation| t.token == *self),
)
.parse_next(input)
}
}
impl<I> Parser<I, Keyword, ContextError> for Keyword
where
I: TokenStream,
{
fn parse_next(&mut self, input: &mut I) -> PResult<Keyword, ContextError> {
trace(
format_args!("keyword {}", self.clone()),
token.verify_map(move |t| match &t.token {
Token::Word(w) if *self == w.keyword => Some(w.keyword),
_ => None,
}),
)
.parse_next(input)
}
}
fn identifier_non_reserved<S>(input: &mut S) -> PResult<Ident>
where
S: TokenStream,
{
token
.verify_map(|t| match &t.token {
Token::Word(w) if !keywords::RESERVED_FOR_COLUMN_OR_TABLE_NAME.contains(&w.keyword) => {
w.to_ident().ok()
}
_ => None,
})
.parse_next(input)
}
pub fn single_quoted_string<S>(input: &mut S) -> PResult<String>
where
S: TokenStream,
{
token
.verify_map(|t| match &t.token {
Token::SingleQuotedString(s) => Some(s.clone()),
_ => None,
})
.parse_next(input)
}
pub fn dollar_quoted_string<S>(input: &mut S) -> PResult<String>
where
S: TokenStream,
{
token
.verify_map(|t| match &t.token {
Token::DollarQuotedString(s) => Some(s.value.clone()),
_ => None,
})
.parse_next(input)
}
fn object_name<S>(input: &mut S) -> PResult<ObjectName>
where
S: TokenStream,
{
separated(1.., identifier_non_reserved, Token::Period)
.map(ObjectName)
.parse_next(input)
}
fn with_state<S, State, O, ParseNext>(mut parse_next: ParseNext) -> impl Parser<S, O, ContextError>
where
S: TokenStream,
State: Default,
ParseNext: Parser<Stateful<S, State>, O, ContextError>,
{
move |input: &mut S| -> PResult<O> {
let state = State::default();
let input2 = std::mem::take(input);
let mut stateful = Stateful {
input: input2,
state,
};
let output = parse_next.parse_next(&mut stateful);
*input = stateful.input;
output
}
}
pub trait ParserExt<I, O, E>: Parser<I, O, E> {
fn expect(self, expected: &'static str) -> Context<Self, I, O, E, StrContext>
where
Self: Sized,
I: Stream,
E: AddContext<I, StrContext>,
{
self.context(StrContext::Expected(
winnow::error::StrContextValue::Description(expected),
))
}
}
impl<I, O, E, T> ParserExt<I, O, E> for T where T: Parser<I, O, E> {}