Use VerboseError
This commit is contained in:
parent
84455d11d5
commit
b1ffcd709b
@ -8,14 +8,14 @@ use nom::character::complete::{one_of, space0, alphanumeric0};
|
|||||||
use nom::bytes::complete::{tag, take, take_while, take_until};
|
use nom::bytes::complete::{tag, take, take_while, take_until};
|
||||||
use nom::combinator::{map, map_res, value, opt, verify};
|
use nom::combinator::{map, map_res, value, opt, verify};
|
||||||
use nom::multi::{separated_list, separated_nonempty_list, many1, many0};
|
use nom::multi::{separated_list, separated_nonempty_list, many1, many0};
|
||||||
//use nom::error::{ParseError, ErrorKind};
|
use nom::error::{context, VerboseError};
|
||||||
use nom::branch::alt;
|
use nom::branch::alt;
|
||||||
use nom::sequence::{pair, delimited};
|
use nom::sequence::{pair, delimited};
|
||||||
|
|
||||||
use crate::ast::*;
|
use crate::ast::*;
|
||||||
use crate::builtin::Builtin;
|
use crate::builtin::Builtin;
|
||||||
|
|
||||||
type ParseResult<'a, T> = IResult<&'a str, T>;
|
type ParseResult<'a, T> = IResult<&'a str, T, VerboseError<&'a str>>;
|
||||||
|
|
||||||
|
|
||||||
fn single_alphabetic_character(text: &str) -> ParseResult<char> {
|
fn single_alphabetic_character(text: &str) -> ParseResult<char> {
|
||||||
@ -40,7 +40,7 @@ fn identifier(text: &str) -> ParseResult<Rc<String>> {
|
|||||||
|
|
||||||
const OPERATOR_CHARS: &'static str = "~`!@#$%^&*-+=<>?/|";
|
const OPERATOR_CHARS: &'static str = "~`!@#$%^&*-+=<>?/|";
|
||||||
fn parse_binop(text: &str) -> ParseResult<BinOp> {
|
fn parse_binop(text: &str) -> ParseResult<BinOp> {
|
||||||
let (text, op): (_, Vec<char>) = many1(one_of(OPERATOR_CHARS))(text)?;
|
let (text, op): (_, Vec<char>) = context("binop yo", many1(one_of(OPERATOR_CHARS)))(text)?;
|
||||||
let sigil: String = op.into_iter().collect();
|
let sigil: String = op.into_iter().collect();
|
||||||
Ok((text, BinOp::from_sigil(&sigil)))
|
Ok((text, BinOp::from_sigil(&sigil)))
|
||||||
}
|
}
|
||||||
@ -110,7 +110,7 @@ fn literal(input: &str) -> ParseResult<ExpressionKind> {
|
|||||||
|
|
||||||
fn paren_expr(text: &str) -> ParseResult<ExpressionKind> {
|
fn paren_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||||
use nom::character::complete::char;
|
use nom::character::complete::char;
|
||||||
delimited(char('('), expression_kind, char(')'))(text)
|
context("Paren expression", delimited(char('('), expression_kind, char(')')))(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prefix_op(input: &str) -> ParseResult<PrefixOp> {
|
fn prefix_op(input: &str) -> ParseResult<PrefixOp> {
|
||||||
@ -181,32 +181,37 @@ fn prefix_expr(text: &str) -> ParseResult<ExpressionKind> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// this implements Pratt parsing, see http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
|
// this implements Pratt parsing, see http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
|
||||||
fn precedence_expr(input: &str, precedence: i32) -> ParseResult<ExpressionKind> {
|
fn precedence_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||||
let (mut outer_rest, mut lhs) = prefix_expr(input)?;
|
fn inner_precedence_expr(input: &str, precedence: i32) -> ParseResult<ExpressionKind> {
|
||||||
loop {
|
let (mut outer_rest, mut lhs) = prefix_expr(input)?;
|
||||||
let (rest, _) = space0(outer_rest)?;
|
loop {
|
||||||
let (rest, maybe_binop) = opt(parse_binop)(rest)?;
|
let (rest, _) = space0(outer_rest)?;
|
||||||
let (new_precedence, binop) = match maybe_binop {
|
let (rest, maybe_binop) = opt(parse_binop)(rest)?;
|
||||||
Some(binop) => (binop.precedence(), binop),
|
let (new_precedence, binop) = match maybe_binop {
|
||||||
None => break,
|
Some(binop) => (binop.precedence(), binop),
|
||||||
};
|
None => break,
|
||||||
|
};
|
||||||
|
|
||||||
if precedence >= new_precedence {
|
if precedence >= new_precedence {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
let (rest, _) = space0(rest)?;
|
||||||
|
let (rest, rhs) = inner_precedence_expr(rest, new_precedence)?;
|
||||||
|
outer_rest = rest;
|
||||||
|
lhs = ExpressionKind::BinExp(binop,
|
||||||
|
bx!(Expression::new(ItemId::new(0), lhs)),
|
||||||
|
bx!(Expression::new(ItemId::new(0), rhs))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
let (rest, _) = space0(rest)?;
|
Ok((outer_rest, lhs))
|
||||||
let (rest, rhs) = precedence_expr(rest, new_precedence)?;
|
|
||||||
outer_rest = rest;
|
|
||||||
lhs = ExpressionKind::BinExp(binop,
|
|
||||||
bx!(Expression::new(ItemId::new(0), lhs)),
|
|
||||||
bx!(Expression::new(ItemId::new(0), rhs))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Ok((outer_rest, lhs))
|
context("Precedence expression",
|
||||||
|
|input| inner_precedence_expr(input, BinOp::min_precedence())
|
||||||
|
)(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expression_kind(input: &str) -> ParseResult<ExpressionKind> {
|
fn expression_kind(text: &str) -> ParseResult<ExpressionKind> {
|
||||||
precedence_expr(input, BinOp::min_precedence())
|
precedence_expr(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn perform_parsing(input: &str) -> Result<String, String> {
|
pub fn perform_parsing(input: &str) -> Result<String, String> {
|
||||||
|
Loading…
Reference in New Issue
Block a user