[lexer] Replace String error messages with Error type
This commit is contained in:
parent
def35966eb
commit
dc8f5a7686
7 changed files with 33 additions and 43 deletions
|
@ -62,7 +62,7 @@ impl<T> Iterator for Lexer<T> where T: Iterator<Item=char> {
|
||||||
out = Some(Ok(Lex::new(token, &buffer, self.line, self.offset)));
|
out = Some(Ok(Lex::new(token, &buffer, self.line, self.offset)));
|
||||||
break;
|
break;
|
||||||
},
|
},
|
||||||
Err(msg) => panic!("{}", msg)
|
Err(err) => panic!("{}:{}: {}", self.line, self.offset, err.msg())
|
||||||
},
|
},
|
||||||
Some(c) => {
|
Some(c) => {
|
||||||
let result = state.lex(c);
|
let result = state.lex(c);
|
||||||
|
@ -84,8 +84,8 @@ impl<T> Iterator for Lexer<T> where T: Iterator<Item=char> {
|
||||||
out = Some(Ok(Lex::new(token, &buffer, self.line, self.offset)));
|
out = Some(Ok(Lex::new(token, &buffer, self.line, self.offset)));
|
||||||
break;
|
break;
|
||||||
},
|
},
|
||||||
StateResult::Fail { msg } => {
|
StateResult::Fail(err) => {
|
||||||
panic!("{}", msg);
|
panic!("{}:{}: {}", self.line, self.offset, err.msg());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use chars::Lexable;
|
use chars::Lexable;
|
||||||
|
use error::Error;
|
||||||
use token::Token;
|
use token::Token;
|
||||||
use states::{Resume, State, StateResult};
|
use states::{Resume, State, StateResult};
|
||||||
use states::id::IdSub;
|
use states::id::IdSub;
|
||||||
|
@ -20,14 +21,11 @@ impl State for Begin {
|
||||||
c if c.is_whitespace() => StateResult::Continue,
|
c if c.is_whitespace() => StateResult::Continue,
|
||||||
c if c.is_identifier_initial() => StateResult::Advance { to: Box::new(IdSub{}) },
|
c if c.is_identifier_initial() => StateResult::Advance { to: Box::new(IdSub{}) },
|
||||||
c if c.is_hash() => StateResult::Advance { to: Box::new(Hash::new()) },
|
c if c.is_hash() => StateResult::Advance { to: Box::new(Hash::new()) },
|
||||||
_ => {
|
_ => StateResult::fail(Error::invalid_char(c)),
|
||||||
let msg = format!("Invalid character: {}", c);
|
|
||||||
StateResult::Fail { msg }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn none(&mut self) -> Result<Option<Token>, String> {
|
fn none(&mut self) -> Result<Option<Token>, Error> {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* Eryn Wells <eryn@erynwells.me>
|
* Eryn Wells <eryn@erynwells.me>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use error::Error;
|
||||||
use chars::Lexable;
|
use chars::Lexable;
|
||||||
use states::{Resume, State, StateResult};
|
use states::{Resume, State, StateResult};
|
||||||
use token::Token;
|
use token::Token;
|
||||||
|
@ -34,10 +35,7 @@ impl State for Bool {
|
||||||
match c {
|
match c {
|
||||||
c if c.is_identifier_delimiter() => match self.handle_delimiter() {
|
c if c.is_identifier_delimiter() => match self.handle_delimiter() {
|
||||||
Some(token) => StateResult::Emit(token, Resume::Here),
|
Some(token) => StateResult::Emit(token, Resume::Here),
|
||||||
None => {
|
None => StateResult::fail(Error::invalid_char(c)),
|
||||||
let msg = format!("Invalid character: {}", c);
|
|
||||||
StateResult::fail(msg.as_str())
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
let buf = {
|
let buf = {
|
||||||
|
@ -48,20 +46,16 @@ impl State for Bool {
|
||||||
if TRUE.starts_with(&buf) || FALSE.starts_with(&buf) {
|
if TRUE.starts_with(&buf) || FALSE.starts_with(&buf) {
|
||||||
StateResult::advance(Box::new(Bool(buf)))
|
StateResult::advance(Box::new(Bool(buf)))
|
||||||
} else {
|
} else {
|
||||||
let msg = format!("Invalid character: {}", c);
|
StateResult::fail(Error::invalid_char(c))
|
||||||
StateResult::fail(msg.as_str())
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn none(&mut self) -> Result<Option<Token>, String> {
|
fn none(&mut self) -> Result<Option<Token>, Error> {
|
||||||
match self.handle_delimiter() {
|
match self.handle_delimiter() {
|
||||||
Some(token) => Ok(Some(token)),
|
Some(token) => Ok(Some(token)),
|
||||||
None => {
|
None => Err(Error::new("Found EOF while trying to parse a bool".to_string()))
|
||||||
let msg = format!("Found EOF while trying to parse a bool");
|
|
||||||
Err(msg)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use chars::Lexable;
|
use chars::Lexable;
|
||||||
|
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::Prefix;
|
||||||
|
@ -30,17 +31,14 @@ impl State for Hash {
|
||||||
if let Some(st) = Prefix::with_char(c) {
|
if let Some(st) = Prefix::with_char(c) {
|
||||||
StateResult::advance(Box::new(st))
|
StateResult::advance(Box::new(st))
|
||||||
} else {
|
} else {
|
||||||
StateResult::fail(format!("invalid numeric prefix character: {}", c).as_str())
|
StateResult::fail(Error::new(format!("invalid numeric prefix character: {}", c)))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => {
|
_ => StateResult::fail(Error::invalid_char(c)),
|
||||||
let msg = format!("Invalid character: {}", c);
|
|
||||||
StateResult::fail(msg.as_str())
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn none(&mut self) -> Result<Option<Token>, String> {
|
fn none(&mut self) -> Result<Option<Token>, Error> {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use chars::Lexable;
|
use chars::Lexable;
|
||||||
|
use error::Error;
|
||||||
use states::{Resume, State, StateResult};
|
use states::{Resume, State, StateResult};
|
||||||
use token::Token;
|
use token::Token;
|
||||||
|
|
||||||
|
@ -14,14 +15,11 @@ impl State for IdSub {
|
||||||
match c {
|
match c {
|
||||||
c if c.is_identifier_subsequent() => StateResult::Continue,
|
c if c.is_identifier_subsequent() => StateResult::Continue,
|
||||||
c if c.is_identifier_delimiter() => StateResult::Emit(Token::Id, Resume::Here),
|
c if c.is_identifier_delimiter() => StateResult::Emit(Token::Id, Resume::Here),
|
||||||
_ => {
|
_ => StateResult::fail(Error::invalid_char(c)),
|
||||||
let msg = format!("Invalid character: {}", c);
|
|
||||||
StateResult::Fail { msg }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn none(&mut self) -> Result<Option<Token>, String> {
|
fn none(&mut self) -> Result<Option<Token>, Error> {
|
||||||
Ok(Some(Token::Id))
|
Ok(Some(Token::Id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
use error::Error;
|
||||||
use token::Token;
|
use token::Token;
|
||||||
|
|
||||||
mod begin;
|
mod begin;
|
||||||
|
@ -22,7 +23,7 @@ pub enum StateResult {
|
||||||
/// Emit a Lex with the provided Token and the accumulated buffer. The Resume value indicates
|
/// Emit a Lex with the provided Token and the accumulated buffer. The Resume value indicates
|
||||||
/// whether to revisit the current input character or advance to the next one.
|
/// whether to revisit the current input character or advance to the next one.
|
||||||
Emit(Token, Resume),
|
Emit(Token, Resume),
|
||||||
Fail { msg: String }
|
Fail(Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
|
@ -35,7 +36,7 @@ pub enum Resume {
|
||||||
|
|
||||||
pub trait State: Debug {
|
pub trait State: Debug {
|
||||||
fn lex(&mut self, c: char) -> StateResult;
|
fn lex(&mut self, c: char) -> StateResult;
|
||||||
fn none(&mut self) -> Result<Option<Token>, String>;
|
fn none(&mut self) -> Result<Option<Token>, Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StateResult {
|
impl StateResult {
|
||||||
|
@ -47,7 +48,7 @@ impl StateResult {
|
||||||
StateResult::Emit(token, at)
|
StateResult::Emit(token, at)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fail(msg: &str) -> StateResult {
|
pub fn fail(err: Error) -> StateResult {
|
||||||
StateResult::Fail { msg: msg.to_string() }
|
StateResult::Fail(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
* Eryn Wells <eryn@erynwells.me>
|
* Eryn Wells <eryn@erynwells.me>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use super::{Radix, Exact};
|
use error::Error;
|
||||||
use states::{State, StateResult};
|
use states::{State, StateResult};
|
||||||
|
use states::number::{Radix, Exact};
|
||||||
use states::number::Builder;
|
use states::number::Builder;
|
||||||
use token::Token;
|
use token::Token;
|
||||||
|
|
||||||
|
@ -32,12 +33,12 @@ impl State for Prefix {
|
||||||
fn lex(&mut self, c: char) -> StateResult {
|
fn lex(&mut self, c: char) -> StateResult {
|
||||||
match c {
|
match c {
|
||||||
'#' => StateResult::advance(Box::new(Hash(self.0))),
|
'#' => StateResult::advance(Box::new(Hash(self.0))),
|
||||||
_ => StateResult::fail(format!("invalid char: {}", c).as_str())
|
_ => StateResult::fail(Error::invalid_char(c))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn none(&mut self) -> Result<Option<Token>, String> {
|
fn none(&mut self) -> Result<Option<Token>, Error> {
|
||||||
Err("blah".to_string())
|
Err(Error::new("blah".to_string()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,21 +49,21 @@ impl State for Hash {
|
||||||
self.0.push_exact(ex);
|
self.0.push_exact(ex);
|
||||||
StateResult::advance(Box::new(Prefix::new(self.0)))
|
StateResult::advance(Box::new(Prefix::new(self.0)))
|
||||||
} else {
|
} else {
|
||||||
StateResult::fail(format!("invalid char: {}", c).as_str())
|
StateResult::fail(Error::invalid_char(c))
|
||||||
}
|
}
|
||||||
} else if let Some(rx) = Radix::from(c) {
|
} else if let Some(rx) = Radix::from(c) {
|
||||||
if !self.0.seen_radix() {
|
if !self.0.seen_radix() {
|
||||||
self.0.push_radix(rx);
|
self.0.push_radix(rx);
|
||||||
StateResult::advance(Box::new(Prefix::new(self.0)))
|
StateResult::advance(Box::new(Prefix::new(self.0)))
|
||||||
} else {
|
} else {
|
||||||
StateResult::fail(format!("invalid char: {}", c).as_str())
|
StateResult::fail(Error::invalid_char(c))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
StateResult::fail(format!("invalid char: {}", c).as_str())
|
StateResult::fail(Error::invalid_char(c))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn none(&mut self) -> Result<Option<Token>, String> {
|
fn none(&mut self) -> Result<Option<Token>, Error> {
|
||||||
Err("blah".to_string())
|
Err(Error::new("blah".to_string()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue