Convert all the things
This commit is contained in:
parent
c3113742a3
commit
606f2853a9
1 changed files with 66 additions and 34 deletions
100
src/lexer/mod.rs
100
src/lexer/mod.rs
|
@ -20,6 +20,10 @@ use self::token::Token;
|
|||
|
||||
type StateResult = Result<Option<Token>, String>;
|
||||
|
||||
trait HasResult {
|
||||
fn has_token(&self) -> bool;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum State {
|
||||
Comment,
|
||||
|
@ -180,8 +184,9 @@ impl Lexer {
|
|||
self.advance();
|
||||
}
|
||||
else if c.is_identifier_delimiter() {
|
||||
self.token_result(Token::Identifier(self.value()));
|
||||
let value = self.value();
|
||||
self.retract();
|
||||
return self.token_result(Token::Identifier(value));
|
||||
}
|
||||
else {
|
||||
return self.generic_error(c);
|
||||
|
@ -189,6 +194,7 @@ impl Lexer {
|
|||
Ok(None)
|
||||
}
|
||||
|
||||
/// Handle self.state == State::Dot
|
||||
fn state_dot(&mut self, c: char) -> StateResult {
|
||||
if c.is_identifier_delimiter() {
|
||||
self.retract();
|
||||
|
@ -201,11 +207,12 @@ impl Lexer {
|
|||
self.advance();
|
||||
}
|
||||
else {
|
||||
self.generic_error(c);
|
||||
return self.generic_error(c);
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// Handle self.state == State::Hash
|
||||
fn state_hash(&mut self, c: char) -> StateResult {
|
||||
if c.is_boolean_true() || c.is_boolean_false() {
|
||||
self.advance();
|
||||
|
@ -226,12 +233,13 @@ impl Lexer {
|
|||
self.advance();
|
||||
}
|
||||
else {
|
||||
self.generic_error(c);
|
||||
return self.generic_error(c);
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn state_number(&mut self, c: char, token: &mut Option<Token>) {
|
||||
/// Handle self.state == State::Number
|
||||
fn state_number(&mut self, c: char) -> StateResult {
|
||||
if c.is_digit(self.number_builder.radix_value()) {
|
||||
self.number_builder.extend_value(c);
|
||||
self.advance();
|
||||
|
@ -241,15 +249,16 @@ impl Lexer {
|
|||
self.advance();
|
||||
}
|
||||
else if c.is_identifier_delimiter() {
|
||||
*token = Some(Token::Number(self.number_builder.resolve()));
|
||||
self.retract();
|
||||
return self.token_result(Token::Number(self.number_builder.resolve()));
|
||||
}
|
||||
else {
|
||||
assert!(false, "Invalid token character: '{}'", c);
|
||||
return self.generic_error(c);
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn state_number_exactness(&mut self, c: char, token: &mut Option<Token>) {
|
||||
fn state_number_exactness(&mut self, c: char) -> StateResult {
|
||||
if c.is_hash() {
|
||||
self.state = State::Hash;
|
||||
self.advance();
|
||||
|
@ -265,25 +274,27 @@ impl Lexer {
|
|||
self.advance();
|
||||
}
|
||||
else {
|
||||
assert!(false, "Invalid token character: '{}'", c);
|
||||
return self.generic_error(c);
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn state_number_decimal(&mut self, c: char, token: &mut Option<Token>) {
|
||||
fn state_number_decimal(&mut self, c: char) -> StateResult {
|
||||
if c.is_digit(Radix::Dec.value()) {
|
||||
self.number_builder.extend_decimal_value(c);
|
||||
self.advance();
|
||||
}
|
||||
else if c.is_identifier_delimiter() {
|
||||
*token = Some(Token::Number(self.number_builder.resolve()));
|
||||
self.retract();
|
||||
return self.token_result(Token::Number(self.number_builder.resolve()));
|
||||
}
|
||||
else {
|
||||
assert!(false, "Invalid token character: '{}'", c);
|
||||
return self.generic_error(c);
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn state_number_radix(&mut self, c: char, token: &mut Option<Token>) {
|
||||
fn state_number_radix(&mut self, c: char) -> StateResult {
|
||||
if c.is_digit(self.number_builder.radix_value()) {
|
||||
self.number_builder.extend_value(c);
|
||||
self.state = State::Number;
|
||||
|
@ -303,11 +314,12 @@ impl Lexer {
|
|||
self.advance();
|
||||
}
|
||||
else {
|
||||
assert!(false, "Invalid token character: '{}'", c);
|
||||
return self.generic_error(c);
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn state_number_sign(&mut self, c: char, token: &mut Option<Token>) {
|
||||
fn state_number_sign(&mut self, c: char) -> StateResult {
|
||||
if c.is_digit(self.number_builder.radix_value()) {
|
||||
self.number_builder.extend_value(c);
|
||||
self.state = State::Number;
|
||||
|
@ -318,42 +330,46 @@ impl Lexer {
|
|||
self.advance();
|
||||
}
|
||||
else {
|
||||
assert!(false, "Invalid token character: '{}'", c);
|
||||
return self.generic_error(c);
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn state_sign(&mut self, c: char, token: &mut Option<Token>) {
|
||||
fn state_sign(&mut self, c: char) -> StateResult {
|
||||
if c.is_digit(Radix::Dec.value()) {
|
||||
self.number_builder.extend_value(c);
|
||||
self.state = State::Number;
|
||||
self.advance();
|
||||
}
|
||||
else if c.is_identifier_delimiter() {
|
||||
*token = Some(Token::Identifier(self.value()));
|
||||
let value = self.value();
|
||||
self.retract();
|
||||
return self.token_result(Token::Identifier(value));
|
||||
}
|
||||
else {
|
||||
assert!(false, "Invalid token character: '{}'", c);
|
||||
return self.generic_error(c);
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn state_string(&mut self, c: char, token: &mut Option<Token>) {
|
||||
fn state_string(&mut self, c: char) -> StateResult {
|
||||
self.advance();
|
||||
if c.is_string_quote() {
|
||||
*token = Some(Token::String(self.value()));
|
||||
return self.token_result(Token::String(self.value()));
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn state_comment(&mut self, c: char, token: &mut Option<Token>) {
|
||||
fn state_comment(&mut self, c: char) -> StateResult {
|
||||
if c.is_newline() {
|
||||
self.handle_newline();
|
||||
*token = Some(Token::Comment(self.value()));
|
||||
return self.token_result(Token::Comment(self.value()));
|
||||
}
|
||||
else if c.is_eof() {
|
||||
*token = Some(Token::Comment(self.value()));
|
||||
return self.token_result(Token::Comment(self.value()));
|
||||
}
|
||||
// Consume all characters.
|
||||
self.advance();
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -374,21 +390,25 @@ impl Iterator for Lexer {
|
|||
};
|
||||
println!("{:?}! c='{}'", self.state, c);
|
||||
let previous_forward = self.forward;
|
||||
match self.state {
|
||||
let result = match self.state {
|
||||
State::Initial => self.state_initial(c),
|
||||
State::Identifier => self.state_identifier(c),
|
||||
State::Dot => self.state_dot(c),
|
||||
State::Hash => self.state_hash(c),
|
||||
State::Number => self.state_number(c, &mut token),
|
||||
State::NumberExactness => self.state_number_exactness(c, &mut token),
|
||||
State::NumberDecimal => self.state_number_decimal(c, &mut token),
|
||||
State::NumberRadix => self.state_number_radix(c, &mut token),
|
||||
State::NumberSign => self.state_number_sign(c, &mut token),
|
||||
State::Sign => self.state_sign(c, &mut token),
|
||||
State::String => self.state_string(c, &mut token),
|
||||
State::Comment => self.state_comment(c, &mut token),
|
||||
State::Number => self.state_number(c),
|
||||
State::NumberExactness => self.state_number_exactness(c),
|
||||
State::NumberDecimal => self.state_number_decimal(c),
|
||||
State::NumberRadix => self.state_number_radix(c),
|
||||
State::NumberSign => self.state_number_sign(c),
|
||||
State::Sign => self.state_sign(c),
|
||||
State::String => self.state_string(c),
|
||||
State::Comment => self.state_comment(c),
|
||||
};
|
||||
assert!(result.has_token() || self.forward != previous_forward, "No lexing progress made!");
|
||||
if result.has_token() {
|
||||
token = result.ok().unwrap();
|
||||
break;
|
||||
}
|
||||
assert!(token.is_some() || self.forward != previous_forward, "No lexing progress made!");
|
||||
}
|
||||
self.advance_begin();
|
||||
match token {
|
||||
|
@ -398,6 +418,18 @@ impl Iterator for Lexer {
|
|||
}
|
||||
}
|
||||
|
||||
impl HasResult for StateResult {
|
||||
fn has_token(&self) -> bool {
|
||||
match *self {
|
||||
Ok(ref token) => match *token {
|
||||
Some(_) => true,
|
||||
None => false,
|
||||
},
|
||||
Err(_) => false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// UNIT TESTING
|
||||
//
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue