Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::iter::{Iterator, Peekable};
- use std::result;
- #[derive(Debug)]
- struct ParserError;
- #[derive(Debug)]
- struct Statement(SqlSetExpr);
- #[derive(Debug)]
- struct TableWithJoins;
- type Result<T> = result::Result<T, ParserError>; type Tokens = Box<Iterator<Item = Token>>;
- #[derive(Debug)]
- enum SqlSetExpr {
- Select,
- Query,
- Values,
- }
- // Not meant to be exhaustive, this is a toy example.
- enum Token {
- Select,
- LParen,
- RParen,
- Values,
- Wildcard,
- From,
- Keyword(String),
- }
- impl From<&str> for Token {
- fn from(s: &str) -> Token {
- match s {
- "(" => Token::LParen,
- ")" => Token::RParen,
- "*" => Token::Wildcard,
- "SELECT" => Token::Select,
- "VALUES" => Token::Values,
- "FROM" => Token::From,
- _ => Token::Keyword(s.to_string()),
- }
- }
- }
- trait Parser {
- fn parse_sql(&self, sql: Tokens) -> Result<Vec<Statement>> {
- let mut peekable = sql.peekable();
- if let Some(token) = peekable.peek() {
- match token {
- Token::Select => return Ok(vec![self.parse_query(&mut peekable)?]),
- _ => unimplemented!(),
- };
- }
- Err(ParserError)
- }
- fn parse_query(&self, sql: &mut Peekable<Tokens>) -> Result<Statement> {
- let body = self.parse_select(sql)?;
- Ok(Statement(body))
- }
- fn parse_select(&self, sql: &mut Peekable<Tokens>) -> Result<SqlSetExpr> {
- if let Some(token) = sql.peek() {
- return match token {
- Token::Select => Ok(SqlSetExpr::Select),
- Token::LParen => Ok(SqlSetExpr::Query),
- Token::Values => Ok(SqlSetExpr::Values),
- _ => panic!()
- };
- }
- Err(ParserError)
- }
- }
- struct BaseParser;
- impl Parser for BaseParser {}
- fn parse<S: Into<String>>(parser: Box<dyn Parser>, sql: S) -> Result<Vec<Statement>> {
- Ok(parser.parse_sql(tokenize(sql)?)?)
- }
- fn tokenize<S: Into<String>>(sql: S) -> Result<Tokens> {
- // THIS IS A TOY EXAMPLE.
- let tokens: Vec<Token> = sql
- .into()
- .as_str()
- .split(" ")
- .map(|s| s.into())
- .collect();
- Ok(Box::new(tokens.into_iter()))
- }
- fn main() {
- println!("{:?}", parse(Box::new(BaseParser), "SELECT * FROM BLAH"));
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement