quil_rs/parser/
macros.rs

1// Copyright 2021 Rigetti Computing
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#[macro_export]
16macro_rules! expected_token {
17    ($input: expr, $actual:expr, $expected:expr) => {{
18        use $crate::parser::error::{InternalError, ParserErrorKind};
19        Err(nom::Err::Error(InternalError::from_kind(
20            $input,
21            ParserErrorKind::ExpectedToken {
22                actual: $actual.clone(),
23                expected: $expected,
24            },
25        )))
26    }};
27}
28
29#[macro_export]
30macro_rules! token {
31    ($expected_variant: ident($enm:ident::$variant:ident)) => {{
32        use $crate::parser::error::{InternalError, ParserErrorKind};
33        use $crate::parser::lexer::$enm;
34        use $crate::parser::lexer::Token;
35        move |input: ParserInput<'a>| match $crate::parser::split_first_token(input) {
36            None => Err(nom::Err::Error(InternalError::from_kind(
37                input,
38                ParserErrorKind::UnexpectedEOF("something else"),
39            ))),
40            Some((Token::$expected_variant($enm::$variant), remainder)) => Ok((remainder, ())),
41            Some((other_token, _)) => {
42                $crate::expected_token!(
43                    input,
44                    other_token,
45                    stringify!($expected_variant).to_owned()
46                )
47            }
48        }
49    }};
50    ($expected_variant: ident($contents: ident)) => {{
51        use $crate::parser::error::{InternalError, ParserErrorKind};
52        use $crate::parser::lexer::Token;
53        move |input: ParserInput<'a>| match $crate::parser::split_first_token(input) {
54            None => Err(nom::Err::Error(InternalError::from_kind(
55                input,
56                ParserErrorKind::UnexpectedEOF("something else"),
57            ))),
58            Some((Token::$expected_variant($contents), remainder)) => {
59                Ok((remainder, $contents.clone()))
60            }
61            Some((other_token, _)) => {
62                $crate::expected_token!(
63                    input,
64                    other_token,
65                    stringify!($expected_variant).to_owned()
66                )
67            }
68        }
69    }};
70    ($expected_variant: ident) => {{
71        use $crate::parser::error::{InternalError, ParserErrorKind};
72        use $crate::parser::lexer::Token;
73        move |input: ParserInput<'a>| match $crate::parser::split_first_token(input) {
74            None => Err(nom::Err::Error(InternalError::from_kind(
75                input,
76                ParserErrorKind::UnexpectedEOF("something else"),
77            ))),
78            Some((Token::$expected_variant, remainder)) => Ok((remainder, ())),
79            Some((other_token, _)) => {
80                $crate::expected_token!(
81                    input,
82                    other_token,
83                    stringify!($expected_variant).to_owned()
84                )
85            }
86        }
87    }};
88}
89
90#[macro_export]
91macro_rules! unexpected_eof {
92    ($input: expr) => {{
93        use $crate::parser::error::{InternalError, ParserErrorKind};
94        Err(nom::Err::Error(InternalError::from_kind(
95            $input,
96            ParserErrorKind::UnexpectedEOF("something else"),
97        )))
98    }};
99}
100
101#[macro_export]
102macro_rules! make_test {
103    ($name: ident, $parser: ident, $input: expr, $expected: expr) => {
104        #[test]
105        fn $name() {
106            let input = ::nom_locate::LocatedSpan::new($input);
107            let tokens = lex(input).unwrap();
108            let (remainder, parsed) = $parser(&tokens).unwrap();
109            assert_eq!(remainder.len(), 0, "tokens left over");
110            assert_eq!(parsed, $expected);
111        }
112    };
113}