4 releases
0.1.3 | Aug 17, 2019 |
---|---|
0.1.2 | Aug 13, 2019 |
0.1.1 | May 13, 2019 |
0.1.0 | May 13, 2019 |
#327 in Parser tooling
62KB
1K
SLoC
combinedfun
A little nom
-like parser combinator library which stays away from macros, while trying to achieve at least part of the expressiveness of nom
Welcome to this little library, the only limit is the sky. And deep recursion. And compile times. And type inference that fucks up. And sometimes, if you're "lucky": Major fuckups when it comes to lifetime inference, leaving you having to use the methods instead of operators, since, while the methods actually use the operators, actually work there. Don't ask me why. It's a mystery.
lib.rs
:
This is a parser combinator library that aims to provide short and consise, but easily readable parser combinators.
If you don't know how parser combinators work, I suggest looking at
nom
first.
This library doesn't use macros, so it is a bit limited for some applications (specifically
places where you can use map_parser
are rather limited).
It also uses operator overloading for writing parsers that are easy to read and write.
Here is one example (I have no clue why almost every closure needs its arguments specified):
use std::iter;
use combinedfun as cf;
enum End {
Repeat(String),
Add(usize),
}
let parser = (
cf::record_while(|c: &char| c.is_digit(10), 1..)
>> (|s: &str| s.parse::<usize>().unwrap())
>> (
-cf::tag(" ")
>> cf::take(..)
>> (|s: &str| End::Repeat(s.to_owned()))
|
-cf::tag("+")
>> cf::record_while(|c: &char| c.is_digit(10), 1..)
>> (|s: &str| End::Add(s.parse::<usize>().unwrap()))
)
>> (|(i, end)| match end {
End::Repeat(s) => (0..i).fold("".to_owned(), |acc, _| acc + &s),
End::Add(j) => (i + j).to_string()
})
);
assert_eq!(parser.parse("3 abc"), Ok("abcabcabc".to_owned()));
assert_eq!(parser.parse("10 x"), Ok("xxxxxxxxxx".to_owned()));
assert_eq!(parser.parse("42+123"), Ok("165".to_owned()));
assert_eq!(parser.parse("42+abc"), Err(()));
assert_eq!(parser.parse("+123"), Err(()));