From 41d4ea480ff27d95528c6d095e9c9c088f72eb1b Mon Sep 17 00:00:00 2001 From: Brennan Vincent Date: Mon, 5 Aug 2019 12:21:52 -0400 Subject: [PATCH] Add and use `expect_keywords` function The code for parsing chains of expected keywords is more readable with this helper function. Co-authored-by: Nikhil Benesch --- src/parser.rs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index cdc031b7..2bfb8687 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -802,6 +802,15 @@ impl Parser { } } + /// Bail out if the following tokens are not the expected sequence of + /// keywords, or consume them if they are. + pub fn expect_keywords(&mut self, expected: &[&'static str]) -> Result<(), ParserError> { + for kw in expected { + self.expect_keyword(kw)?; + } + Ok(()) + } + /// Consume the next token if it matches the expected token, otherwise return false #[must_use] pub fn consume_token(&mut self, expected: &Token) -> bool { @@ -856,8 +865,7 @@ impl Parser { self.expect_keyword("TABLE")?; let table_name = self.parse_object_name()?; let (columns, constraints) = self.parse_columns()?; - self.expect_keyword("STORED")?; - self.expect_keyword("AS")?; + self.expect_keywords(&["STORED", "AS"])?; let file_format = self.parse_identifier()?.parse::()?; self.expect_keyword("LOCATION")?; @@ -1111,8 +1119,7 @@ impl Parser { pub fn parse_copy(&mut self) -> Result { let table_name = self.parse_object_name()?; let columns = self.parse_parenthesized_column_list(Optional)?; - self.expect_keyword("FROM")?; - self.expect_keyword("STDIN")?; + self.expect_keywords(&["FROM", "STDIN"])?; self.expect_token(&Token::SemiColon)?; let values = self.parse_tsv()?; Ok(Statement::Copy { @@ -1240,16 +1247,14 @@ impl Parser { "TIMESTAMP" => { // TBD: we throw away "with/without timezone" information if self.parse_keyword("WITH") || self.parse_keyword("WITHOUT") { - self.expect_keyword("TIME")?; - self.expect_keyword("ZONE")?; + self.expect_keywords(&["TIME", "ZONE"])?; } Ok(DataType::Timestamp) } "TIME" => { // TBD: we throw away "with/without timezone" information if self.parse_keyword("WITH") || self.parse_keyword("WITHOUT") { - self.expect_keyword("TIME")?; - self.expect_keyword("ZONE")?; + self.expect_keywords(&["TIME", "ZONE"])?; } Ok(DataType::Time) }