mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-25 18:49:50 -04:00
FIX: Better error reporting.
This commit is contained in:
parent
7f47dc3f38
commit
c22d397545
@ -63,6 +63,12 @@ impl Position {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a Position> for Position {
|
||||||
|
fn from(source: &'a Position) -> Self {
|
||||||
|
source.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Defines the types of tokens in UCG syntax.
|
/// Defines the types of tokens in UCG syntax.
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
|
#[derive(Debug, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
|
||||||
pub enum TokenType {
|
pub enum TokenType {
|
||||||
@ -121,31 +127,31 @@ macro_rules! value_node {
|
|||||||
#[allow(unused_macros)]
|
#[allow(unused_macros)]
|
||||||
macro_rules! make_tok {
|
macro_rules! make_tok {
|
||||||
(EOF => $i:expr) => {
|
(EOF => $i:expr) => {
|
||||||
Token::new("", TokenType::END, $i)
|
Token::new("", TokenType::END, &$i)
|
||||||
};
|
};
|
||||||
|
|
||||||
(WS => $i:expr) => {
|
(WS => $i:expr) => {
|
||||||
Token::new("", TokenType::WS, $i)
|
Token::new("", TokenType::WS, &$i)
|
||||||
};
|
};
|
||||||
|
|
||||||
(CMT => $e:expr, $i:expr) => {
|
(CMT => $e:expr, $i:expr) => {
|
||||||
Token::new($e, TokenType::COMMENT, $i)
|
Token::new($e, TokenType::COMMENT, &$i)
|
||||||
};
|
};
|
||||||
|
|
||||||
(QUOT => $e:expr, $i:expr) => {
|
(QUOT => $e:expr, $i:expr) => {
|
||||||
Token::new($e, TokenType::QUOTED, $i)
|
Token::new($e, TokenType::QUOTED, &$i)
|
||||||
};
|
};
|
||||||
|
|
||||||
(PUNCT => $e:expr, $i:expr) => {
|
(PUNCT => $e:expr, $i:expr) => {
|
||||||
Token::new($e, TokenType::PUNCT, $i)
|
Token::new($e, TokenType::PUNCT, &$i)
|
||||||
};
|
};
|
||||||
|
|
||||||
(DIGIT => $e:expr, $i:expr) => {
|
(DIGIT => $e:expr, $i:expr) => {
|
||||||
Token::new($e, TokenType::DIGIT, $i)
|
Token::new($e, TokenType::DIGIT, &$i)
|
||||||
};
|
};
|
||||||
|
|
||||||
($e:expr, $i:expr) => {
|
($e:expr, $i:expr) => {
|
||||||
Token::new($e, TokenType::BAREWORD, $i)
|
Token::new($e, TokenType::BAREWORD, &$i)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,6 +249,7 @@ impl<'a> Builder<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn eval_span(&mut self, input: OffsetStrIter) -> Result<Rc<Val>, Box<Error>> {
|
fn eval_span(&mut self, input: OffsetStrIter) -> Result<Rc<Val>, Box<Error>> {
|
||||||
|
// TODO(jwall): This should really return a better error.
|
||||||
match parse(input) {
|
match parse(input) {
|
||||||
Ok(stmts) => {
|
Ok(stmts) => {
|
||||||
//panic!("Successfully parsed {}", input);
|
//panic!("Successfully parsed {}", input);
|
||||||
@ -261,14 +262,13 @@ impl<'a> Builder<'a> {
|
|||||||
Some(val) => Ok(val),
|
Some(val) => Ok(val),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// FIXME(jwall): We need to return a error::Error so we have position information.
|
Err(err) => Err(Box::new(error::Error::new_with_cause(
|
||||||
Err(err) => Err(Box::new(error::Error::new_with_boxed_cause(
|
|
||||||
format!(
|
format!(
|
||||||
"Error while parsing file: {}",
|
"Error while parsing file: {}",
|
||||||
self.curr_file.unwrap_or("<eval>")
|
self.curr_file.unwrap_or("<eval>")
|
||||||
),
|
),
|
||||||
error::ErrorType::ParseError,
|
error::ErrorType::ParseError,
|
||||||
Box::new(err),
|
err,
|
||||||
))),
|
))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -998,7 +998,7 @@ impl<'a> Builder<'a> {
|
|||||||
expr_as_stmt.push_str(expr);
|
expr_as_stmt.push_str(expr);
|
||||||
expr_as_stmt.push_str(";");
|
expr_as_stmt.push_str(";");
|
||||||
let assert_input =
|
let assert_input =
|
||||||
OffsetStrIter::new_with_offsets(&expr_as_stmt, 0, tok.pos.line - 1, tok.pos.column - 1);
|
OffsetStrIter::new_with_offsets(&expr_as_stmt, tok.pos.line - 1, tok.pos.column - 1);
|
||||||
let ok = match self.eval_span(assert_input) {
|
let ok = match self.eval_span(assert_input) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -79,15 +79,17 @@ impl Error {
|
|||||||
msg: S,
|
msg: S,
|
||||||
t: ErrorType,
|
t: ErrorType,
|
||||||
cause: Box<error::Error>,
|
cause: Box<error::Error>,
|
||||||
|
pos: Position,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// TODO(jwall): This should take a real position instead of this fake one.
|
// FIXME(jwall): This should take a real position instead of this fake one.
|
||||||
let mut e = Self::new(msg, t, Position::new(0, 0, 0));
|
let mut e = Self::new(msg, t, pos);
|
||||||
e.cause = Some(cause);
|
e.cause = Some(cause);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_cause<S: Into<String>>(msg: S, t: ErrorType, cause: Self) -> Self {
|
pub fn new_with_cause<S: Into<String>>(msg: S, t: ErrorType, cause: Self) -> Self {
|
||||||
Self::new_with_boxed_cause(msg, t, Box::new(cause))
|
let pos = cause.pos.clone();
|
||||||
|
Self::new_with_boxed_cause(msg, t, Box::new(cause), pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&self, w: &mut fmt::Formatter) -> fmt::Result {
|
fn render(&self, w: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
38
src/iter.rs
38
src/iter.rs
@ -1,33 +1,28 @@
|
|||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
use std::iter::Iterator;
|
use std::iter::Iterator;
|
||||||
|
|
||||||
use abortable_parser::iter::StrIter;
|
use abortable_parser::iter::{SliceIter, StrIter};
|
||||||
use abortable_parser::{
|
use abortable_parser::{
|
||||||
InputIter, Offsetable, Peekable, Seekable, Span, SpanRange, TextPositionTracker,
|
InputIter, Offsetable, Peekable, Seekable, Span, SpanRange, TextPositionTracker,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use ast::{Position, Token};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct OffsetStrIter<'a> {
|
pub struct OffsetStrIter<'a> {
|
||||||
contained: StrIter<'a>,
|
contained: StrIter<'a>,
|
||||||
idx_offset: usize,
|
|
||||||
line_offset: usize,
|
line_offset: usize,
|
||||||
col_offset: usize,
|
col_offset: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> OffsetStrIter<'a> {
|
impl<'a> OffsetStrIter<'a> {
|
||||||
pub fn new(input: &'a str) -> Self {
|
pub fn new(input: &'a str) -> Self {
|
||||||
Self::new_with_offsets(input, 0, 0, 0)
|
Self::new_with_offsets(input, 0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_offsets(
|
pub fn new_with_offsets(input: &'a str, line_offset: usize, col_offset: usize) -> Self {
|
||||||
input: &'a str,
|
|
||||||
idx_offset: usize,
|
|
||||||
line_offset: usize,
|
|
||||||
col_offset: usize,
|
|
||||||
) -> Self {
|
|
||||||
OffsetStrIter {
|
OffsetStrIter {
|
||||||
contained: StrIter::new(input),
|
contained: StrIter::new(input),
|
||||||
idx_offset: idx_offset,
|
|
||||||
line_offset: line_offset,
|
line_offset: line_offset,
|
||||||
col_offset: col_offset,
|
col_offset: col_offset,
|
||||||
}
|
}
|
||||||
@ -44,7 +39,7 @@ impl<'a> Iterator for OffsetStrIter<'a> {
|
|||||||
|
|
||||||
impl<'a> Offsetable for OffsetStrIter<'a> {
|
impl<'a> Offsetable for OffsetStrIter<'a> {
|
||||||
fn get_offset(&self) -> usize {
|
fn get_offset(&self) -> usize {
|
||||||
self.contained.get_offset() + self.idx_offset
|
self.contained.get_offset()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +47,6 @@ impl<'a> Clone for OffsetStrIter<'a> {
|
|||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
OffsetStrIter {
|
OffsetStrIter {
|
||||||
contained: self.contained.clone(),
|
contained: self.contained.clone(),
|
||||||
idx_offset: self.idx_offset,
|
|
||||||
line_offset: self.line_offset,
|
line_offset: self.line_offset,
|
||||||
col_offset: self.col_offset,
|
col_offset: self.col_offset,
|
||||||
}
|
}
|
||||||
@ -63,7 +57,6 @@ impl<'a> From<&'a str> for OffsetStrIter<'a> {
|
|||||||
fn from(source: &'a str) -> Self {
|
fn from(source: &'a str) -> Self {
|
||||||
OffsetStrIter {
|
OffsetStrIter {
|
||||||
contained: StrIter::new(source),
|
contained: StrIter::new(source),
|
||||||
idx_offset: 0,
|
|
||||||
line_offset: 0,
|
line_offset: 0,
|
||||||
col_offset: 0,
|
col_offset: 0,
|
||||||
}
|
}
|
||||||
@ -72,9 +65,7 @@ impl<'a> From<&'a str> for OffsetStrIter<'a> {
|
|||||||
|
|
||||||
impl<'a> Seekable for OffsetStrIter<'a> {
|
impl<'a> Seekable for OffsetStrIter<'a> {
|
||||||
fn seek(&mut self, to: usize) -> usize {
|
fn seek(&mut self, to: usize) -> usize {
|
||||||
let contained_offset = self.contained.seek(to);
|
self.contained.seek(to)
|
||||||
self.idx_offset += contained_offset;
|
|
||||||
contained_offset
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,3 +92,18 @@ impl<'a> TextPositionTracker for OffsetStrIter<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> InputIter for OffsetStrIter<'a> {}
|
impl<'a> InputIter for OffsetStrIter<'a> {}
|
||||||
|
|
||||||
|
impl<'a> From<&'a SliceIter<'a, Token>> for Position {
|
||||||
|
fn from(source: &'a SliceIter<'a, Token>) -> Self {
|
||||||
|
match source.peek_next() {
|
||||||
|
Some(t) => t.pos.clone(),
|
||||||
|
None => Position::new(0, 0, 0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a OffsetStrIter<'a>> for Position {
|
||||||
|
fn from(s: &'a OffsetStrIter<'a>) -> Position {
|
||||||
|
Position::new(s.line(), s.column(), s.get_offset())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -24,6 +24,7 @@ use abortable_parser::{Error, Peekable, Result};
|
|||||||
|
|
||||||
use self::precedence::op_expression;
|
use self::precedence::op_expression;
|
||||||
use ast::*;
|
use ast::*;
|
||||||
|
use error;
|
||||||
use iter::OffsetStrIter;
|
use iter::OffsetStrIter;
|
||||||
use tokenizer::*;
|
use tokenizer::*;
|
||||||
|
|
||||||
@ -890,8 +891,8 @@ fn statement(i: SliceIter<Token>) -> Result<SliceIter<Token>, Statement> {
|
|||||||
}
|
}
|
||||||
//trace_macros!(false);
|
//trace_macros!(false);
|
||||||
|
|
||||||
/// Parses a LocatedSpan into a list of Statements or an `abortable_parser::Error`.
|
/// Parses a LocatedSpan into a list of Statements or an `error::Error`.
|
||||||
pub fn parse(input: OffsetStrIter) -> std::result::Result<Vec<Statement>, Error> {
|
pub fn parse(input: OffsetStrIter) -> std::result::Result<Vec<Statement>, error::Error> {
|
||||||
match tokenize(input.clone()) {
|
match tokenize(input.clone()) {
|
||||||
Ok(tokenized) => {
|
Ok(tokenized) => {
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
@ -903,16 +904,35 @@ pub fn parse(input: OffsetStrIter) -> std::result::Result<Vec<Statement>, Error>
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// FIXME(jwall): We need to return a error::Error so we have position information.
|
|
||||||
match statement(i.clone()) {
|
match statement(i.clone()) {
|
||||||
Result::Abort(e) => {
|
Result::Abort(e) => {
|
||||||
return Err(e);
|
let pos: Position = (&i).into();
|
||||||
|
let err = error::Error::new_with_boxed_cause(
|
||||||
|
"Statement Parse Error",
|
||||||
|
error::ErrorType::ParseError,
|
||||||
|
Box::new(e),
|
||||||
|
pos,
|
||||||
|
);
|
||||||
|
return Err(err);
|
||||||
}
|
}
|
||||||
Result::Fail(e) => {
|
Result::Fail(e) => {
|
||||||
return Err(Error::caused_by("Statement Parse error", &i, Box::new(e)));
|
let pos: Position = (&i).into();
|
||||||
|
let err = error::Error::new_with_boxed_cause(
|
||||||
|
"Statement Parse Error",
|
||||||
|
error::ErrorType::ParseError,
|
||||||
|
Box::new(e),
|
||||||
|
pos,
|
||||||
|
);
|
||||||
|
return Err(err);
|
||||||
}
|
}
|
||||||
Result::Incomplete(ei) => {
|
Result::Incomplete(_ei) => {
|
||||||
return Err(Error::new("Unexpected end of parsing input: {:?}", &ei));
|
let pos: Position = (&i).into();
|
||||||
|
let err = error::Error::new(
|
||||||
|
"Unexpected end of parse input",
|
||||||
|
error::ErrorType::IncompleteParsing,
|
||||||
|
pos,
|
||||||
|
);
|
||||||
|
return Err(err);
|
||||||
}
|
}
|
||||||
Result::Complete(rest, stmt) => {
|
Result::Complete(rest, stmt) => {
|
||||||
out.push(stmt);
|
out.push(stmt);
|
||||||
@ -926,7 +946,12 @@ pub fn parse(input: OffsetStrIter) -> std::result::Result<Vec<Statement>, Error>
|
|||||||
return Ok(out);
|
return Ok(out);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err(Error::caused_by("Tokenization Error", &input, Box::new(e)));
|
let err = error::Error::new_with_cause(
|
||||||
|
"Tokenization Error",
|
||||||
|
error::ErrorType::UnexpectedToken,
|
||||||
|
e,
|
||||||
|
);
|
||||||
|
return Err(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,17 +17,12 @@ use std;
|
|||||||
|
|
||||||
use abortable_parser::combinators::*;
|
use abortable_parser::combinators::*;
|
||||||
use abortable_parser::iter::SliceIter;
|
use abortable_parser::iter::SliceIter;
|
||||||
use abortable_parser::{Error, Offsetable, Result, TextPositionTracker};
|
use abortable_parser::{Error, Offsetable, Result};
|
||||||
|
|
||||||
use ast::*;
|
use ast::*;
|
||||||
|
use error;
|
||||||
use iter::OffsetStrIter;
|
use iter::OffsetStrIter;
|
||||||
|
|
||||||
impl<'a> From<OffsetStrIter<'a>> for Position {
|
|
||||||
fn from(s: OffsetStrIter<'a>) -> Position {
|
|
||||||
Position::new(s.line(), s.column(), s.get_offset())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_symbol_char<'a>(i: OffsetStrIter<'a>) -> Result<OffsetStrIter<'a>, u8> {
|
fn is_symbol_char<'a>(i: OffsetStrIter<'a>) -> Result<OffsetStrIter<'a>, u8> {
|
||||||
let mut _i = i.clone();
|
let mut _i = i.clone();
|
||||||
let c = match _i.next() {
|
let c = match _i.next() {
|
||||||
@ -75,7 +70,7 @@ make_fn!(strtok<OffsetStrIter, Token>,
|
|||||||
frag => escapequoted,
|
frag => escapequoted,
|
||||||
(Token{
|
(Token{
|
||||||
typ: TokenType::QUOTED,
|
typ: TokenType::QUOTED,
|
||||||
pos: Position::from(span),
|
pos: Position::from(&span),
|
||||||
fragment: frag.to_string(),
|
fragment: frag.to_string(),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@ -89,7 +84,7 @@ make_fn!(pipequotetok<OffsetStrIter, Token>,
|
|||||||
_ => text_token!("|"),
|
_ => text_token!("|"),
|
||||||
(Token{
|
(Token{
|
||||||
typ: TokenType::PIPEQUOTE,
|
typ: TokenType::PIPEQUOTE,
|
||||||
pos: Position::from(p),
|
pos: Position::from(&p),
|
||||||
fragment: frag.to_string(),
|
fragment: frag.to_string(),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@ -102,7 +97,7 @@ make_fn!(barewordtok<OffsetStrIter, Token>,
|
|||||||
frag => consume_all!(is_symbol_char),
|
frag => consume_all!(is_symbol_char),
|
||||||
(Token{
|
(Token{
|
||||||
typ: TokenType::BAREWORD,
|
typ: TokenType::BAREWORD,
|
||||||
pos: Position::from(span),
|
pos: Position::from(&span),
|
||||||
fragment: frag.to_string(),
|
fragment: frag.to_string(),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@ -115,7 +110,7 @@ make_fn!(digittok<OffsetStrIter, Token>,
|
|||||||
digits => consume_all!(ascii_digit),
|
digits => consume_all!(ascii_digit),
|
||||||
(Token{
|
(Token{
|
||||||
typ: TokenType::DIGIT,
|
typ: TokenType::DIGIT,
|
||||||
pos: Position::from(span),
|
pos: Position::from(&span),
|
||||||
fragment: digits.to_string(),
|
fragment: digits.to_string(),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@ -130,7 +125,7 @@ make_fn!(booleantok<OffsetStrIter, Token>,
|
|||||||
),
|
),
|
||||||
(Token{
|
(Token{
|
||||||
typ: TokenType::BOOLEAN,
|
typ: TokenType::BOOLEAN,
|
||||||
pos: Position::from(span),
|
pos: Position::from(&span),
|
||||||
fragment: token.to_string(),
|
fragment: token.to_string(),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@ -141,27 +136,27 @@ make_fn!(booleantok<OffsetStrIter, Token>,
|
|||||||
macro_rules! do_text_token_tok {
|
macro_rules! do_text_token_tok {
|
||||||
($i:expr, $type:expr, $text_token:expr, WS) => {
|
($i:expr, $type:expr, $text_token:expr, WS) => {
|
||||||
do_each!($i,
|
do_each!($i,
|
||||||
span => input!(),
|
span => input!(),
|
||||||
frag => text_token!($text_token),
|
frag => text_token!($text_token),
|
||||||
_ => either!(whitespace, comment),
|
_ => either!(whitespace, comment),
|
||||||
(Token {
|
(Token {
|
||||||
typ: $type,
|
typ: $type,
|
||||||
pos: Position::from(span),
|
pos: Position::from(&span),
|
||||||
fragment: frag.to_string(),
|
fragment: frag.to_string(),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
($i:expr, $type:expr, $text_token:expr) => {
|
($i:expr, $type:expr, $text_token:expr) => {
|
||||||
do_each!($i,
|
do_each!($i,
|
||||||
span => input!(),
|
span => input!(),
|
||||||
frag => text_token!($text_token),
|
frag => text_token!($text_token),
|
||||||
(Token {
|
(Token {
|
||||||
typ: $type,
|
typ: $type,
|
||||||
pos: Position::from(span),
|
pos: Position::from(&span),
|
||||||
fragment: frag.to_string(),
|
fragment: frag.to_string(),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,7 +321,7 @@ make_fn!(whitespace<OffsetStrIter, Token>,
|
|||||||
_ => repeat!(ascii_ws),
|
_ => repeat!(ascii_ws),
|
||||||
(Token{
|
(Token{
|
||||||
typ: TokenType::WS,
|
typ: TokenType::WS,
|
||||||
pos: Position::from(span),
|
pos: Position::from(&span),
|
||||||
fragment: String::new(),
|
fragment: String::new(),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@ -338,7 +333,7 @@ make_fn!(end_of_input<OffsetStrIter, Token>,
|
|||||||
_ => eoi,
|
_ => eoi,
|
||||||
(Token{
|
(Token{
|
||||||
typ: TokenType::END,
|
typ: TokenType::END,
|
||||||
pos: Position::from(span),
|
pos: Position::from(&span),
|
||||||
fragment: String::new(),
|
fragment: String::new(),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@ -389,31 +384,38 @@ make_fn!(token<OffsetStrIter, Token>,
|
|||||||
);
|
);
|
||||||
|
|
||||||
/// Consumes an input OffsetStrIter and returns either a Vec<Token> or a error::Error.
|
/// Consumes an input OffsetStrIter and returns either a Vec<Token> or a error::Error.
|
||||||
pub fn tokenize(input: OffsetStrIter) -> std::result::Result<Vec<Token>, Error> {
|
pub fn tokenize(input: OffsetStrIter) -> std::result::Result<Vec<Token>, error::Error> {
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
let mut i = input.clone();
|
let mut i = input.clone();
|
||||||
loop {
|
loop {
|
||||||
if let Result::Complete(_, _) = eoi(i.clone()) {
|
if let Result::Complete(_, _) = eoi(i.clone()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
let pos: Position = Position::from(&i);
|
||||||
// FIXME(jwall): We need to return a error::Error so we have position information.
|
// FIXME(jwall): We need to return a error::Error so we have position information.
|
||||||
match token(i.clone()) {
|
match token(i.clone()) {
|
||||||
Result::Abort(e) => {
|
Result::Abort(e) => {
|
||||||
return Err(Error::caused_by(
|
return Err(error::Error::new_with_boxed_cause(
|
||||||
"Invalid Token encountered",
|
"Invalid Token encountered",
|
||||||
&i,
|
error::ErrorType::UnexpectedToken,
|
||||||
Box::new(e),
|
Box::new(e),
|
||||||
));
|
pos,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
Result::Fail(e) => {
|
Result::Fail(e) => {
|
||||||
return Err(Error::caused_by(
|
return Err(error::Error::new_with_boxed_cause(
|
||||||
"Invalid Token encountered",
|
"Invalid Token encountered",
|
||||||
&i,
|
error::ErrorType::UnexpectedToken,
|
||||||
Box::new(e),
|
Box::new(e),
|
||||||
));
|
pos,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
Result::Incomplete(offset) => {
|
Result::Incomplete(_offset) => {
|
||||||
return Err(Error::new("Unexepcted end of Input", &offset));
|
return Err(error::Error::new(
|
||||||
|
"Invalid Token encountered",
|
||||||
|
error::ErrorType::IncompleteParsing,
|
||||||
|
pos,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
Result::Complete(rest, tok) => {
|
Result::Complete(rest, tok) => {
|
||||||
i = rest;
|
i = rest;
|
||||||
@ -429,7 +431,7 @@ pub fn tokenize(input: OffsetStrIter) -> std::result::Result<Vec<Token>, Error>
|
|||||||
out.push(Token {
|
out.push(Token {
|
||||||
fragment: String::new(),
|
fragment: String::new(),
|
||||||
typ: TokenType::END,
|
typ: TokenType::END,
|
||||||
pos: i.into(),
|
pos: Position::from(&i),
|
||||||
});
|
});
|
||||||
Ok(out)
|
Ok(out)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user