More parser refactoring

This commit is contained in:
Greg Shuflin 2021-11-20 02:33:09 -08:00
parent 9a13848f80
commit c1ef0ee506
3 changed files with 33 additions and 16 deletions

View File

@ -17,11 +17,13 @@ use nom::{
}; };
use nom_locate::{position, LocatedSpan}; use nom_locate::{position, LocatedSpan};
use crate::identifier::{Id, IdStore}; use crate::{
use crate::parsing::StoreRef; identifier::{Id, IdStore},
parsing::StoreRef,
};
pub type Span<'a> = LocatedSpan<&'a str, StoreRef>; pub type Span<'a> = LocatedSpan<&'a str, StoreRef>;
type ParseResult<'a, O> = IResult<Span<'a>, O, VerboseError<Span<'a>>>; pub type ParseResult<'a, O> = IResult<Span<'a>, O, VerboseError<Span<'a>>>;
use crate::ast::*; use crate::ast::*;

View File

@ -32,16 +32,7 @@ impl Parser {
pub(crate) fn parse_comb(&mut self, input: &str) -> Result<AST, ParseError> { pub(crate) fn parse_comb(&mut self, input: &str) -> Result<AST, ParseError> {
let span = Span::new_extra(input, self.id_store.clone()); let span = Span::new_extra(input, self.id_store.clone());
let (rest, output) = combinator::program(span).map_err(|err| convert_err(input, err))?; convert(input, combinator::program(span))
if rest.fragment() != &"" {
return Err(ParseError {
location: Default::default(),
msg: format!("Bad parse state, remaining text: `{}`", rest.fragment()),
});
}
Ok(output)
} }
#[cfg(test)] #[cfg(test)]
@ -52,7 +43,7 @@ impl Parser {
#[cfg(test)] #[cfg(test)]
fn expression_comb(&mut self, input: &str) -> Result<Expression, ParseError> { fn expression_comb(&mut self, input: &str) -> Result<Expression, ParseError> {
let span = Span::new_extra(input, self.id_store.clone()); let span = Span::new_extra(input, self.id_store.clone());
combinator::expression(span).map_err(|err| convert_err(input, err)).map(|(rest, output)| output) convert(input, combinator::expression(span))
} }
#[cfg(test)] #[cfg(test)]
@ -63,7 +54,7 @@ impl Parser {
#[cfg(test)] #[cfg(test)]
fn block_comb(&mut self, input: &str) -> Result<Block, ParseError> { fn block_comb(&mut self, input: &str) -> Result<Block, ParseError> {
let span = Span::new_extra(input, self.id_store.clone()); let span = Span::new_extra(input, self.id_store.clone());
combinator::block(span).map_err(|err| convert_err(input, err)).map(|(_, output)| output) convert(input, combinator::block(span))
} }
fn fresh(&mut self) -> Id<ASTItem> { fn fresh(&mut self) -> Id<ASTItem> {
@ -71,6 +62,30 @@ impl Parser {
} }
} }
fn convert<'a, O>(input: &'a str, result: combinator::ParseResult<'a, O>) -> Result<O, ParseError> {
use nom::{error::VerboseError, Err, Finish};
match result.finish() {
Ok((rest, output)) => {
if rest.fragment() != &"" {
return Err(ParseError {
location: Default::default(),
msg: format!("Bad parse state, remaining text: `{}`", rest.fragment()),
});
}
Ok(output)
}
Err(err) => {
let err = VerboseError {
errors: err.errors.into_iter().map(|(sp, kind)| (*sp.fragment(), kind)).collect(),
};
let msg = nom::error::convert_error(input, err);
Err(ParseError { msg, location: (0).into() })
}
}
}
fn convert_err<'a>( fn convert_err<'a>(
input: &'a str, input: &'a str,
err: nom::Err<nom::error::VerboseError<combinator::Span<'a>>>, err: nom::Err<nom::error::VerboseError<combinator::Span<'a>>>,

View File

@ -192,7 +192,7 @@ fn basic_literals() {
assert_expr!("0b0_1_0", expr(NatLiteral(2))); assert_expr!("0b0_1_0", expr(NatLiteral(2)));
assert_expr!("0xff", expr(NatLiteral(255))); assert_expr!("0xff", expr(NatLiteral(255)));
assert_expr!("0x032f", expr(NatLiteral(815))); assert_expr!("0x032f", expr(NatLiteral(815)));
assert_expr!("0xf_f_", expr(NatLiteral(255))); assert_expr!("0xf_f", expr(NatLiteral(255)));
assert_expr!("false", expr(BoolLiteral(false))); assert_expr!("false", expr(BoolLiteral(false)));
assert_expr!("true", expr(BoolLiteral(true))); assert_expr!("true", expr(BoolLiteral(true)));
} }