Lex hashes and booleans
This commit is contained in:
parent
e9b0eab38a
commit
43054b3f49
4 changed files with 30 additions and 3 deletions
|
@ -10,6 +10,8 @@ pub trait Lexable {
|
||||||
fn is_identifier_initial(&self) -> bool;
|
fn is_identifier_initial(&self) -> bool;
|
||||||
fn is_identifier_subsequent(&self) -> bool;
|
fn is_identifier_subsequent(&self) -> bool;
|
||||||
fn is_identifier_single(&self) -> bool;
|
fn is_identifier_single(&self) -> bool;
|
||||||
|
fn is_hash(&self) -> bool;
|
||||||
|
fn is_boolean(&self) -> bool;
|
||||||
fn is_newline(&self) -> bool;
|
fn is_newline(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +36,14 @@ impl Lexable for char {
|
||||||
charset::identifier_singles().contains(&self)
|
charset::identifier_singles().contains(&self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_hash(&self) -> bool {
|
||||||
|
*self == '#'
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_boolean(&self) -> bool {
|
||||||
|
*self == 't' || *self == 'f'
|
||||||
|
}
|
||||||
|
|
||||||
fn is_newline(&self) -> bool {
|
fn is_newline(&self) -> bool {
|
||||||
*self == '\n'
|
*self == '\n'
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ use self::token::Kind;
|
||||||
enum State {
|
enum State {
|
||||||
Initial,
|
Initial,
|
||||||
Identifier,
|
Identifier,
|
||||||
|
Hash,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Lexer {
|
pub struct Lexer {
|
||||||
|
@ -72,13 +73,13 @@ impl Lexer {
|
||||||
impl Lexer {
|
impl Lexer {
|
||||||
/// Handle self.state == State::Initial
|
/// Handle self.state == State::Initial
|
||||||
fn state_initial(&mut self, c: char, token: &mut Option<Token>) {
|
fn state_initial(&mut self, c: char, token: &mut Option<Token>) {
|
||||||
println!("Initial! c='{}'", c);
|
|
||||||
if c.is_left_paren() {
|
if c.is_left_paren() {
|
||||||
*token = Some(Token::new(Kind::LeftParen, c.to_string()));
|
*token = Some(Token::new(Kind::LeftParen, c.to_string()));
|
||||||
}
|
}
|
||||||
else if c.is_right_paren() {
|
else if c.is_right_paren() {
|
||||||
*token = Some(Token::new(Kind::RightParen, c.to_string()));
|
*token = Some(Token::new(Kind::RightParen, c.to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if c.is_identifier_single() {
|
else if c.is_identifier_single() {
|
||||||
*token = Some(Token::new(Kind::Identifier, c.to_string()));
|
*token = Some(Token::new(Kind::Identifier, c.to_string()));
|
||||||
}
|
}
|
||||||
|
@ -86,6 +87,12 @@ impl Lexer {
|
||||||
self.state = State::Identifier;
|
self.state = State::Identifier;
|
||||||
self.advance();
|
self.advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if c.is_hash() {
|
||||||
|
self.state = State::Hash;
|
||||||
|
self.advance();
|
||||||
|
}
|
||||||
|
|
||||||
else if c.is_whitespace() {
|
else if c.is_whitespace() {
|
||||||
if c.is_newline() {
|
if c.is_newline() {
|
||||||
self.line += 1;
|
self.line += 1;
|
||||||
|
@ -96,7 +103,6 @@ impl Lexer {
|
||||||
|
|
||||||
/// Handle self.state == State::Identifier
|
/// Handle self.state == State::Identifier
|
||||||
fn state_identifier(&mut self, c: char, token: &mut Option<Token>) {
|
fn state_identifier(&mut self, c: char, token: &mut Option<Token>) {
|
||||||
println!("Identifier! c='{}'", c);
|
|
||||||
if c.is_identifier_subsequent() {
|
if c.is_identifier_subsequent() {
|
||||||
// State in Identifier state.
|
// State in Identifier state.
|
||||||
self.advance();
|
self.advance();
|
||||||
|
@ -106,6 +112,13 @@ impl Lexer {
|
||||||
self.retract();
|
self.retract();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn state_hash(&mut self, c: char, token: &mut Option<Token>) {
|
||||||
|
if c.is_boolean() {
|
||||||
|
self.advance();
|
||||||
|
*token = Some(Token::new(Kind::Boolean, self.value()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for Lexer {
|
impl Iterator for Lexer {
|
||||||
|
@ -120,9 +133,11 @@ impl Iterator for Lexer {
|
||||||
println!("Lexing '{}'", &self.input[self.begin ..]);
|
println!("Lexing '{}'", &self.input[self.begin ..]);
|
||||||
while token.is_none() {
|
while token.is_none() {
|
||||||
if let Some(c) = self.input.char_at(self.forward) {
|
if let Some(c) = self.input.char_at(self.forward) {
|
||||||
|
println!("{}! c='{}'", self.state, c);
|
||||||
match self.state {
|
match self.state {
|
||||||
State::Initial => self.state_initial(c, &mut token),
|
State::Initial => self.state_initial(c, &mut token),
|
||||||
State::Identifier => self.state_identifier(c, &mut token),
|
State::Identifier => self.state_identifier(c, &mut token),
|
||||||
|
State::Hash => self.state_hash(c, &mut token),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -6,6 +6,7 @@ pub enum Kind {
|
||||||
LeftParen,
|
LeftParen,
|
||||||
RightParen,
|
RightParen,
|
||||||
Identifier,
|
Identifier,
|
||||||
|
Boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Token {
|
pub struct Token {
|
||||||
|
@ -29,6 +30,7 @@ impl fmt::Display for Kind {
|
||||||
Kind::LeftParen => "LeftParen",
|
Kind::LeftParen => "LeftParen",
|
||||||
Kind::RightParen => "RightParen",
|
Kind::RightParen => "RightParen",
|
||||||
Kind::Identifier => "Identifier",
|
Kind::Identifier => "Identifier",
|
||||||
|
Kind::Boolean => "Boolean",
|
||||||
};
|
};
|
||||||
write!(f, "{}", s)
|
write!(f, "{}", s)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
mod lexer;
|
mod lexer;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let lexer = lexer::Lexer::new(String::from("((abc def + ghi))"));
|
let lexer = lexer::Lexer::new(String::from("((abc def + ghi #f))"));
|
||||||
for t in lexer {
|
for t in lexer {
|
||||||
println!("token = {}", t);
|
println!("token = {}", t);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue