#![feature(assert_matches)] #![allow(dead_code)] //TODO eventually turn this off mod bnf; mod parser; mod sequence; use parser::{ParseResult, Parser}; fn literal(expected: &'static str) -> impl Fn(&str) -> ParseResult<&str, &str, &str> { move |input| match input.get(0..expected.len()) { Some(next) if next == expected => Ok((expected, &input[expected.len()..])), _ => Err(input), } } fn map
(parser: P, map_fn: F) -> impl Parser where P: Parser, F: Fn(O1) -> O2, { move |input| { parser .parse(input) .map(|(result, rest)| (map_fn(result), rest)) } } fn pred
(parser: P, pred_fn: F) -> impl Parser where P: Parser, F: Fn(&O) -> bool, { move |input| { parser.parse(input).and_then(|(result, rest)| { if pred_fn(&result) { Ok((result, rest)) } else { Err(rest) } }) } } fn zero_or_more
(parser: P) -> impl Parser, I> where P: Parser, I: Copy, { move |mut input| { let mut results = Vec::new(); while let Ok((item, rest)) = parser.parse(input) { results.push(item); input = rest; } Ok((results, input)) } } fn one_or_more
(parser: P) -> impl Parser, I>
where
P: Parser + 'static,
I: Copy + 'static,
O: 'static,
{
let parser = std::rc::Rc::new(parser);
parser
.clone()
.then(zero_or_more(parser))
.map(|(first, rest)| {
let mut output = vec![first];
output.extend(rest.into_iter());
output
})
}
/// Parses a standard identifier in a programming language
fn identifier(input: &str) -> ParseResult<&str, String, &str> {
let mut chars = input.chars();
let mut buf = String::new();
match chars.next() {
Some(ch) if ch.is_alphabetic() => buf.push(ch),
_ => return Err(input),
}
while let Some(next) = chars.next() {
if next.is_alphanumeric() {
buf.push(next);
} else {
break;
}
}
let next_index = buf.len();
Ok((buf, &input[next_index..]))
}
fn any_char(input: &str) -> ParseResult<&str, char, &str> {
match input.chars().next() {
Some(ch) => Ok((ch, &input[ch.len_utf8()..])),
None => Err(input),
}
}
fn choice