[lexer] Let states handle their own creation in from_char
This commit is contained in:
parent
eabc8f98e8
commit
176686b3a7
2 changed files with 18 additions and 22 deletions
|
@ -6,7 +6,7 @@ use chars::Lexable;
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use states::{State, StateResult};
|
use states::{State, StateResult};
|
||||||
use states::bool::Bool;
|
use states::bool::Bool;
|
||||||
use states::number::Prefix;
|
use states::number::{Builder, Prefix};
|
||||||
use token::Token;
|
use token::Token;
|
||||||
|
|
||||||
trait HashLexable {
|
trait HashLexable {
|
||||||
|
@ -28,7 +28,7 @@ impl State for Hash {
|
||||||
StateResult::advance(Box::new(Bool::new(buf.as_str())))
|
StateResult::advance(Box::new(Bool::new(buf.as_str())))
|
||||||
},
|
},
|
||||||
c if c.is_radix() || c.is_exactness() => {
|
c if c.is_radix() || c.is_exactness() => {
|
||||||
if let Some(st) = Prefix::with_char(c) {
|
if let Some(st) = Prefix::with_char(Builder::new(), c) {
|
||||||
StateResult::advance(Box::new(st))
|
StateResult::advance(Box::new(st))
|
||||||
} else {
|
} else {
|
||||||
StateResult::fail(Error::new(format!("invalid numeric prefix character: {}", c)))
|
StateResult::fail(Error::new(format!("invalid numeric prefix character: {}", c)))
|
||||||
|
|
|
@ -17,16 +17,24 @@ impl Prefix {
|
||||||
Prefix(b)
|
Prefix(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_char(c: char) -> Option<Prefix> {
|
pub fn with_char(b: Builder, c: char) -> Option<Prefix> {
|
||||||
let mut builder = Builder::new();
|
|
||||||
if let Some(ex) = Exact::from(c) {
|
if let Some(ex) = Exact::from(c) {
|
||||||
builder.push_exact(ex);
|
if b.seen_exact() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let mut b = b.clone();
|
||||||
|
b.push_exact(ex);
|
||||||
|
Some(Prefix::new(b))
|
||||||
} else if let Some(rx) = Radix::from(c) {
|
} else if let Some(rx) = Radix::from(c) {
|
||||||
builder.push_radix(rx);
|
if b.seen_radix() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let mut b = b.clone();
|
||||||
|
b.push_radix(rx);
|
||||||
|
Some(Prefix::new(b))
|
||||||
} else {
|
} else {
|
||||||
return None;
|
None
|
||||||
}
|
}
|
||||||
Some(Prefix::new(builder))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,20 +56,8 @@ impl State for Prefix {
|
||||||
|
|
||||||
impl State for Hash {
|
impl State for Hash {
|
||||||
fn lex(&mut self, c: char) -> StateResult {
|
fn lex(&mut self, c: char) -> StateResult {
|
||||||
if let Some(ex) = Exact::from(c) {
|
if let Some(st) = Prefix::with_char(self.0, c) {
|
||||||
if !self.0.seen_exact() {
|
StateResult::advance(Box::new(st))
|
||||||
self.0.push_exact(ex);
|
|
||||||
StateResult::advance(Box::new(Prefix::new(self.0)))
|
|
||||||
} else {
|
|
||||||
StateResult::fail(Error::invalid_char(c))
|
|
||||||
}
|
|
||||||
} else if let Some(rx) = Radix::from(c) {
|
|
||||||
if !self.0.seen_radix() {
|
|
||||||
self.0.push_radix(rx);
|
|
||||||
StateResult::advance(Box::new(Prefix::new(self.0)))
|
|
||||||
} else {
|
|
||||||
StateResult::fail(Error::invalid_char(c))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
StateResult::fail(Error::invalid_char(c))
|
StateResult::fail(Error::invalid_char(c))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue