Compare commits

..

2 Commits

Author SHA1 Message Date
annieversary a66e769b5a cleanup 2021-09-26 17:05:30 +02:00
annieversary 9390fb4fd5 fixed it :) 2021-09-26 16:56:41 +02:00
1 changed files with 62 additions and 47 deletions

View File

@ -1,17 +1,12 @@
use nom::{ use nom::{
branch::alt, branch::alt,
bytes::complete::{escaped, is_not}, bytes::complete::{escaped, is_not, tag, take_until},
bytes::complete::{tag, take_until}, character::complete::{alpha1, alphanumeric1, char, multispace0, one_of, space0},
character::complete::char, combinator::{cut, map, recognize, value},
character::complete::multispace0, error::ParseError,
character::complete::{alpha1, alphanumeric1, digit1, one_of, space0},
combinator::value,
combinator::{cut, map, map_res, recognize},
error::{context, convert_error, ContextError, ErrorKind, ParseError, VerboseError},
multi::{fold_many0, many0, separated_list0}, multi::{fold_many0, many0, separated_list0},
number::complete::double, number::complete::double,
sequence::pair, sequence::{delimited, pair, preceded, terminated, tuple},
sequence::{delimited, preceded, terminated, tuple},
IResult, Parser, IResult, Parser,
}; };
@ -28,17 +23,11 @@ fn pinline_comment<'a, E>(i: &'a str) -> IResult<&'a str, (), E>
where where
E: ParseError<&'a str>, E: ParseError<&'a str>,
{ {
value( value((), tuple((tag("/*"), take_until("*/"), tag("*/"))))(i)
(), // Output is thrown away.
tuple((tag("/*"), take_until("*/"), tag("*/"))),
)(i)
} }
fn peol_comment<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, (), E> { fn peol_comment<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, (), E> {
value( value((), pair(char('/'), is_not("\n\r")))(i)
(), // Output is thrown away.
pair(char('/'), is_not("\n\r")),
)(i)
} }
fn braces<'a, P, O, E>(a: P) -> impl FnMut(&'a str) -> IResult<&'a str, O, E> fn braces<'a, P, O, E>(a: P) -> impl FnMut(&'a str) -> IResult<&'a str, O, E>
@ -61,11 +50,17 @@ where
) )
} }
fn identifier(input: &str) -> IResult<&str, &str> { fn identifier(i: &str) -> IResult<&str, &str> {
println!("identifier: {}", i);
recognize(pair( recognize(pair(
alt((alpha1, tag("_"))), alt((alpha1, tag("_"))),
many0(alt((alphanumeric1, tag("_")))), many0(alt((alphanumeric1, tag("_")))),
))(input) ))(i)
}
fn variable(i: &str) -> IResult<&str, Expr> {
println!("variable: {}", i);
map(identifier, |a| Expr::Var(a.to_string()))(i)
} }
fn parse_str<'a>(i: &'a str) -> IResult<&'a str, &'a str> { fn parse_str<'a>(i: &'a str) -> IResult<&'a str, &'a str> {
@ -73,6 +68,7 @@ fn parse_str<'a>(i: &'a str) -> IResult<&'a str, &'a str> {
} }
fn string<'a>(i: &'a str) -> IResult<&'a str, Expr> { fn string<'a>(i: &'a str) -> IResult<&'a str, Expr> {
println!("string: {}", i);
map( map(
preceded(char('\"'), cut(terminated(parse_str, char('\"')))), preceded(char('\"'), cut(terminated(parse_str, char('\"')))),
|s| Expr::LStr(String::from(s)), |s| Expr::LStr(String::from(s)),
@ -87,18 +83,22 @@ fn boolean<'a>(i: &'a str) -> IResult<&'a str, Expr> {
))(i) ))(i)
} }
fn call<'a>(i: &'a str) -> IResult<&'a str, (Identifier, Vec<Expr>)> { fn call<'a>(i: &'a str) -> IResult<&'a str, Expr> {
println!("call: {}", i); println!("call: {}", i);
map( map(
tuple(( tuple((
identifier, identifier,
delimited( sc,
char('('), alt((
separated_list0(tuple((sc, tag(","), sc)), expr), value(vec![], tuple((char('('), sc, char(')')))),
char(')'), delimited(
), char('('),
separated_list0(tuple((sc, tag(","), sc)), expr),
char(')'),
),
)),
)), )),
|(i, v)| (i.to_string(), v), |(i, _, v)| Expr::Call(i.to_string(), v),
)(i) )(i)
} }
@ -112,7 +112,7 @@ fn literal(i: &str) -> IResult<&str, Expr> {
} }
fn factor_bin(i: &str) -> IResult<&str, Expr> { fn factor_bin(i: &str) -> IResult<&str, Expr> {
alt((delimited(space0, literal, space0), expr))(i) alt((delimited(space0, term, space0), expr))(i)
} }
fn bin_less_greater(i: &str) -> IResult<&str, Expr> { fn bin_less_greater(i: &str) -> IResult<&str, Expr> {
@ -134,13 +134,13 @@ fn bin_equal_not(i: &str) -> IResult<&str, Expr> {
let (i, init) = bin_less_greater(i)?; let (i, init) = bin_less_greater(i)?;
fold_many0( fold_many0(
pair(alt((char('<'), char('>'))), bin_less_greater), pair(alt((tag("=="), tag("!="))), bin_less_greater),
move || init.clone(), move || init.clone(),
|acc, (op, val): (char, Expr)| { |acc, (op, val)| {
if op == '<' { if op == "==" {
Expr::Binary(BinOp::LessThan, Box::new(acc), Box::new(val)) Expr::Binary(BinOp::Equals, Box::new(acc), Box::new(val))
} else { } else {
Expr::Binary(BinOp::GreaterThan, Box::new(acc), Box::new(val)) Expr::Binary(BinOp::NotEquals, Box::new(acc), Box::new(val))
} }
}, },
)(i) )(i)
@ -177,25 +177,19 @@ fn binary<'a>(i: &'a str) -> IResult<&'a str, Expr> {
)(i) )(i)
} }
fn receive<'a>(i: &'a str) -> IResult<&'a str, Expr> { fn receive<'a>(i: &'a str) -> IResult<&'a str, Expr> {
println!("receive: {}", i);
map(pair(tag("<-"), expr), |(_, expr)| { map(pair(tag("<-"), expr), |(_, expr)| {
Expr::Receive(Box::new(expr)) Expr::Receive(Box::new(expr))
})(i) })(i)
} }
pub fn expr<'a>(i: &'a str) -> IResult<&'a str, Expr> { pub fn expr<'a>(i: &'a str) -> IResult<&'a str, Expr> {
alt((receive, binary))(i)
}
fn term<'a>(i: &'a str) -> IResult<&'a str, Expr> {
println!("expr: {}", i); println!("expr: {}", i);
delimited( delimited(sc, alt((literal, call, variable, parens(expr))), sc)(i)
sc,
alt((
parens(expr),
map(call, |(i, v)| Expr::Call(i, v)),
receive,
binary,
literal,
map(identifier, |i| Expr::Var(i.to_string())),
)),
sc,
)(i)
} }
#[cfg(test)] #[cfg(test)]
@ -214,7 +208,7 @@ mod tests {
#[test] #[test]
fn can_parse_binary_op() { fn can_parse_binary_op() {
let a = "3 +3 + 6"; let a = "3 +3 + 6";
let (_rest, res) = binary(a).unwrap(); let (_rest, res) = expr(a).unwrap();
assert_eq!( assert_eq!(
res, res,
@ -233,7 +227,7 @@ mod tests {
#[test] #[test]
fn can_parse_binary_op_with_str() { fn can_parse_binary_op_with_str() {
let a = r#"3 +3 + 6 + "hey""#; let a = r#"3 +3 + 6 + "hey""#;
let (_rest, res) = binary(a).unwrap(); let (_rest, res) = expr(a).unwrap();
assert_eq!( assert_eq!(
res, res,
@ -253,6 +247,15 @@ mod tests {
); );
} }
#[test]
fn can_parse_var() {
let a = "hello";
let (rest, res) = expr(a).unwrap();
assert_eq!(res, Expr::Var("hello".to_string()));
assert_eq!(rest, "");
}
#[test] #[test]
fn can_parse_empty_call() { fn can_parse_empty_call() {
let a = "hello()"; let a = "hello()";
@ -262,6 +265,18 @@ mod tests {
assert_eq!(rest, ""); assert_eq!(rest, "");
} }
#[test]
fn can_parse_call_with_var() {
let a = "hello(hey)";
let (rest, res) = expr(a).unwrap();
assert_eq!(
res,
Expr::Call("hello".to_string(), vec![Expr::Var("hey".to_string())])
);
assert_eq!(rest, "");
}
#[test] #[test]
fn can_parse_call() { fn can_parse_call() {
let a = "hello(1.0, 45 , yeah)"; let a = "hello(1.0, 45 , yeah)";