-
I'm writing a SQL parser, starting with a lexer, and am having trouble at basic keywords and identifiers.
Sorry; I'm a total newb and I've never worked with scanners or parsers before. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
Here's what I have for the keyword parser: #[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum Keyword {
Alter,
And,
...
Where,
}
pub fn keyword<'src>(
) -> impl Parser<'src, &'src str, (SimpleSpan<usize>, Keyword), extra::Err<Rich<'src, char, SimpleSpan>>>
{
any()
.filter(|c: &char| c.is_alphabetic() || *c == '_')
.then(
any()
.filter(|c: &char| c.is_alphabetic() || *c == '_' || c.is_ascii_digit())
.repeated()
.at_least(0),
)
.to_slice()
.map(|ident: &str| {
Ok((match ident.to_uppercase().as_str() {
"ALTER" => Keyword::Alter,
"AND" => Keyword::And,
...
"WHERE" => Keyword::Where,
_ => return Err(()),
},))
})
} This is failing the type checker, both in terms of the What do I do instead? |
Beta Was this translation helpful? Give feedback.
My personal view is that the simplest way to set up keyword and identifier parsing looks something like this:
This parses any C-style identifier, then checks to see whether it is a lower-case match with any of the given keywords, mapping it to the relevant keyword token if so. If not, it'll fall back to the identifier token.
If you really want other cases to fall back to an error,
try_map
can be used instead ofmap
as m…