Some wording changes; added ws combinator
This commit is contained in:
parent
31da29c324
commit
d034a99ac1
@ -8,7 +8,7 @@ use nom::character::complete::{one_of, space0, alphanumeric0};
|
|||||||
use nom::bytes::complete::{tag, take, take_while, take_while1, take_until};
|
use nom::bytes::complete::{tag, take, take_while, take_while1, take_until};
|
||||||
use nom::combinator::{cut, map, map_res, value, opt, verify};
|
use nom::combinator::{cut, 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::{context, VerboseError};
|
use nom::error::{context, ParseError, VerboseError};
|
||||||
use nom::branch::alt;
|
use nom::branch::alt;
|
||||||
use nom::sequence::{pair, delimited, preceded};
|
use nom::sequence::{pair, delimited, preceded};
|
||||||
|
|
||||||
@ -18,6 +18,16 @@ use crate::builtin::Builtin;
|
|||||||
type ParseResult<'a, T> = IResult<&'a str, T, VerboseError<&'a str>>;
|
type ParseResult<'a, T> = IResult<&'a str, T, VerboseError<&'a str>>;
|
||||||
|
|
||||||
|
|
||||||
|
pub fn ws<I, O, E: ParseError<I>, F>(parser: F) -> impl Fn(I) -> IResult<I, O, E>
|
||||||
|
where
|
||||||
|
I: nom::InputTakeAtPosition,
|
||||||
|
<I as nom::InputTakeAtPosition>::Item: nom::AsChar + Clone,
|
||||||
|
F: Fn(I) -> IResult<I, O, E>,
|
||||||
|
{
|
||||||
|
delimited(space0, parser, space0)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fn single_alphabetic_character(text: &str) -> ParseResult<char> {
|
fn single_alphabetic_character(text: &str) -> ParseResult<char> {
|
||||||
let p = verify(take(1usize), |s: &str| s.chars().nth(0).map(|c| c.is_alphabetic()).unwrap_or(false));
|
let p = verify(take(1usize), |s: &str| s.chars().nth(0).map(|c| c.is_alphabetic()).unwrap_or(false));
|
||||||
map(p, |s: &str| s.chars().nth(0).unwrap())(text)
|
map(p, |s: &str| s.chars().nth(0).unwrap())(text)
|
||||||
@ -69,20 +79,20 @@ fn number_literal(text: &str) -> ParseResult<ExpressionKind> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn binary_literal(input: &str) -> ParseResult<ExpressionKind> {
|
fn binary_literal(text: &str) -> ParseResult<ExpressionKind> {
|
||||||
let p = preceded(tag("0b"), cut(take_while1(|c: char| c == '0' || c == '1')));
|
let p = preceded(tag("0b"), cut(take_while1(|c: char| c == '0' || c == '1')));
|
||||||
let (rest, n): (&str, u64) = map_res(
|
let (rest, n): (&str, u64) = map_res(
|
||||||
p, |hex_str: &str| u64::from_str_radix(hex_str, 2)
|
p, |hex_str: &str| u64::from_str_radix(hex_str, 2)
|
||||||
)(input)?;
|
)(text)?;
|
||||||
let expr = ExpressionKind::NatLiteral(n);
|
let expr = ExpressionKind::NatLiteral(n);
|
||||||
Ok((rest, expr))
|
Ok((rest, expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hex_literal(input: &str) -> ParseResult<ExpressionKind> {
|
fn hex_literal(text: &str) -> ParseResult<ExpressionKind> {
|
||||||
let p = preceded(tag("0x"), cut(take_while1(|c: char| c.is_digit(16))));
|
let p = preceded(tag("0x"), cut(take_while1(|c: char| c.is_digit(16))));
|
||||||
let (rest, n): (&str, u64) = map_res(
|
let (rest, n): (&str, u64) = map_res(
|
||||||
p, |hex_str: &str| u64::from_str_radix(hex_str, 16)
|
p, |hex_str: &str| u64::from_str_radix(hex_str, 16)
|
||||||
)(input)?;
|
)(text)?;
|
||||||
let expr = ExpressionKind::NatLiteral(n);
|
let expr = ExpressionKind::NatLiteral(n);
|
||||||
Ok((rest, expr))
|
Ok((rest, expr))
|
||||||
}
|
}
|
||||||
@ -96,14 +106,14 @@ fn string_literal(text: &str) -> ParseResult<ExpressionKind> {
|
|||||||
Ok((text, expr))
|
Ok((text, expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn literal(input: &str) -> ParseResult<ExpressionKind> {
|
fn literal(text: &str) -> ParseResult<ExpressionKind> {
|
||||||
alt((
|
alt((
|
||||||
string_literal,
|
string_literal,
|
||||||
hex_literal,
|
hex_literal,
|
||||||
binary_literal,
|
binary_literal,
|
||||||
number_literal,
|
number_literal,
|
||||||
bool_literal,
|
bool_literal,
|
||||||
))(input)
|
))(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paren_expr(text: &str) -> ParseResult<ExpressionKind> {
|
fn paren_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||||
@ -111,10 +121,10 @@ fn paren_expr(text: &str) -> ParseResult<ExpressionKind> {
|
|||||||
context("Paren expression", 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(text: &str) -> ParseResult<PrefixOp> {
|
||||||
use nom::character::complete::char;
|
use nom::character::complete::char;
|
||||||
let p = alt((char('+'), char('-'), char('!')));
|
let p = alt((char('+'), char('-'), char('!')));
|
||||||
map(p, |sigil| PrefixOp::from_str(&sigil.to_string()).unwrap())(input)
|
map(p, |sigil| PrefixOp::from_str(&sigil.to_string()).unwrap())(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn identifier_expr(text: &str) -> ParseResult<ExpressionKind> {
|
fn identifier_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||||
@ -167,7 +177,7 @@ fn call_expr(text: &str) -> ParseResult<ExpressionKind> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn prefix_expr(text: &str) -> ParseResult<ExpressionKind> {
|
fn prefix_expr(text: &str) -> ParseResult<ExpressionKind> {
|
||||||
let (text, pfx) = delimited(space0, opt(prefix_op), space0)(text)?;
|
let (text, pfx) = ws(opt(prefix_op))(text)?;
|
||||||
let (text, result) = call_expr(text)?;
|
let (text, result) = call_expr(text)?;
|
||||||
match pfx {
|
match pfx {
|
||||||
None => Ok((text, result)),
|
None => Ok((text, result)),
|
||||||
@ -209,9 +219,20 @@ fn precedence_expr(text: &str) -> ParseResult<ExpressionKind> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn expression_kind(text: &str) -> ParseResult<ExpressionKind> {
|
fn expression_kind(text: &str) -> ParseResult<ExpressionKind> {
|
||||||
precedence_expr(text)
|
context("Expression kind", precedence_expr)(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
fn type_anno(text: &str) -> ParseResult<TypeIdentifier> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expression(text: &str) -> ParseResult<Expression> {
|
||||||
|
let (rest, (kind, type_anno)) = pair(expression_kind, type_anno)(text)?;
|
||||||
|
Ok((rest, Expression::with_anno(ItemId::new(0), kind, type_anno)))
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
pub fn perform_parsing(input: &str) -> Result<String, String> {
|
pub fn perform_parsing(input: &str) -> Result<String, String> {
|
||||||
let output = match expression_kind(input) {
|
let output = match expression_kind(input) {
|
||||||
Ok((rest, ast)) => format!("{:?} (rest: {})", ast, rest),
|
Ok((rest, ast)) => format!("{:?} (rest: {})", ast, rest),
|
||||||
|
Loading…
Reference in New Issue
Block a user