Newer
Older
pub mod macros;
#[cfg(test)]
mod tests {
use core::panic;
use crate::combinators::common::characters::Char;
use crate::parser::Parser;
#[test]
fn test_parser() -> Result<(), String> {
let p = Char {c: 'h'};
match parser!((p)).parse("he") {
Ok(c) => assert_eq!(c, 'h'),
Err(e) => panic!("{}", e)
}
match parser!(p).parse("he") {
Ok(c) => assert_eq!(c, 'h'),
Err(e) => panic!("{}", e)
}
match parser!(((p))).parse("he") {
Ok(c) => assert_eq!(c, 'h'),
Err(e) => panic!("{}", e)
}
#[test]
fn test_pure() -> Result<(), String>{
match parser!(pure 1).parse("c") {
Ok(_c) => (),
Err(e) => panic!("{}", e)
}
// match parser!(pure (1 + 1)).parse("c") {
// Ok(_c) => (),
// Err(e) => panic!("{}", e)
// }
match parser!((pure (false))).parse("c") {
Ok(_c) => (),
Err(e) => panic!("{}", e)
}
match parser!((pure 'l')).parse("c") {
Ok(_c) => (),
Err(e) => panic!("{}", e)
}
match parser!(pure 1).parse("c") {
Ok(_c) => Ok(()),
Err(e) => panic!("{}", e)
}
}
#[test]
fn test_empty() -> Result<(), String>{
match parser!(empty).parse("c") {
Ok(e) => panic!("{}", e),
Err(_s) => ()
}
match parser!(empty <* empty).parse("c") {
Ok(e) => panic!("{}", e),
Err(_s) => Ok(())
}
}
#[test]
fn test_sat() -> Result<(), String>{
let f = |c:char| c == 'k';
match parser!((sat (f))).parse("kb") {
Ok(c) => assert_eq!(c, 'k'),
Err(e) => panic!("{}", e)
}
match parser!((sat f)).parse("kb") {
Ok(c) => assert_eq!(c, 'k'),
Err(e) => panic!("{}", e)
}
match parser!(sat (f)).parse("kb") {
Ok(c) => assert_eq!(c, 'k'),
Err(e) => panic!("{}", e)
}
let f = |c:char| c == 'k';
match parser!(sat f).parse("kb") {
Ok(c) => {
assert_eq!(c, 'k');
Ok(())
},
Err(e) => panic!("{}", e)
}
}
#[test]
fn test_char() -> Result<(), String> {
match parser!('h').parse("he") {
Ok(c) => assert_eq!(c, 'h'),
Err(e) => panic!("{}", e)
}
match parser!(('h')).parse("he") {
Ok(c) => assert_eq!(c, 'h'),
Err(e) => panic!("{}", e)
}
let p = Char {c: 'h'};
match parser!((p)).parse("he") {
Ok(c) => assert_eq!(c, 'h'),
Err(e) => panic!("{}", e)
}
fn test_zip_base() -> Result<(), String>{
// Only literals
match parser!('c'<~>'x').parse("cx") {
Ok((c1, c2)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
},
Err(e) => panic!("{}", e)
}
match parser!(('c'<~>'x')).parse("cx") {
Ok((c1, c2)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
},
Err(e) => panic!("{}", e)
}
// Only idents
let p = Char {c: 'c'};
match parser!(p <~> p2).parse("cx") {
Ok((c1, c2)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'c'};
let p2 = Char {c: 'x'};
match parser!((p) <~> p2).parse("cx") {
Ok((c1, c2)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'c'};
let p2 = Char {c: 'x'};
match parser!(p <~> (p2)).parse("cx") {
Ok((c1, c2)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'c'};
match parser!((p) <~> (p2)).parse("cx") {
Ok((c1, c2)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
},
Err(e) => panic!("{}", e)
}
// Combining idents and literals
let p = Char {c: 'x'};
match parser!('c' <~> p).parse("cx") {
Ok((c1, c2)) => {
assert_eq!(c1, 'c');
},
Err(e) => panic!("{}", e)
}
match parser!(p <~>'x').parse("cx") {
Ok((c1, c2)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
},
Err(e) => panic!("{}", e)
match parser!((p)<~>'x').parse("cx") {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'x'};
match parser!('c'<~>(p)).parse("cx") {
Ok((c1, c2)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
Ok(())
},
Err(e) => panic!("{}", e)
}
}
fn test_zip_recursive() -> Result<(), String>{
match parser!(('c'<~>'x') <~> 'k').parse("cxk") {
Ok(((c1, c2), c3)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
assert_eq!(c3, 'k');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'k'};
match parser!(('c'<~>'x') <~> p).parse("cxk") {
Ok(((c1, c2), c3)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
assert_eq!(c3, 'k');
},
Err(e) => panic!("{}", e)
}
match parser!('c'<~> ('x' <~> 'k')).parse("cxk") {
Ok((c1, (c2, c3))) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
assert_eq!(c3, 'k');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'c'};
match parser!(p <~> ('x' <~> 'k')).parse("cxk") {
Ok((c1, (c2, c3))) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
assert_eq!(c3, 'k');
},
Err(e) => panic!("{}", e)
}
match parser!(p <~> ('x' <~> ('k' <~> 'p'))).parse("cxkp") {
Ok((c1, (c2, (c3, c4)))) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
assert_eq!(c3, 'k');
assert_eq!(c4, 'p');
},
match parser!('c' <~> 'x' <~> ('k')).parse("cxk") {
Ok(((c1, c2), c3)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
assert_eq!(c3, 'k');
},
match parser!('c' <~> 'x' <~> 'k').parse("cxk") {
Ok(((c1, c2), c3)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
assert_eq!(c3, 'k');
},
Err(e) => panic!("{}", e)
match parser!(p <~> 'x' <~> 'k').parse("cxk") {
Ok(((c1, c2), c3)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
assert_eq!(c3, 'k');
match parser!('c' <~> p <~> 'k').parse("cxk") {
Ok(((c1, c2), c3)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
assert_eq!(c3, 'k');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'c'};
let p2 = Char {c: 'x'};
match parser!(p <~> p2 <~> 'k').parse("cxk") {
Ok(((c1, c2), c3)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
assert_eq!(c3, 'k');
},
Err(e) => panic!("{}", e)
}
match parser!('c' <~> ('x' <~> 'k') <~> 'r').parse("cxkr") {
Ok(((c1, (c2, c3)), c4)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
assert_eq!(c3, 'k');
assert_eq!(c4, 'r');
},
Err(e) => panic!("{}", e)
}
match parser!(('c' <~> 'x') <~> 'k' <~> 'r').parse("cxkr") {
Ok((((c1, c2), c3), c4)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
assert_eq!(c3, 'k');
assert_eq!(c4, 'r');
},
Err(e) => panic!("{}", e)
}
match parser!(('c' <~> 'x') <~> ('k' <~> 'r') <~> 'm').parse("cxkrm") {
Ok((((c1, c2), (c3, c4)), c5)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
assert_eq!(c3, 'k');
assert_eq!(c4, 'r');
assert_eq!(c5, 'm');
},
Err(e) => panic!("{}", e)
}
match parser!(('c' <~> 'x') <~> ('k' <~> 'r') <~> 'm').parse("cxkrm") {
Ok((((c1, c2), (c3, c4)), c5)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
assert_eq!(c3, 'k');
assert_eq!(c4, 'r');
assert_eq!(c5, 'm');
},
Err(e) => panic!("{}", e)
}
// Not fully covered, but essentially right associativity with idents
let p = Char {c:'k'};
match parser!(('c' <~> 'x') <~> p <~> 'm').parse("cxkm") {
Ok((((c1, c2), c3), c4)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'x');
assert_eq!(c3, 'k');
assert_eq!(c4, 'm');
},
Err(e) => panic!("{}", e)
}
Ok(())
fn test_alternative_base() -> Result<(), String>{
// Only literals
match parser!('c'<|>'x').parse("cx") {
Ok(c1) => {
assert_eq!(c1, 'c');
},
Err(e) => panic!("{}", e)
}
match parser!(('c'<|>'x')).parse("x") {
Ok(c1) => {
assert_eq!(c1, 'x');
},
Err(e) => panic!("{}", e)
}
// Only idents
match parser!(p <|> p2).parse("cx") {
Ok(c1) => {
assert_eq!(c1, 'c');
},
let p = Char {c: 'c'};
let p2 = Char {c: 'x'};
match parser!((p) <|> p2).parse("cx") {
Ok(c1) => {
assert_eq!(c1, 'c');
},
let p = Char {c: 'c'};
let p2 = Char {c: 'x'};
match parser!(p <|> (p2)).parse("cx") {
Ok(c1) => {
assert_eq!(c1, 'c');
},
Err(e) => panic!("{}", e)
let p = Char {c: 'c'};
let p2 = Char {c: 'x'};
match parser!(p <|> (p2)).parse("cx") {
Ok(c1) => {
assert_eq!(c1, 'c');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'c'};
let p2 = Char {c: 'x'};
match parser!((p) <|> (p2)).parse("cx") {
Ok(c1) => {
assert_eq!(c1, 'c');
},
Err(e) => panic!("{}", e)
}
// Combining idents and literals
let p = Char {c: 'x'};
match parser!('k' <|> p).parse("x") {
Ok(c1) => {
assert_eq!(c1, 'x');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'c'};
match parser!(p <|>'x').parse("cx") {
Ok(c1) => {
assert_eq!(c1, 'c');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'c'};
match parser!((p)<|>'x').parse("cx") {
Ok(c1) => {
assert_eq!(c1, 'c');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'x'};
match parser!('c'<|>(p)).parse("cx") {
Ok(c1) => {
assert_eq!(c1, 'c');
Ok(())
},
Err(e) => panic!("{}", e)
}
}
fn test_alternative_recursive() -> Result<(), String>{
match parser!(('c'<|>'x') <|> 'k').parse("cxk") {
Ok(c) => {
assert_eq!(c, 'c');
},
match parser!(('c'<|>'x') <|> p).parse("cxk") {
Ok(c) => {
assert_eq!(c, 'c');
},
Err(e) => panic!("{}", e)
}
match parser!('c'<|> ('x' <|> 'k')).parse("cxk") {
Ok(c) => {
assert_eq!(c, 'c');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'c'};
match parser!(p <|> ('x' <|> 'k')).parse("cxk") {
Ok(c) => {
assert_eq!(c, 'c');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'c'};
match parser!(p <|> ('x' <|> ('k' <|> 'p'))).parse("cxkp") {
Ok(c) => {
assert_eq!(c, 'c');
},
Err(e) => panic!("{}", e)
}
// Right associativity
match parser!('c' <|> 'x' <|> ('k')).parse("cxk") {
Ok(c) => {
assert_eq!(c, 'c');
},
Err(e) => panic!("{}", e)
}
match parser!('c' <|> 'x' <|> 'k').parse("cxk") {
Ok(c) => {
assert_eq!(c, 'c');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'c'};
match parser!(p <|> 'x' <|> 'k').parse("cxk") {
Ok(c) => {
assert_eq!(c, 'c');
},
match parser!('c' <|> p <|> 'k').parse("cxk") {
Ok(c) => {
assert_eq!(c, 'c');
},
let p = Char {c: 'c'};
let p2 = Char {c: 'x'};
match parser!(p <|> p2 <|> 'k').parse("cxk") {
Ok(c) => {
assert_eq!(c, 'c');
},
match parser!('c' <|> ('x' <|> 'k') <|> 'r').parse("cxkr") {
Ok(c) => {
assert_eq!(c, 'c');
},
match parser!(('c' <|> 'x') <|> 'k' <|> 'r').parse("cxkr") {
Ok(c) => {
assert_eq!(c, 'c');
},
match parser!(('c' <|> 'x') <|> ('k' <|> 'r') <|> 'm').parse("cxkrm") {
Ok(c) => {
assert_eq!(c, 'c');
},
match parser!(('c' <|> 'x') <|> ('k' <|> 'r') <|> 'm').parse("cxkrm") {
Ok(c) => {
assert_eq!(c, 'c');
},
// Not fully covered, but essentially right associativity with idents
let p = Char {c:'k'};
match parser!(('c' <|> 'x') <|> p <|> 'm').parse("cxkm") {
Ok(c) => {
assert_eq!(c, 'c');
},
Ok(())
}
#[test]
fn test_alternative_zip() -> Result<(), String> {
match parser!(p <|> 'b' <~> 'c').parse("ac") {
assert_eq!(c2, 'c');
},
Err(e) => panic!("{}", e)
}
let p = parser!('a' <~> 'c');
let p2 = Char {c: 'b'};
match parser!(p <|> p2 <~> 'c').parse("bc") {
Ok((c1, c2)) => {
assert_eq!(c1, 'b');
assert_eq!(c2, 'c');
},
match parser!(p <|> ('a' <|> 'b') <~> 'c').parse("bc") {
Ok((c1, c2)) => {
assert_eq!(c1, 'b');
assert_eq!(c2, 'c');
},
match parser!(('a' <~> 'b') <|> p <~> 'c').parse("bc") {
Ok((c1, c2)) => {
assert_eq!(c1, 'b');
assert_eq!(c2, 'c');
},
match parser!(('a' <~> 'b') <|> 'b' <~> 'c').parse("bc") {
Ok((c1, c2)) => {
assert_eq!(c1, 'b');
assert_eq!(c2, 'c');
match parser!(('a' <~> 'b') <|> ('b' <|> 'k') <~> 'c').parse("bc") {
Ok((c1, c2)) => {
assert_eq!(c1, 'b');
assert_eq!(c2, 'c');
#[test]
fn test_zip_alternative() -> Result<(), String> {
let p = parser!('c' <~> 'd');
match parser!('a' <~> 'b' <|> p).parse("ab") {
Ok((c1, c2)) => {
assert_eq!(c1, 'a');
assert_eq!(c2, 'b');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'a'};
let p2 = parser!('c' <~> 'd');
match parser!(p <~> 'b' <|> p2).parse("cd") {
Ok((c1, c2)) => {
assert_eq!(c1, 'c');
assert_eq!(c2, 'd');
},
Err(e) => panic!("{}", e)
let p = Char {c: 'b'};
let p2 = parser!('c' <~> 'd');
match parser!('a' <~> p <|> p2).parse("ab") {
Ok((c1, c2)) => {
assert_eq!(c1, 'a');
assert_eq!(c2, 'b');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'a'};
let p2 = Char {c: 'b'};
let p3 = parser!('c' <~> 'd');
match parser!(p <~> p2 <|> p3).parse("ab") {
Ok((c1, c2)) => {
assert_eq!(c1, 'a');
assert_eq!(c2, 'b');
},
Err(e) => panic!("{}", e)
}
let p = parser!('c' <~> 'd');
match parser!('a' <~> ('a' <|> 'b') <|> p).parse("ab") {
Ok((c1, c2)) => {
assert_eq!(c1, 'a');
assert_eq!(c2, 'b');
},
Err(e) => panic!("{}", e)
}
let p = parser!('c' <~> 'd');
match parser!(('a' <|> 'b') <~> 'a' <|> p).parse("ba") {
Ok((c1, c2)) => {
assert_eq!(c1, 'b');
assert_eq!(c2, 'a');
},
Err(e) => panic!("{}", e)
}
let p1 = parser!('a');
let p2 = parser!('c' <~> 'd');
match parser!(p1 <~> ('a' <|> 'b') <|> p2).parse("aa") {
Ok((c1, c2)) => {
assert_eq!(c1, 'a');
assert_eq!(c2, 'a');
},
Err(e) => panic!("{}", e)
}
let p1 = parser!('a');
let p2 = parser!('c' <~> 'd');
match parser!(('a' <|> 'b') <~> p1 <|> p2).parse("ba") {
Ok((c1, c2)) => {
assert_eq!(c1, 'b');
assert_eq!(c2, 'a');
},
Err(e) => panic!("{}", e)
}
let p3 = parser!('c' <~> 'd');
match parser!(('a' <|> 'b') <~> ('b' <|> 'a') <|> p3).parse("ab") {
Ok((c1, c2)) => {
assert_eq!(c1, 'a');
assert_eq!(c2, 'b');
},
Err(e) => panic!("{}", e)
}
#[test]
fn test_thern_r_base() -> Result<(), String> {
// Only literals
match parser!('c'*>'x').parse("cx") {
Ok(c1) => assert_eq!(c1, 'x'),
Err(e) => panic!("{}", e)
}
match parser!(('c'*>'x')).parse("cx") {
Ok(c1) => {
assert_eq!(c1, 'x');
},
Err(e) => panic!("{}", e)
}
// Only idents
let p = Char {c: 'c'};
let p2 = Char {c: 'x'};
match parser!(p *> p2).parse("cx") {
Ok(c1) => {
assert_eq!(c1, 'x');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'c'};
let p2 = Char {c: 'x'};
match parser!((p) *> p2).parse("cx") {
Ok(c1) => {
assert_eq!(c1, 'x');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'c'};
let p2 = Char {c: 'x'};
match parser!(p *> (p2)).parse("cx") {
Ok(c1) => {
assert_eq!(c1, 'x');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'c'};
let p2 = Char {c: 'x'};
match parser!((p) *> (p2)).parse("cx") {
Ok(c1) => {
assert_eq!(c1, 'x');
},
Err(e) => panic!("{}", e)
}
// Combining idents and literals
let p = Char {c: 'x'};
match parser!('k' *> p).parse("kx") {
Ok(c1) => {
assert_eq!(c1, 'x');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'c'};
match parser!(p *>'x').parse("cx") {
Ok(c1) => {
assert_eq!(c1, 'x');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'c'};
match parser!((p)*>'x').parse("cx") {
Ok(c1) => {
assert_eq!(c1, 'x');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'x'};
match parser!('c'*>(p)).parse("cx") {
Ok(c1) => {
assert_eq!(c1, 'x');
},
Err(e) => panic!("{}", e)
}
let p = parser!('c' <|> 'a');
let p2 = parser!('c' <|> 'a');
match parser!((p)*> p2).parse("ca") {
Ok(c1) => {
assert_eq!(c1, 'a');
Ok(())
},
Err(e) => panic!("{}", e)
}
}
#[test]
fn test_then_r_recursive() -> Result<(), String>{
match parser!(('c'*>'x') *> 'k').parse("cxk") {
Ok(c) => {
assert_eq!(c, 'k');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'k'};
match parser!(('c'*>'x') *> p).parse("cxk") {
Ok(c) => {
assert_eq!(c, 'k');
},
Err(e) => panic!("{}", e)
}
match parser!('c'*> ('x' *> 'k')).parse("cxk") {
Ok(c) => {
assert_eq!(c, 'k');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'c'};
match parser!(p *> ('x' *> 'k')).parse("cxk") {
Ok(c) => {
assert_eq!(c, 'k');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'c'};
match parser!(p *> ('x' *> ('k' *> 'p'))).parse("cxkp") {
Ok(c) => {
assert_eq!(c, 'p');
},
Err(e) => panic!("{}", e)
}
// Right associativity
match parser!('c' *> 'x' *> ('k')).parse("cxk") {
Ok(c) => {
assert_eq!(c, 'k');
},
Err(e) => panic!("{}", e)
}
match parser!('c' *> 'x' *> 'k').parse("cxk") {
Ok(c) => {
assert_eq!(c, 'k');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'c'};
match parser!(p *> 'x' *> 'k').parse("cxk") {
Ok(c) => {
assert_eq!(c, 'k');
},
Err(e) => panic!("{}", e)
}
let p = Char {c: 'x'};
match parser!('c' *> p *> 'k').parse("cxk") {