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 crate::identifier::{Id, IdStore};
use crate::parsing::StoreRef;
use crate::{
identifier::{Id, IdStore},
parsing::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::*;

View File

@ -32,16 +32,7 @@ impl Parser {
pub(crate) fn parse_comb(&mut self, input: &str) -> Result<AST, ParseError> {
let span = Span::new_extra(input, self.id_store.clone());
let (rest, output) = combinator::program(span).map_err(|err| convert_err(input, err))?;
if rest.fragment() != &"" {
return Err(ParseError {
location: Default::default(),
msg: format!("Bad parse state, remaining text: `{}`", rest.fragment()),
});
}
Ok(output)
convert(input, combinator::program(span))
}
#[cfg(test)]
@ -52,7 +43,7 @@ impl Parser {
#[cfg(test)]
fn expression_comb(&mut self, input: &str) -> Result<Expression, ParseError> {
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)]
@ -63,7 +54,7 @@ impl Parser {
#[cfg(test)]
fn block_comb(&mut self, input: &str) -> Result<Block, ParseError> {
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> {
@ -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>(
input: &'a str,
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!("0xff", expr(NatLiteral(255)));
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!("true", expr(BoolLiteral(true)));
}