1#[macro_export]
5macro_rules! reverse_parse_keywords {
6 ($(
7 $(#[$metas:meta])*
8 keywords $enum_name:ident
9 { $(
10 $string:literal -> $var:ident,
11 )*}
12 )*) => {
13 $(
14 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
15 $(#[$metas])*
16 pub enum $enum_name {
17 $(
18 $var,
19 )*
20 }
21
22 impl std::ops::Deref for $enum_name {
23 type Target = str;
24 fn deref(&self) -> &Self::Target {
25 match self {
26 $(Self::$var => $string,)*
27 }
28 }
29
30 }
31
32 impl std::fmt::Display for $enum_name {
33 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
34 f.write_str(self)
35 }
36 }
37
38 #[cfg(feature = "parse")]
39 impl terl::ReverseParseUnit<$crate::Token> for $enum_name {
40 type Left = $enum_name;
41 fn reverse_parse(&self, p:&mut terl::Parser<$crate::Token>) -> Result<$enum_name, terl::ParseError> {
42 use terl::WithSpanExt;
43
44 let Some(next) = p.next() else {
45 return p.unmatch(format!("expect {}, but non token left", self))
46 };
47
48 if &**next != &**self {
49 let msg = format!("expect {}, but {} was got", self, &**next);
50 return p.unmatch(msg)
51 }
52
53 Ok(*self)
54 }
55 }
56
57 )*
58
59
60 thread_local! {
61 pub static KEPPING_KEYWORDS: std::collections::HashSet<&'static str> = {
62 let mut set = std::collections::HashSet::<&'static str>::default();
63 $($(
64 set.insert($string);
65 )*)*
66 set
67 };
68 }
69 };
70}
71
72#[macro_export]
73macro_rules! front_parse_keywords {
74 ($(
75 $(#[$metas:meta])*
76 keywords $enum_name:ident
77 { $(
78 $string:literal -> $var:ident,
79 )*}
80 )*) => {
81 $crate::reverse_parse_keywords! {
82 $(
83 $(#[$metas])*
84 keywords $enum_name
85 { $(
86 $string -> $var,
87 )*}
88 )*
89 }
90 $(
91 $crate::parse_unit_impl! {
92 $(#[$metas])*
93 $enum_name
94 { $(
95 $string -> $var,
96 )*}
97 }
98 )*
99 }
100}