open_pql/range_parser/
mod.rs

1use std::convert::From;
2
3use ast::Expr;
4pub use error::Error;
5use error::{LalrError, ResultE};
6use lalrpop_util::{ParseError, lalrpop_mod, lexer::Token};
7
8use crate::{Loc, LocInfo};
9
10pub mod ast;
11mod error;
12
13lalrpop_mod!(
14    #[allow(clippy::empty_line_after_outer_attr)]
15    #[allow(clippy::iter_nth_zero)]
16    #[allow(clippy::nursery)]
17    #[allow(clippy::pedantic)]
18    #[allow(clippy::restriction)]
19    #[allow(clippy::useless_conversion)]
20    parser,
21    "/range_parser/range.rs"
22);
23
24type Expected = Vec<String>;
25
26pub fn parse(src: &str) -> Result<Box<Expr>, Error> {
27    Ok(parser::ExprParser::new().parse(src)?)
28}
29
30#[cfg(test)]
31pub mod tests {
32    use super::*;
33
34    pub fn parse_card(src: &str) -> ResultE<'_, ast::RangeCard> {
35        parser::RangeCardParser::new().parse(src)
36    }
37
38    pub fn parse_list(src: &str) -> ResultE<'_, ast::List> {
39        parser::ListParser::new().parse(src)
40    }
41
42    pub fn parse_span(src: &str) -> ResultE<'_, ast::Span> {
43        parser::SpanParser::new().parse(src)
44    }
45
46    pub fn parse_term(src: &str) -> ResultE<'_, ast::Term> {
47        parser::TermParser::new().parse(src)
48    }
49
50    fn assert_str_in(vec: &[String], val: &str) {
51        assert!(vec.contains(&format!("\"{val}\"")));
52    }
53
54    #[test]
55    fn test_error_invalid_token() {
56        assert_eq!(Error::InvalidToken((0, 1)), parse("?").unwrap_err());
57    }
58
59    #[test]
60    fn test_error_unrecognized_eof() {
61        let res = parse("[").unwrap_err();
62
63        if let Error::UnrecognizedEof(loc, expected) = res {
64            assert_eq!(loc, (1, 2));
65            assert_eq!(expected.len(), 3);
66
67            assert_str_in(&expected, "Suit");
68            assert_str_in(&expected, "Rank");
69            assert_str_in(&expected, "RankSuit");
70        } else {
71            panic!("Expected: UnrecognizedEof. Got: {res:?}")
72        }
73    }
74
75    #[test]
76    fn test_error_unrecognized_token() {
77        let res = parse("[,").unwrap_err();
78
79        if let Error::UnrecognizedToken(loc, expected) = res {
80            assert_eq!(loc, (1, 2));
81            assert_eq!(expected.len(), 3);
82
83            assert_str_in(&expected, "Suit");
84            assert_str_in(&expected, "Rank");
85            assert_str_in(&expected, "RankSuit");
86        } else {
87            panic!("Expected: UnrecognizedToken. Got: {res:?}")
88        }
89    }
90
91    #[test]
92    fn test_error() {
93        let err = LalrError::ExtraToken {
94            token: (0, Token(0, "a"), 1),
95        };
96
97        assert_eq!(Error::ExtraToken((0, 1)), err.into());
98
99        let err = LalrError::User {
100            error: Error::InvalidRank((0, 1)),
101        };
102
103        assert_eq!(Error::InvalidRank((0, 1)), err.into());
104    }
105}