mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
Unify Errors so better error messages can be had.
This commit is contained in:
parent
bfde2c5238
commit
01e7ee59b7
23
src/ast.rs
23
src/ast.rs
@ -24,29 +24,6 @@ use std::cmp::PartialEq;
|
||||
use std::hash::Hasher;
|
||||
use std::hash::Hash;
|
||||
|
||||
/// Encodes a parsing error with position information and a helpful description.
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct ParseError {
|
||||
pub pos: Position,
|
||||
pub description: String,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ParseError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
write!(
|
||||
f,
|
||||
"Parsing Error {} at line: {} column: {}",
|
||||
self.description, self.pos.line, self.pos.column
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for ParseError {
|
||||
fn description(&self) -> &str {
|
||||
&self.description
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! enum_type_equality {
|
||||
( $slf:ident, $r:expr, $( $l:pat ),* ) => {
|
||||
match $slf {
|
||||
|
34
src/error.rs
34
src/error.rs
@ -18,6 +18,8 @@ use std::fmt;
|
||||
|
||||
use ast::*;
|
||||
|
||||
use nom;
|
||||
|
||||
/// ErrorType defines the various types of errors that can result from compiling UCG into an
|
||||
/// output format.
|
||||
pub enum ErrorType {
|
||||
@ -32,6 +34,7 @@ pub enum ErrorType {
|
||||
// Parsing Errors
|
||||
UnexpectedToken,
|
||||
EmptyExpression,
|
||||
ParseError,
|
||||
}
|
||||
|
||||
impl fmt::Display for ErrorType {
|
||||
@ -46,6 +49,7 @@ impl fmt::Display for ErrorType {
|
||||
&ErrorType::FormatError => "FormatError",
|
||||
&ErrorType::UnexpectedToken => "UnexpectedToken",
|
||||
&ErrorType::EmptyExpression => "EmptyExpression",
|
||||
&ErrorType::ParseError => "ParseError",
|
||||
};
|
||||
w.write_str(name)
|
||||
}
|
||||
@ -56,6 +60,7 @@ pub struct Error {
|
||||
pub err_type: ErrorType,
|
||||
pub pos: Position,
|
||||
pub msg: String,
|
||||
pub cause: Option<Box<Error>>,
|
||||
_pkgonly: (),
|
||||
}
|
||||
|
||||
@ -65,16 +70,41 @@ impl Error {
|
||||
err_type: t,
|
||||
pos: pos,
|
||||
msg: msg.into(),
|
||||
cause: None,
|
||||
_pkgonly: (),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_with_cause<S: Into<String>>(
|
||||
msg: S,
|
||||
t: ErrorType,
|
||||
pos: Position,
|
||||
cause: Error,
|
||||
) -> Self {
|
||||
let mut e = Self::new(msg, t, pos);
|
||||
e.cause = Some(Box::new(cause));
|
||||
return e;
|
||||
}
|
||||
|
||||
pub fn new_with_errorkind<S: Into<String>>(
|
||||
msg: S,
|
||||
t: ErrorType,
|
||||
pos: Position,
|
||||
cause: nom::ErrorKind<Error>,
|
||||
) -> Self {
|
||||
match cause {
|
||||
nom::ErrorKind::Custom(e) => Self::new_with_cause(msg, t, pos, e),
|
||||
// TODO(jwall): We could get more creative here with our messaging.
|
||||
_ => Self::new(msg, t, pos),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Error {
|
||||
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
w,
|
||||
"{}: \"{}\" {}:{}",
|
||||
"{}: \"{}\" at line: {} column: {}",
|
||||
self.err_type, self.msg, self.pos.line, self.pos.column
|
||||
)
|
||||
}
|
||||
@ -84,7 +114,7 @@ impl fmt::Display for Error {
|
||||
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
w,
|
||||
"{}: \"{}\" {}:{}",
|
||||
"{}: \"{}\" at line: {} column: {}",
|
||||
self.err_type, self.msg, self.pos.line, self.pos.column
|
||||
)
|
||||
}
|
||||
|
199
src/parse.rs
199
src/parse.rs
@ -23,10 +23,11 @@ use nom::IResult;
|
||||
|
||||
use ast::*;
|
||||
use tokenizer::*;
|
||||
use error;
|
||||
|
||||
type NomResult<'a, O> = nom::IResult<TokenIter<'a>, O, ParseError>;
|
||||
type NomResult<'a, O> = nom::IResult<TokenIter<'a>, O, error::Error>;
|
||||
|
||||
type ParseResult<O> = Result<O, ParseError>;
|
||||
type ParseResult<O> = Result<O, error::Error>;
|
||||
|
||||
fn symbol_to_value(s: &Token) -> ParseResult<Value> {
|
||||
Ok(Value::Symbol(value_node!(
|
||||
@ -36,7 +37,7 @@ fn symbol_to_value(s: &Token) -> ParseResult<Value> {
|
||||
}
|
||||
|
||||
// symbol is a bare unquoted field.
|
||||
named!(symbol<TokenIter, Value, ParseError>,
|
||||
named!(symbol<TokenIter, Value, error::Error>,
|
||||
match_type!(BAREWORD => symbol_to_value)
|
||||
);
|
||||
|
||||
@ -48,7 +49,7 @@ fn str_to_value(s: &Token) -> ParseResult<Value> {
|
||||
}
|
||||
|
||||
// quoted_value is a quoted string.
|
||||
named!(quoted_value<TokenIter, Value, ParseError>,
|
||||
named!(quoted_value<TokenIter, Value, error::Error>,
|
||||
match_type!(STR => str_to_value)
|
||||
);
|
||||
|
||||
@ -65,10 +66,11 @@ fn triple_to_number(v: (Option<Token>, Option<Token>, Option<Token>)) -> ParseRe
|
||||
let i = match FromStr::from_str(pref) {
|
||||
Ok(i) => i,
|
||||
Err(_) => {
|
||||
return Err(ParseError {
|
||||
description: format!("Not an integer! {}", pref),
|
||||
pos: pref_pos,
|
||||
})
|
||||
return Err(error::Error::new(
|
||||
format!("Not an integer! {}", pref),
|
||||
error::ErrorType::UnexpectedToken,
|
||||
pref_pos,
|
||||
))
|
||||
}
|
||||
};
|
||||
return Ok(Value::Int(value_node!(i, pref_pos)));
|
||||
@ -88,10 +90,11 @@ fn triple_to_number(v: (Option<Token>, Option<Token>, Option<Token>)) -> ParseRe
|
||||
let f = match FromStr::from_str(&to_parse) {
|
||||
Ok(f) => f,
|
||||
Err(_) => {
|
||||
return Err(ParseError {
|
||||
description: format!("Not a float! {}", to_parse),
|
||||
pos: maybepos.unwrap(),
|
||||
})
|
||||
return Err(error::Error::new(
|
||||
format!("Not a float! {}", to_parse),
|
||||
error::ErrorType::UnexpectedToken,
|
||||
maybepos.unwrap(),
|
||||
))
|
||||
}
|
||||
};
|
||||
return Ok(Value::Float(value_node!(f, pref_pos)));
|
||||
@ -109,7 +112,7 @@ fn triple_to_number(v: (Option<Token>, Option<Token>, Option<Token>)) -> ParseRe
|
||||
// *IMPORTANT*
|
||||
// It also means this combinator is risky when used with partial
|
||||
// inputs. So handle with care.
|
||||
named!(number<TokenIter, Value, ParseError>,
|
||||
named!(number<TokenIter, Value, error::Error>,
|
||||
map_res!(alt!(
|
||||
complete!(do_parse!( // 1.0
|
||||
prefix: match_type!(DIGIT) >>
|
||||
@ -138,7 +141,7 @@ named!(number<TokenIter, Value, ParseError>,
|
||||
);
|
||||
// trace_macros!(false);
|
||||
|
||||
named!(boolean_value<TokenIter, Value, ParseError>,
|
||||
named!(boolean_value<TokenIter, Value, error::Error>,
|
||||
do_parse!(
|
||||
b: match_type!(BOOLEAN) >>
|
||||
(Value::Boolean(Positioned{
|
||||
@ -149,7 +152,7 @@ named!(boolean_value<TokenIter, Value, ParseError>,
|
||||
);
|
||||
|
||||
named!(
|
||||
field_value<TokenIter, (Token, Expression), ParseError>,
|
||||
field_value<TokenIter, (Token, Expression), error::Error>,
|
||||
do_parse!(
|
||||
field: match_type!(BAREWORD) >>
|
||||
punct!("=") >>
|
||||
@ -167,13 +170,13 @@ fn vec_to_tuple(t: (Position, Option<FieldList>)) -> ParseResult<Value> {
|
||||
)))
|
||||
}
|
||||
|
||||
named!(field_list<TokenIter, FieldList, ParseError>,
|
||||
named!(field_list<TokenIter, FieldList, error::Error>,
|
||||
separated_list!(punct!(","), field_value)
|
||||
);
|
||||
|
||||
named!(
|
||||
#[doc="Capture a tuple of named fields with values. {<field>=<value>,...}"],
|
||||
tuple<TokenIter, Value, ParseError>,
|
||||
tuple<TokenIter, Value, error::Error>,
|
||||
map_res!(
|
||||
do_parse!(
|
||||
pos: pos >>
|
||||
@ -193,7 +196,7 @@ fn tuple_to_list<Sp: Into<Position>>(t: (Sp, Vec<Expression>)) -> ParseResult<Va
|
||||
}));
|
||||
}
|
||||
|
||||
named!(list_value<TokenIter, Value, ParseError>,
|
||||
named!(list_value<TokenIter, Value, error::Error>,
|
||||
map_res!(
|
||||
do_parse!(
|
||||
start: punct!("[") >>
|
||||
@ -205,7 +208,7 @@ named!(list_value<TokenIter, Value, ParseError>,
|
||||
)
|
||||
);
|
||||
|
||||
named!(empty_value<TokenIter, Value, ParseError>,
|
||||
named!(empty_value<TokenIter, Value, error::Error>,
|
||||
do_parse!(
|
||||
pos: pos >>
|
||||
match_type!(EMPTY) >>
|
||||
@ -213,7 +216,7 @@ named!(empty_value<TokenIter, Value, ParseError>,
|
||||
)
|
||||
);
|
||||
|
||||
named!(value<TokenIter, Value, ParseError>,
|
||||
named!(value<TokenIter, Value, error::Error>,
|
||||
alt!(
|
||||
boolean_value |
|
||||
empty_value |
|
||||
@ -228,7 +231,7 @@ fn value_to_expression(v: Value) -> ParseResult<Expression> {
|
||||
Ok(Expression::Simple(v))
|
||||
}
|
||||
|
||||
named!(simple_expression<TokenIter, Expression, ParseError>,
|
||||
named!(simple_expression<TokenIter, Expression, error::Error>,
|
||||
map_res!(
|
||||
value,
|
||||
value_to_expression
|
||||
@ -266,20 +269,20 @@ macro_rules! do_binary_expr {
|
||||
}
|
||||
|
||||
// trace_macros!(true);
|
||||
named!(add_expression<TokenIter, Expression, ParseError>,
|
||||
named!(add_expression<TokenIter, Expression, error::Error>,
|
||||
do_binary_expr!(punct!("+"), BinaryExprType::Add)
|
||||
);
|
||||
// trace_macros!(false);
|
||||
|
||||
named!(sub_expression<TokenIter, Expression, ParseError>,
|
||||
named!(sub_expression<TokenIter, Expression, error::Error>,
|
||||
do_binary_expr!(punct!("-"), BinaryExprType::Sub)
|
||||
);
|
||||
|
||||
named!(mul_expression<TokenIter, Expression, ParseError>,
|
||||
named!(mul_expression<TokenIter, Expression, error::Error>,
|
||||
do_binary_expr!(punct!("*"), BinaryExprType::Mul)
|
||||
);
|
||||
|
||||
named!(div_expression<TokenIter, Expression, ParseError>,
|
||||
named!(div_expression<TokenIter, Expression, error::Error>,
|
||||
do_binary_expr!(punct!("/"), BinaryExprType::Div)
|
||||
);
|
||||
|
||||
@ -287,7 +290,7 @@ fn expression_to_grouped_expression(e: Expression) -> ParseResult<Expression> {
|
||||
Ok(Expression::Grouped(Box::new(e)))
|
||||
}
|
||||
|
||||
named!(grouped_expression<TokenIter, Expression, ParseError>,
|
||||
named!(grouped_expression<TokenIter, Expression, error::Error>,
|
||||
map_res!(
|
||||
preceded!(punct!("("), terminated!(expression, punct!(")"))),
|
||||
expression_to_grouped_expression
|
||||
@ -346,10 +349,11 @@ fn selector_list(input: TokenIter) -> NomResult<SelectorList> {
|
||||
};
|
||||
|
||||
if list.is_empty() {
|
||||
return IResult::Error(nom::ErrorKind::Custom(ParseError {
|
||||
description: "(.) with no selector fields after".to_string(),
|
||||
pos: is_dot.unwrap().pos,
|
||||
}));
|
||||
return IResult::Error(nom::ErrorKind::Custom(error::Error::new(
|
||||
"(.) with no selector fields after".to_string(),
|
||||
error::ErrorType::IncompleteParsing,
|
||||
is_dot.unwrap().pos,
|
||||
)));
|
||||
} else {
|
||||
(rest, Some(list))
|
||||
}
|
||||
@ -374,7 +378,7 @@ fn tuple_to_copy(t: (SelectorDef, FieldList)) -> ParseResult<Expression> {
|
||||
}))
|
||||
}
|
||||
|
||||
named!(copy_expression<TokenIter, Expression, ParseError>,
|
||||
named!(copy_expression<TokenIter, Expression, error::Error>,
|
||||
map_res!(
|
||||
do_parse!(
|
||||
pos: pos >>
|
||||
@ -402,16 +406,17 @@ fn tuple_to_macro(mut t: (Position, Vec<Value>, Value)) -> ParseResult<Expressio
|
||||
pos: t.0,
|
||||
})),
|
||||
// TODO(jwall): Show a better version of the unexpected parsed value.
|
||||
val => Err(ParseError {
|
||||
description: format!("Expected Tuple Got {:?}", val),
|
||||
pos: t.0,
|
||||
}),
|
||||
val => Err(error::Error::new(
|
||||
format!("Expected Tuple Got {:?}", val),
|
||||
error::ErrorType::UnexpectedToken,
|
||||
t.0,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
named!(arglist<TokenIter, Vec<Value>, ParseError>, separated_list!(punct!(","), symbol));
|
||||
named!(arglist<TokenIter, Vec<Value>, error::Error>, separated_list!(punct!(","), symbol));
|
||||
|
||||
named!(macro_expression<TokenIter, Expression, ParseError>,
|
||||
named!(macro_expression<TokenIter, Expression, error::Error>,
|
||||
map_res!(
|
||||
do_parse!(
|
||||
pos: pos >>
|
||||
@ -435,14 +440,15 @@ fn tuple_to_select(t: (Position, Expression, Expression, Value)) -> ParseResult<
|
||||
tuple: v.val,
|
||||
pos: t.0,
|
||||
})),
|
||||
val => Err(ParseError {
|
||||
description: format!("Expected Tuple Got {:?}", val),
|
||||
pos: t.0,
|
||||
}),
|
||||
val => Err(error::Error::new(
|
||||
format!("Expected Tuple Got {:?}", val),
|
||||
error::ErrorType::UnexpectedToken,
|
||||
t.0,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
named!(select_expression<TokenIter, Expression, ParseError>,
|
||||
named!(select_expression<TokenIter, Expression, error::Error>,
|
||||
map_res!(
|
||||
do_parse!(
|
||||
start: word!("select") >>
|
||||
@ -463,7 +469,7 @@ fn tuple_to_format(t: (Token, Vec<Expression>)) -> ParseResult<Expression> {
|
||||
}))
|
||||
}
|
||||
|
||||
named!(format_expression<TokenIter, Expression, ParseError>,
|
||||
named!(format_expression<TokenIter, Expression, error::Error>,
|
||||
map_res!(
|
||||
do_parse!(
|
||||
tmpl: match_type!(STR) >>
|
||||
@ -485,10 +491,11 @@ fn tuple_to_call(t: (Position, Value, Vec<Expression>)) -> ParseResult<Expressio
|
||||
pos: Position::new(t.0.line as usize, t.0.column as usize),
|
||||
}))
|
||||
} else {
|
||||
Err(ParseError {
|
||||
description: format!("Expected Selector Got {:?}", t.0),
|
||||
pos: Position::new(t.0.line as usize, t.0.column as usize),
|
||||
})
|
||||
Err(error::Error::new(
|
||||
format!("Expected Selector Got {:?}", t.0),
|
||||
error::ErrorType::UnexpectedToken,
|
||||
Position::new(t.0.line as usize, t.0.column as usize),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@ -500,7 +507,7 @@ fn vec_to_selector_value(t: (Position, SelectorList)) -> ParseResult<Value> {
|
||||
)))
|
||||
}
|
||||
|
||||
named!(selector_value<TokenIter, Value, ParseError>,
|
||||
named!(selector_value<TokenIter, Value, error::Error>,
|
||||
map_res!(
|
||||
do_parse!(
|
||||
sl: selector_list >>
|
||||
@ -510,7 +517,7 @@ named!(selector_value<TokenIter, Value, ParseError>,
|
||||
)
|
||||
);
|
||||
|
||||
named!(call_expression<TokenIter, Expression, ParseError>,
|
||||
named!(call_expression<TokenIter, Expression, error::Error>,
|
||||
map_res!(
|
||||
do_parse!(
|
||||
macroname: selector_value >>
|
||||
@ -557,13 +564,14 @@ fn tuple_to_list_op(tpl: (Position, Token, Value, Value)) -> ParseResult<Express
|
||||
} else if &tpl.1.fragment == "filter" {
|
||||
ListOpType::Filter
|
||||
} else {
|
||||
return Err(ParseError {
|
||||
description: format!(
|
||||
return Err(error::Error::new(
|
||||
format!(
|
||||
"Expected one of 'map' or 'filter' but got '{}'",
|
||||
tpl.1.fragment
|
||||
),
|
||||
pos: pos,
|
||||
});
|
||||
error::ErrorType::UnexpectedToken,
|
||||
pos,
|
||||
));
|
||||
};
|
||||
let macroname = tpl.2;
|
||||
let list = tpl.3;
|
||||
@ -572,17 +580,19 @@ fn tuple_to_list_op(tpl: (Position, Token, Value, Value)) -> ParseResult<Express
|
||||
// two sections.
|
||||
let fieldname: String = match &mut def.sel.tail {
|
||||
&mut None => {
|
||||
return Err(ParseError {
|
||||
description: format!("Missing a result field for the macro"),
|
||||
pos: pos,
|
||||
});
|
||||
return Err(error::Error::new(
|
||||
format!("Missing a result field for the macro"),
|
||||
error::ErrorType::IncompleteParsing,
|
||||
pos,
|
||||
));
|
||||
}
|
||||
&mut Some(ref mut tl) => {
|
||||
if tl.len() < 1 {
|
||||
return Err(ParseError {
|
||||
description: format!("Missing a result field for the macro"),
|
||||
pos: def.pos.clone(),
|
||||
});
|
||||
return Err(error::Error::new(
|
||||
format!("Missing a result field for the macro"),
|
||||
error::ErrorType::IncompleteParsing,
|
||||
def.pos.clone(),
|
||||
));
|
||||
}
|
||||
let fname = tl.pop();
|
||||
fname.unwrap().fragment
|
||||
@ -598,18 +608,20 @@ fn tuple_to_list_op(tpl: (Position, Token, Value, Value)) -> ParseResult<Express
|
||||
}));
|
||||
}
|
||||
// TODO(jwall): We should print a pretter message than debug formatting here.
|
||||
return Err(ParseError {
|
||||
pos: pos,
|
||||
description: format!("Expected a list but got {:?}", list),
|
||||
});
|
||||
return Err(error::Error::new(
|
||||
format!("Expected a list but got {:?}", list),
|
||||
error::ErrorType::UnexpectedToken,
|
||||
pos,
|
||||
));
|
||||
}
|
||||
return Err(ParseError {
|
||||
pos: pos,
|
||||
description: format!("Expected a macro but got {:?}", macroname),
|
||||
});
|
||||
return Err(error::Error::new(
|
||||
format!("Expected a selector but got {:?}", macroname),
|
||||
error::ErrorType::UnexpectedToken,
|
||||
pos,
|
||||
));
|
||||
}
|
||||
|
||||
named!(list_op_expression<TokenIter, Expression, ParseError>,
|
||||
named!(list_op_expression<TokenIter, Expression, error::Error>,
|
||||
map_res!(
|
||||
do_parse!(
|
||||
pos: pos >>
|
||||
@ -632,7 +644,7 @@ named!(list_op_expression<TokenIter, Expression, ParseError>,
|
||||
// *IMPORTANT*
|
||||
// It also means this combinator is risky when used with partial
|
||||
// inputs. So handle with care.
|
||||
named!(expression<TokenIter, Expression, ParseError>,
|
||||
named!(expression<TokenIter, Expression, error::Error>,
|
||||
do_parse!(
|
||||
expr: alt!(
|
||||
complete!(list_op_expression) |
|
||||
@ -656,7 +668,7 @@ fn expression_to_statement(v: Expression) -> ParseResult<Statement> {
|
||||
Ok(Statement::Expression(v))
|
||||
}
|
||||
|
||||
named!(expression_statement<TokenIter, Statement, ParseError>,
|
||||
named!(expression_statement<TokenIter, Statement, error::Error>,
|
||||
map_res!(
|
||||
terminated!(expression, punct!(";")),
|
||||
expression_to_statement
|
||||
@ -670,7 +682,7 @@ fn tuple_to_let(t: (Token, Expression)) -> ParseResult<Statement> {
|
||||
}))
|
||||
}
|
||||
|
||||
named!(let_statement<TokenIter, Statement, ParseError>,
|
||||
named!(let_statement<TokenIter, Statement, error::Error>,
|
||||
map_res!(
|
||||
do_parse!(
|
||||
word!("let") >>
|
||||
@ -691,7 +703,7 @@ fn tuple_to_import(t: (Token, Token)) -> ParseResult<Statement> {
|
||||
}))
|
||||
}
|
||||
|
||||
named!(import_statement<TokenIter, Statement, ParseError>,
|
||||
named!(import_statement<TokenIter, Statement, error::Error>,
|
||||
map_res!(
|
||||
do_parse!(
|
||||
word!("import") >>
|
||||
@ -705,7 +717,7 @@ named!(import_statement<TokenIter, Statement, ParseError>,
|
||||
)
|
||||
);
|
||||
|
||||
named!(statement<TokenIter, Statement, ParseError>,
|
||||
named!(statement<TokenIter, Statement, error::Error>,
|
||||
do_parse!(
|
||||
stmt: alt_complete!(
|
||||
import_statement |
|
||||
@ -716,8 +728,8 @@ named!(statement<TokenIter, Statement, ParseError>,
|
||||
)
|
||||
);
|
||||
|
||||
/// Parses a LocatedSpan into a list of Statements or a ParseError.
|
||||
pub fn parse(input: LocatedSpan<&str>) -> Result<Vec<Statement>, ParseError> {
|
||||
/// Parses a LocatedSpan into a list of Statements or an error::Error.
|
||||
pub fn parse(input: LocatedSpan<&str>) -> Result<Vec<Statement>, error::Error> {
|
||||
match tokenize(input) {
|
||||
Ok(tokenized) => {
|
||||
let mut out = Vec::new();
|
||||
@ -734,25 +746,25 @@ pub fn parse(input: LocatedSpan<&str>) -> Result<Vec<Statement>, ParseError> {
|
||||
return Err(e);
|
||||
}
|
||||
IResult::Error(e) => {
|
||||
return Err(ParseError {
|
||||
description: format!(
|
||||
"Statement Parse error: {:?} current token: {:?}",
|
||||
e, i_[0]
|
||||
),
|
||||
pos: Position {
|
||||
return Err(error::Error::new_with_errorkind(
|
||||
format!("Statement Parse error: {:?} current token: {:?}", e, i_[0]),
|
||||
error::ErrorType::ParseError,
|
||||
Position {
|
||||
line: i_[0].pos.line,
|
||||
column: i_[0].pos.column,
|
||||
},
|
||||
});
|
||||
e,
|
||||
));
|
||||
}
|
||||
IResult::Incomplete(ei) => {
|
||||
return Err(ParseError {
|
||||
description: format!("Unexpected end of parsing input: {:?}", ei),
|
||||
pos: Position {
|
||||
return Err(error::Error::new(
|
||||
format!("Unexpected end of parsing input: {:?}", ei),
|
||||
error::ErrorType::IncompleteParsing,
|
||||
Position {
|
||||
line: i_[0].pos.line,
|
||||
column: i_[0].pos.column,
|
||||
},
|
||||
});
|
||||
));
|
||||
}
|
||||
IResult::Done(rest, stmt) => {
|
||||
out.push(stmt);
|
||||
@ -766,12 +778,11 @@ pub fn parse(input: LocatedSpan<&str>) -> Result<Vec<Statement>, ParseError> {
|
||||
return Ok(out);
|
||||
}
|
||||
Err(e) => {
|
||||
// FIXME(jwall): We should really capture the location
|
||||
// of the tokenization error here.
|
||||
return Err(ParseError {
|
||||
description: format!("Tokenize Error: {:?}", e.1),
|
||||
pos: e.0,
|
||||
});
|
||||
return Err(error::Error::new(
|
||||
format!("Tokenization Error {:?}", e.1),
|
||||
error::ErrorType::ParseError,
|
||||
e.0,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ use nom;
|
||||
use nom::{alpha, digit, is_alphanumeric, multispace};
|
||||
use nom::{InputIter, InputLength, Slice};
|
||||
use ast::*;
|
||||
use error;
|
||||
use std;
|
||||
use std::result::Result;
|
||||
|
||||
@ -327,8 +328,6 @@ named!(token( Span ) -> Token,
|
||||
end_of_input)
|
||||
);
|
||||
|
||||
// TODO(jwall): This should return a ParseError instead.
|
||||
|
||||
/// Consumes an input Span and returns either a Vec<Token> or a nom::ErrorKind.
|
||||
pub fn tokenize(input: Span) -> Result<Vec<Token>, (Position, nom::ErrorKind)> {
|
||||
let mut out = Vec::new();
|
||||
@ -378,7 +377,7 @@ pub fn tokenize(input: Span) -> Result<Vec<Token>, (Position, nom::ErrorKind)> {
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
pub fn token_clone(t: &Token) -> Result<Token, ParseError> {
|
||||
pub fn token_clone(t: &Token) -> Result<Token, error::Error> {
|
||||
Ok(t.clone())
|
||||
}
|
||||
|
||||
@ -448,10 +447,10 @@ macro_rules! match_type {
|
||||
use std::convert::Into;
|
||||
if i_.input_len() == 0 {
|
||||
nom::IResult::Error(
|
||||
nom::ErrorKind::Custom(ParseError{
|
||||
description: format!("End of Input! {}", $msg),
|
||||
pos: Position{line: 0, column: 0}
|
||||
}))
|
||||
nom::ErrorKind::Custom(error::Error::new(
|
||||
format!("End of Input! {}", $msg),
|
||||
error::ErrorType::IncompleteParsing,
|
||||
Position{line: 0, column: 0})))
|
||||
} else {
|
||||
let tok = &(i_[0]);
|
||||
if tok.typ == $t {
|
||||
@ -461,9 +460,10 @@ macro_rules! match_type {
|
||||
nom::ErrorKind::Custom(e.into())),
|
||||
}
|
||||
} else {
|
||||
nom::IResult::Error(nom::ErrorKind::Custom(ParseError{
|
||||
description: $msg.to_string(),
|
||||
pos: tok.pos.clone()}))
|
||||
nom::IResult::Error(nom::ErrorKind::Custom(error::Error::new(
|
||||
$msg.to_string(),
|
||||
error::ErrorType::UnexpectedToken,
|
||||
tok.pos.clone())))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -502,9 +502,10 @@ macro_rules! match_token {
|
||||
nom::ErrorKind::Custom(e.into())),
|
||||
}
|
||||
} else {
|
||||
nom::IResult::Error(nom::ErrorKind::Custom(ParseError{
|
||||
description: format!("{} Instead is ({})", $msg, tok.fragment),
|
||||
pos: tok.pos.clone()}))
|
||||
nom::IResult::Error(nom::ErrorKind::Custom(error::Error::new(
|
||||
format!("{} Instead is ({})", $msg, tok.fragment),
|
||||
error::ErrorType::UnexpectedToken,
|
||||
tok.pos.clone())))
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -525,7 +526,7 @@ macro_rules! word {
|
||||
}
|
||||
|
||||
/// pos gets the current position from a TokenIter input without consuming it.
|
||||
pub fn pos(i: TokenIter) -> nom::IResult<TokenIter, Position, ParseError> {
|
||||
pub fn pos(i: TokenIter) -> nom::IResult<TokenIter, Position, error::Error> {
|
||||
let tok = &i[0];
|
||||
let line = tok.pos.line;
|
||||
let column = tok.pos.column;
|
||||
|
Loading…
x
Reference in New Issue
Block a user