[lexer] Add state for finding Dots at the beginning of input
This happens to be a valid token by itself and the beginning of a decimal number.
This commit is contained in:
parent
15e275513d
commit
34d612a832
6 changed files with 56 additions and 11 deletions
|
@ -3,18 +3,22 @@
|
|||
*/
|
||||
|
||||
pub trait Lexable {
|
||||
fn is_left_paren(&self) -> bool;
|
||||
fn is_right_paren(&self) -> bool;
|
||||
fn is_dot(&self) -> bool;
|
||||
fn is_exactness(&self) -> bool;
|
||||
fn is_hash(&self) -> bool;
|
||||
fn is_identifier_delimiter(&self) -> bool;
|
||||
fn is_identifier_initial(&self) -> bool;
|
||||
fn is_identifier_subsequent(&self) -> bool;
|
||||
fn is_identifier_delimiter(&self) -> bool;
|
||||
|
||||
fn is_exactness(&self) -> bool;
|
||||
fn is_left_paren(&self) -> bool;
|
||||
fn is_radix(&self) -> bool;
|
||||
fn is_hash(&self) -> bool;
|
||||
fn is_right_paren(&self) -> bool;
|
||||
}
|
||||
|
||||
impl Lexable for char {
|
||||
fn is_dot(&self) -> bool {
|
||||
*self == '.'
|
||||
}
|
||||
|
||||
fn is_exactness(&self) -> bool {
|
||||
*self == 'i' || *self == 'e'
|
||||
}
|
||||
|
|
|
@ -6,13 +6,13 @@ use chars::Lexable;
|
|||
use error::Error;
|
||||
use token::Token;
|
||||
use states::{Resume, State, StateResult};
|
||||
use states::dot::Dot;
|
||||
use states::id::IdSub;
|
||||
use states::hash::Hash;
|
||||
use states::number::{Builder, Digit};
|
||||
use states::whitespace::Whitespace;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Begin;
|
||||
#[derive(Debug)] pub struct Begin;
|
||||
|
||||
impl Begin {
|
||||
pub fn new() -> Begin {
|
||||
|
@ -28,9 +28,8 @@ impl State for Begin {
|
|||
StateResult::Emit(Token::LeftParen, Resume::AtNext)
|
||||
} else if c.is_right_paren() {
|
||||
StateResult::Emit(Token::RightParen, Resume::AtNext)
|
||||
} else if c.is_whitespace() {
|
||||
// TODO: Figure out some way to track newlines.
|
||||
StateResult::Continue
|
||||
} else if c.is_dot() {
|
||||
StateResult::advance(Box::new(Dot::new()))
|
||||
} else if c.is_identifier_initial() {
|
||||
StateResult::advance(Box::new(IdSub{}))
|
||||
} else if c.is_hash() {
|
||||
|
|
33
lexer/src/states/dot.rs
Normal file
33
lexer/src/states/dot.rs
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* lexer/src/states/dot.rs
|
||||
* Eryn Wells <eryn@erynwells.me>
|
||||
*/
|
||||
|
||||
use chars::Lexable;
|
||||
use error::Error;
|
||||
use states::{Resume, State, StateResult};
|
||||
use states::number::{Builder, Digit};
|
||||
use token::Token;
|
||||
|
||||
#[derive(Debug)] pub struct Dot;
|
||||
|
||||
impl Dot {
|
||||
pub fn new() -> Dot {
|
||||
Dot{}
|
||||
}
|
||||
}
|
||||
|
||||
impl State for Dot {
|
||||
fn lex(&mut self, c: char) -> StateResult {
|
||||
if c.is_identifier_delimiter() {
|
||||
StateResult::emit(Token::Dot, Resume::Here)
|
||||
} else if let Some(st) = Digit::with_char(&Builder::new(), c) {
|
||||
StateResult::advance(Box::new(st))
|
||||
} else {
|
||||
StateResult::fail(Error::invalid_char(c))
|
||||
}
|
||||
}
|
||||
|
||||
fn none(&mut self) -> Result<Option<Token>, Error> {
|
||||
Ok(Some(Token::Dot))
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ use token::Token;
|
|||
|
||||
mod begin;
|
||||
mod bool;
|
||||
mod dot;
|
||||
mod hash;
|
||||
mod number;
|
||||
mod id;
|
||||
|
|
|
@ -13,6 +13,7 @@ pub struct Lex {
|
|||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum Token {
|
||||
Bool(bool),
|
||||
Dot,
|
||||
Num(i64),
|
||||
LeftParen,
|
||||
RightParen,
|
||||
|
|
|
@ -88,3 +88,10 @@ fn integers_in_alternative_bases() {
|
|||
assert_eq!(lex.next(), Some(Ok(Lex::new(Token::Num(0b11001), "#b11001", 0, 5))));
|
||||
assert_eq!(lex.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dot() {
|
||||
let mut lex = Lexer::new(".".chars());
|
||||
assert_eq!(lex.next(), Some(Ok(Lex::new(Token::Dot, ".", 0, 0))));
|
||||
assert_eq!(lex.next(), None);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue