Skip to content

Commit 3ff700e

Browse files
orpuente-MSidavis
authored andcommitted
Implement OpenQASM 3 lexer (#2129)
This PR adds our own implementation of an OpenQASM3 parser to the `compiler/qsc_qasm3` directory.
1 parent e0df7cc commit 3ff700e

File tree

9 files changed

+3509
-2
lines changed

9 files changed

+3509
-2
lines changed

Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compiler/qsc_qasm3/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ version.workspace = true
99

1010
[dependencies]
1111
bitflags = { workspace = true }
12+
enum-iterator = { workspace = true }
1213
num-bigint = { workspace = true }
1314
miette = { workspace = true }
1415
qsc_ast = { path = "../qsc_ast" }
@@ -20,7 +21,6 @@ thiserror = { workspace = true }
2021
oq3_source_file = { workspace = true }
2122
oq3_syntax = { workspace = true }
2223
oq3_parser = { workspace = true }
23-
oq3_lexer = { workspace = true }
2424
oq3_semantics = { workspace = true }
2525

2626
[dev-dependencies]

compiler/qsc_qasm3/src/keyword.rs

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
use enum_iterator::Sequence;
5+
use std::{
6+
fmt::{self, Display, Formatter},
7+
str::FromStr,
8+
};
9+
10+
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Sequence)]
11+
pub enum Keyword {
12+
Box,
13+
Break,
14+
Cal,
15+
Case,
16+
Continue,
17+
Def,
18+
Default,
19+
Defcalgrammar,
20+
Else,
21+
End,
22+
Extern,
23+
For,
24+
Gate,
25+
If,
26+
In,
27+
Include,
28+
Let,
29+
OpenQASM,
30+
Pragma,
31+
Return,
32+
Switch,
33+
While,
34+
}
35+
36+
impl Keyword {
37+
pub(super) fn as_str(self) -> &'static str {
38+
match self {
39+
Keyword::Box => "box",
40+
Keyword::Break => "break",
41+
Keyword::Cal => "cal",
42+
Keyword::Case => "case",
43+
Keyword::Continue => "continue",
44+
Keyword::Def => "def",
45+
Keyword::Default => "default",
46+
Keyword::Defcalgrammar => "defcalgrammar",
47+
Keyword::Else => "else",
48+
Keyword::End => "end",
49+
Keyword::Extern => "extern",
50+
Keyword::For => "for",
51+
Keyword::Gate => "gate",
52+
Keyword::If => "if",
53+
Keyword::In => "in",
54+
Keyword::Include => "include",
55+
Keyword::Let => "let",
56+
Keyword::OpenQASM => "openqasm",
57+
Keyword::Pragma => "pragma",
58+
Keyword::Return => "return",
59+
Keyword::Switch => "switch",
60+
Keyword::While => "while",
61+
}
62+
}
63+
}
64+
65+
impl Display for Keyword {
66+
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
67+
f.write_str(self.as_str())
68+
}
69+
}
70+
71+
impl FromStr for Keyword {
72+
type Err = ();
73+
74+
// This is a hot function. Use a match expression so that the Rust compiler
75+
// can optimize the string comparisons better, and order the cases by
76+
// frequency in Q# so that fewer comparisons are needed on average.
77+
fn from_str(s: &str) -> Result<Self, Self::Err> {
78+
match s {
79+
"box" => Ok(Self::Box),
80+
"break" => Ok(Self::Break),
81+
"cal" => Ok(Self::Cal),
82+
"case" => Ok(Self::Case),
83+
"continue" => Ok(Self::Continue),
84+
"def" => Ok(Self::Def),
85+
"default" => Ok(Self::Default),
86+
"defcalgrammar" => Ok(Self::Defcalgrammar),
87+
"else" => Ok(Self::Else),
88+
"end" => Ok(Self::End),
89+
"extern" => Ok(Self::Extern),
90+
"for" => Ok(Self::For),
91+
"gate" => Ok(Self::Gate),
92+
"if" => Ok(Self::If),
93+
"in" => Ok(Self::In),
94+
"include" => Ok(Self::Include),
95+
"let" => Ok(Self::Let),
96+
"openqasm" => Ok(Self::OpenQASM),
97+
"pragma" => Ok(Self::Pragma),
98+
"return" => Ok(Self::Return),
99+
"switch" => Ok(Self::Switch),
100+
"while" => Ok(Self::While),
101+
_ => Err(()),
102+
}
103+
}
104+
}

compiler/qsc_qasm3/src/lex.rs

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
#![allow(unused)]
4+
5+
pub mod cooked;
6+
pub mod raw;
7+
use enum_iterator::Sequence;
8+
9+
pub(super) use cooked::{Error, Lexer, Token, TokenKind};
10+
11+
/// A delimiter token.
12+
#[derive(Clone, Copy, Debug, Eq, PartialEq, Sequence)]
13+
pub enum Delim {
14+
/// `{` or `}`
15+
Brace,
16+
/// `[` or `]`
17+
Bracket,
18+
/// `(` or `)`
19+
Paren,
20+
}
21+
22+
#[derive(Clone, Copy, Debug, Eq, PartialEq, Sequence)]
23+
pub enum Radix {
24+
Binary,
25+
Octal,
26+
Decimal,
27+
Hexadecimal,
28+
}
29+
30+
impl From<Radix> for u32 {
31+
fn from(value: Radix) -> Self {
32+
match value {
33+
Radix::Binary => 2,
34+
Radix::Octal => 8,
35+
Radix::Decimal => 10,
36+
Radix::Hexadecimal => 16,
37+
}
38+
}
39+
}
40+
41+
#[derive(Clone, Copy, Debug, Eq, PartialEq, Sequence)]
42+
pub enum InterpolatedStart {
43+
DollarQuote,
44+
RBrace,
45+
}
46+
47+
#[derive(Clone, Copy, Debug, Eq, PartialEq, Sequence)]
48+
pub enum InterpolatedEnding {
49+
Quote,
50+
LBrace,
51+
}

0 commit comments

Comments
 (0)