@@ -18,10 +18,7 @@ impl<'t> Lexer<'t> {
|
||||
Default::default()
|
||||
};
|
||||
|
||||
Lexer {
|
||||
text,
|
||||
pos,
|
||||
}
|
||||
Lexer { text, pos }
|
||||
}
|
||||
|
||||
/// Gets whether this lexer has reached the EOF.
|
||||
@@ -66,7 +63,8 @@ impl<'t> Lexer<'t> {
|
||||
pub fn next_token(&mut self) -> Result<Option<Token>> {
|
||||
// Constants and statics
|
||||
lazy_static! {
|
||||
static ref REGEX: Regex = RegexBuilder::new(r#"
|
||||
static ref REGEX: Regex = RegexBuilder::new(
|
||||
r#"
|
||||
^(?P<kw_return>return)
|
||||
|(?P<ident>[a-zA-Z_][a-zA-Z0-9_]*)
|
||||
|(?P<sym>:[a-zA-Z_][a-zA-Z0-9_]*)
|
||||
@@ -99,21 +97,21 @@ impl<'t> Lexer<'t> {
|
||||
|(?P<comma>,)
|
||||
|(?P<eol>;)
|
||||
|(?P<newline>\n)
|
||||
"#).ignore_whitespace(true)
|
||||
.build()
|
||||
.unwrap();
|
||||
"#
|
||||
)
|
||||
.ignore_whitespace(true)
|
||||
.build()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
const CAPTURES: &[(&str, TokenKind)] = &[
|
||||
("kw_return", TokenKind::KwReturn),
|
||||
|
||||
("ident", TokenKind::Ident),
|
||||
("sym", TokenKind::Sym),
|
||||
("dec_num", TokenKind::Num),
|
||||
("hex_num", TokenKind::Num),
|
||||
("dq_str", TokenKind::Str),
|
||||
("sq_str", TokenKind::Str),
|
||||
|
||||
("lparen", TokenKind::LParen),
|
||||
("rparen", TokenKind::RParen),
|
||||
("lbracket", TokenKind::LBracket),
|
||||
@@ -127,7 +125,6 @@ impl<'t> Lexer<'t> {
|
||||
("splat", TokenKind::Splat),
|
||||
("fslash", TokenKind::FSlash),
|
||||
("bang", TokenKind::Bang),
|
||||
|
||||
("arrow", TokenKind::Arrow),
|
||||
("eqeq", TokenKind::EqEq),
|
||||
("bangeq", TokenKind::BangEq),
|
||||
@@ -135,7 +132,6 @@ impl<'t> Lexer<'t> {
|
||||
("gteq", TokenKind::GtEq),
|
||||
("lt", TokenKind::Lt),
|
||||
("gt", TokenKind::Gt),
|
||||
|
||||
("eq", TokenKind::Eq),
|
||||
("eol", TokenKind::Eol),
|
||||
("newline", TokenKind::Newline),
|
||||
@@ -147,28 +143,30 @@ impl<'t> Lexer<'t> {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
let caps = REGEX.captures(&self.text[self.pos.byte..])
|
||||
.ok_or_else(|| Error::Unexpected {
|
||||
what: "EOF".to_string(),
|
||||
pos: self.pos,
|
||||
})?;
|
||||
let caps =
|
||||
REGEX
|
||||
.captures(&self.text[self.pos.byte..])
|
||||
.ok_or_else(|| Error::Unexpected {
|
||||
what: "EOF".to_string(),
|
||||
pos: self.pos,
|
||||
})?;
|
||||
|
||||
// Get first capture
|
||||
let capture_kind = CAPTURES.iter()
|
||||
.filter_map(|(name, kind)|
|
||||
caps.name(name)
|
||||
.map(|cap| (cap, kind)))
|
||||
let capture_kind = CAPTURES
|
||||
.iter()
|
||||
.filter_map(|(name, kind)| caps.name(name).map(|cap| (cap, kind)))
|
||||
.next();
|
||||
|
||||
let (token_text, kind) = if let Some((capture, kind)) = capture_kind {
|
||||
(capture.as_str(), *kind)
|
||||
} else {
|
||||
return Err(
|
||||
Error::Unexpected {
|
||||
what: format!("character {}", (&self.text[self.pos.byte..]).chars().next().unwrap()),
|
||||
pos: self.pos,
|
||||
}
|
||||
);
|
||||
return Err(Error::Unexpected {
|
||||
what: format!(
|
||||
"character {}",
|
||||
(&self.text[self.pos.byte..]).chars().next().unwrap()
|
||||
),
|
||||
pos: self.pos,
|
||||
});
|
||||
};
|
||||
|
||||
let start = self.pos;
|
||||
@@ -221,11 +219,16 @@ mod test {
|
||||
fn test_ident_token() {
|
||||
test_token!(
|
||||
"ident OtherIdent other_ident ident1234 RETURN",
|
||||
TokenKind::Ident, "ident",
|
||||
TokenKind::Ident, "OtherIdent",
|
||||
TokenKind::Ident, "other_ident",
|
||||
TokenKind::Ident, "ident1234",
|
||||
TokenKind::Ident, "RETURN",
|
||||
TokenKind::Ident,
|
||||
"ident",
|
||||
TokenKind::Ident,
|
||||
"OtherIdent",
|
||||
TokenKind::Ident,
|
||||
"other_ident",
|
||||
TokenKind::Ident,
|
||||
"ident1234",
|
||||
TokenKind::Ident,
|
||||
"RETURN",
|
||||
);
|
||||
}
|
||||
|
||||
@@ -261,20 +264,22 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_sym_token() {
|
||||
test_token!(":symbol :OtherSymbol :other_symbol :symbol1234",
|
||||
TokenKind::Sym, ":symbol",
|
||||
TokenKind::Sym, ":OtherSymbol",
|
||||
TokenKind::Sym, ":other_symbol",
|
||||
TokenKind::Sym, ":symbol1234",
|
||||
test_token!(
|
||||
":symbol :OtherSymbol :other_symbol :symbol1234",
|
||||
TokenKind::Sym,
|
||||
":symbol",
|
||||
TokenKind::Sym,
|
||||
":OtherSymbol",
|
||||
TokenKind::Sym,
|
||||
":other_symbol",
|
||||
TokenKind::Sym,
|
||||
":symbol1234",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eol() {
|
||||
test_token!("\n;",
|
||||
TokenKind::Newline, "\n",
|
||||
TokenKind::Eol, ";"
|
||||
);
|
||||
test_token!("\n;", TokenKind::Newline, "\n", TokenKind::Eol, ";");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user