1use crate::instruction::QuotedString;
2use crate::parser::lexer::{Command, DataType, LexInput, LexResult, Modifier, Operator};
3use std::fmt;
4use std::fmt::Formatter;
5
6#[derive(Debug, Clone, PartialEq)]
8pub struct TokenWithLocation<'a> {
9 token: Token,
10 original_input: LexInput<'a>,
11}
12
13impl PartialEq<Token> for TokenWithLocation<'_> {
14 fn eq(&self, other: &Token) -> bool {
15 &self.token == other
16 }
17}
18
19impl TokenWithLocation<'_> {
20 pub fn as_token(&self) -> &Token {
22 &self.token
23 }
24
25 pub fn into_token(self) -> Token {
27 self.token
28 }
29
30 pub fn line(&self) -> u32 {
32 self.original_input.location_line()
33 }
34
35 pub fn column(&self) -> usize {
37 self.original_input.get_utf8_column()
38 }
39}
40
41impl nom::InputLength for TokenWithLocation<'_> {
42 fn input_len(&self) -> usize {
43 self.as_token().input_len()
45 }
46}
47
48pub(crate) fn token_with_location<'i, E, P>(
50 mut parser: P,
51) -> impl FnMut(LexInput<'i>) -> LexResult<'i, TokenWithLocation<'i>, E>
52where
53 P: nom::Parser<LexInput<'i>, Token, E>,
54 E: nom::error::ParseError<LexInput<'i>>,
55{
56 move |input| {
57 parser.parse(input).map(|(leftover, token)| {
59 (
60 leftover,
61 TokenWithLocation {
62 token,
63 original_input: input,
64 },
65 )
66 })
67 }
68}
69
70#[derive(Debug, Copy, Clone, PartialEq, Eq, strum::Display, strum::EnumString)]
73#[strum(serialize_all = "SCREAMING-KEBAB-CASE")]
74pub enum KeywordToken {
75 As,
76 Matrix,
77 #[strum(serialize = "mut")]
78 Mutable,
79 #[strum(serialize = "NONBLOCKING")]
80 NonBlocking,
81 Offset,
82 PauliSum,
83 Permutation,
84 Sharing,
85}
86
87impl From<KeywordToken> for Token {
88 fn from(token: KeywordToken) -> Self {
89 match token {
90 KeywordToken::As => Token::As,
91 KeywordToken::Matrix => Token::Matrix,
92 KeywordToken::Mutable => Token::Mutable,
93 KeywordToken::NonBlocking => Token::NonBlocking,
94 KeywordToken::Offset => Token::Offset,
95 KeywordToken::PauliSum => Token::PauliSum,
96 KeywordToken::Permutation => Token::Permutation,
97 KeywordToken::Sharing => Token::Sharing,
98 }
99 }
100}
101
102impl TryFrom<Token> for KeywordToken {
103 type Error = ();
104
105 fn try_from(token: Token) -> Result<Self, Self::Error> {
106 #[deny(clippy::wildcard_enum_match_arm, clippy::wildcard_in_or_patterns)]
109 match token {
110 Token::As => Ok(KeywordToken::As),
111 Token::Matrix => Ok(KeywordToken::Matrix),
112 Token::Mutable => Ok(KeywordToken::Mutable),
113 Token::Offset => Ok(KeywordToken::Offset),
114 Token::PauliSum => Ok(KeywordToken::PauliSum),
115 Token::Permutation => Ok(KeywordToken::Permutation),
116 Token::Sharing => Ok(KeywordToken::Sharing),
117
118 Token::Colon
119 | Token::Comma
120 | Token::Command(_)
121 | Token::Comment(_)
122 | Token::DataType(_)
123 | Token::Float(_)
124 | Token::Identifier(_)
125 | Token::Indentation
126 | Token::Integer(_)
127 | Token::Target(_)
128 | Token::LBracket
129 | Token::LParenthesis
130 | Token::NonBlocking
131 | Token::Modifier(_)
132 | Token::NewLine
133 | Token::Operator(_)
134 | Token::RBracket
135 | Token::RParenthesis
136 | Token::Semicolon
137 | Token::String(_)
138 | Token::Variable(_) => Err(()),
139 }
140 }
141}
142
143#[derive(Clone, PartialEq)]
144pub enum Token {
145 As,
146 Colon,
147 Comma,
148 Command(Command),
149 Comment(String),
150 DataType(DataType),
151 Float(f64),
152 Identifier(String),
153 Indentation,
154 Integer(u64),
155 Target(String),
156 LBracket,
157 LParenthesis,
158 NonBlocking,
159 Matrix,
160 Modifier(Modifier),
161 Mutable,
162 NewLine,
163 Operator(Operator),
164 Offset,
165 PauliSum,
166 Permutation,
167 RBracket,
168 RParenthesis,
169 Semicolon,
170 Sharing,
171 String(String),
172 Variable(String),
173}
174
175impl fmt::Display for Token {
176 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
177 match self {
178 Token::As => write!(f, "{}", KeywordToken::As),
179 Token::Colon => write!(f, ":"),
180 Token::Comma => write!(f, ","),
181 Token::Command(cmd) => write!(f, "{cmd}"),
182 Token::Comment(comment) => write!(f, "# {comment}"),
183 Token::DataType(typ) => write!(f, "{typ}"),
184 Token::Float(float) => write!(f, "{float}"),
185 Token::Identifier(ident) => write!(f, "{ident}"),
186 Token::Indentation => write!(f, " "),
187 Token::Integer(i) => write!(f, "{i}"),
188 Token::Target(label) => write!(f, "{label}"),
189 Token::LBracket => write!(f, "["),
190 Token::LParenthesis => write!(f, "("),
191 Token::NonBlocking => write!(f, "{}", KeywordToken::NonBlocking),
192 Token::Matrix => write!(f, "{}", KeywordToken::Matrix),
193 Token::Modifier(m) => write!(f, "{m}"),
194 Token::Mutable => write!(f, "{}", KeywordToken::Mutable),
195 Token::NewLine => write!(f, "NEWLINE"),
196 Token::Operator(op) => write!(f, "{op}"),
197 Token::Offset => write!(f, "{}", KeywordToken::Offset),
198 Token::PauliSum => write!(f, "{}", KeywordToken::PauliSum),
199 Token::Permutation => write!(f, "{}", KeywordToken::Permutation),
200 Token::RBracket => write!(f, "]"),
201 Token::RParenthesis => write!(f, ")"),
202 Token::Semicolon => write!(f, ";"),
203 Token::Sharing => write!(f, "{}", KeywordToken::Sharing),
204 Token::String(s) => write!(f, "{}", QuotedString(s)),
205 Token::Variable(v) => write!(f, "{v}"),
206 }
207 }
208}
209
210impl fmt::Debug for Token {
211 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
212 match self {
213 Token::As => write!(f, "{self}"),
214 Token::Colon => write!(f, "COLON"),
215 Token::Comma => write!(f, "COMMA"),
216 Token::Command(cmd) => write!(f, "COMMAND({cmd})"),
217 Token::Comment(comment) => write!(f, "COMMENT({comment:?})"),
218 Token::DataType(typ) => write!(f, "DATATYPE({typ})"),
219 Token::Float(float) => write!(f, "FLOAT({float})"),
220 Token::Identifier(id) => write!(f, "IDENTIFIER({id})"),
221 Token::Indentation => write!(f, "INDENT"),
222 Token::Integer(i) => write!(f, "INTEGER({i})"),
223 Token::Target(label) => write!(f, "@{label}"),
224 Token::LBracket => write!(f, "LBRACKET"),
225 Token::LParenthesis => write!(f, "LPAREN"),
226 Token::NonBlocking => write!(f, "{self}"),
227 Token::Matrix => write!(f, "{self}"),
228 Token::Modifier(m) => write!(f, "MODIFIER({m})"),
229 Token::Mutable => write!(f, "{self}"),
230 Token::NewLine => write!(f, "NEWLINE"),
231 Token::Operator(op) => write!(f, "OPERATOR({op})"),
232 Token::Offset => write!(f, "{self}"),
233 Token::PauliSum => write!(f, "{self}"),
234 Token::Permutation => write!(f, "{self}"),
235 Token::RBracket => write!(f, "RBRACKET"),
236 Token::RParenthesis => write!(f, "RPAREN"),
237 Token::Semicolon => write!(f, "SEMICOLON"),
238 Token::Sharing => write!(f, "{self}"),
239 Token::String(s) => write!(f, "STRING({s:?})"),
240 Token::Variable(v) => write!(f, "VARIABLE({v})"),
241 }
242 }
243}
244
245impl nom::InputLength for Token {
246 fn input_len(&self) -> usize {
247 1
249 }
250}