Skip to content

Commit 30fbb41

Browse files
orpuente-MSidavis
authored andcommitted
Implement Pratt Parsing for Qasm3 parser (#2166)
1 parent 158a5f5 commit 30fbb41

File tree

6 files changed

+952
-135
lines changed

6 files changed

+952
-135
lines changed

compiler/qsc_qasm3/src/ast.rs

Lines changed: 91 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ impl Display for MeasureExpr {
204204
}
205205
}
206206
/// A binary operator.
207-
#[derive(Clone, Debug)]
207+
#[derive(Clone, Copy, Debug)]
208208
pub enum BinOp {
209209
/// Addition: `+`.
210210
Add,
@@ -273,8 +273,8 @@ impl Display for BinOp {
273273
}
274274

275275
/// A unary operator.
276-
#[derive(Clone, Debug)]
277-
pub enum UnOp {
276+
#[derive(Clone, Copy, Debug)]
277+
pub enum UnaryOp {
278278
/// Negation: `-`.
279279
Neg,
280280
/// Bitwise NOT: `~`.
@@ -283,12 +283,12 @@ pub enum UnOp {
283283
NotL,
284284
}
285285

286-
impl Display for UnOp {
286+
impl Display for UnaryOp {
287287
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
288288
match self {
289-
UnOp::Neg => write!(f, "Neg"),
290-
UnOp::NotB => write!(f, "NotB"),
291-
UnOp::NotL => write!(f, "NotL"),
289+
UnaryOp::Neg => write!(f, "Neg"),
290+
UnaryOp::NotB => write!(f, "NotB"),
291+
UnaryOp::NotL => write!(f, "NotL"),
292292
}
293293
}
294294
}
@@ -637,7 +637,7 @@ impl Display for AliasStmt {
637637
#[derive(Clone, Debug)]
638638
pub struct ExprStmt {
639639
pub span: Span,
640-
pub expr: Box<Expr>,
640+
pub expr: Expr,
641641
}
642642

643643
impl Display for ExprStmt {
@@ -667,7 +667,7 @@ impl Display for Expr {
667667
#[derive(Clone, Debug)]
668668
pub struct DiscreteSet {
669669
pub span: Span,
670-
pub values: List<ExprStmt>,
670+
pub values: Box<[Expr]>,
671671
}
672672

673673
impl Display for DiscreteSet {
@@ -685,9 +685,9 @@ impl Display for DiscreteSet {
685685
#[derive(Clone, Debug)]
686686
pub struct RangeDefinition {
687687
pub span: Span,
688-
pub start: Option<ExprStmt>,
689-
pub end: Option<ExprStmt>,
690-
pub step: Option<ExprStmt>,
688+
pub start: Option<Expr>,
689+
pub end: Option<Expr>,
690+
pub step: Option<Expr>,
691691
}
692692

693693
#[derive(Clone, Debug)]
@@ -1584,17 +1584,20 @@ impl Display for ClassicalAssignment {
15841584

15851585
#[derive(Clone, Debug, Default)]
15861586
pub enum ExprKind {
1587+
Assign(AssignExpr),
1588+
AssignOp(AssignOpExpr),
15871589
/// An expression with invalid syntax that can't be parsed.
15881590
#[default]
15891591
Err,
15901592
Ident(Ident),
1591-
UnaryExpr(UnaryExpr),
1592-
BinaryExpr(BinaryExpr),
1593+
UnaryOp(UnaryOpExpr),
1594+
BinaryOp(BinaryOpExpr),
15931595
Lit(Lit),
15941596
FunctionCall(FunctionCall),
15951597
Cast(Cast),
15961598
Concatenation(Concatenation),
15971599
IndexExpr(IndexExpr),
1600+
Paren(Expr),
15981601
}
15991602

16001603
impl Display for ExprKind {
@@ -1603,40 +1606,68 @@ impl Display for ExprKind {
16031606
match self {
16041607
ExprKind::Err => write!(f, "Err"),
16051608
ExprKind::Ident(id) => write!(f, "{id}"),
1606-
ExprKind::UnaryExpr(expr) => write!(f, "{expr}"),
1607-
ExprKind::BinaryExpr(expr) => display_bin_op(indent, expr),
1609+
ExprKind::UnaryOp(expr) => write!(f, "{expr}"),
1610+
ExprKind::BinaryOp(expr) => display_bin_op(indent, expr),
16081611
ExprKind::Lit(lit) => write!(f, "{lit}"),
16091612
ExprKind::FunctionCall(call) => write!(f, "{call}"),
1610-
ExprKind::Cast(cast) => write!(f, "{cast}"),
1613+
ExprKind::Cast(cast) => display_cast(indent, cast),
16111614
ExprKind::Concatenation(concat) => write!(f, "{concat}"),
16121615
ExprKind::IndexExpr(index) => write!(f, "{index}"),
1616+
ExprKind::Assign(expr) => write!(f, "{expr}"),
1617+
ExprKind::AssignOp(expr) => write!(f, "{expr}"),
1618+
ExprKind::Paren(expr) => display_paren(indent, expr),
16131619
}
16141620
}
16151621
}
16161622

16171623
#[derive(Clone, Debug)]
1618-
pub struct UnaryExpr {
1619-
pub span: Span,
1624+
pub struct AssignExpr {
1625+
pub lhs: Expr,
1626+
pub rhs: Expr,
1627+
}
1628+
1629+
impl Display for AssignExpr {
1630+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1631+
let indent = set_indentation(indented(f), 0);
1632+
display_assign(indent, &self.lhs, &self.rhs)
1633+
}
1634+
}
1635+
1636+
#[derive(Clone, Debug)]
1637+
pub struct AssignOpExpr {
1638+
pub op: BinOp,
1639+
pub lhs: Expr,
1640+
pub rhs: Expr,
1641+
}
1642+
1643+
impl Display for AssignOpExpr {
1644+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1645+
let indent = set_indentation(indented(f), 0);
1646+
display_assign_op(indent, self.op, &self.lhs, &self.rhs)
1647+
}
1648+
}
1649+
1650+
#[derive(Clone, Debug)]
1651+
pub struct UnaryOpExpr {
16201652
pub op: UnaryOp,
1621-
pub expr: Box<Expr>,
1653+
pub expr: Expr,
16221654
}
16231655

1624-
impl Display for UnaryExpr {
1656+
impl Display for UnaryOpExpr {
16251657
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
16261658
let indent = set_indentation(indented(f), 0);
16271659
display_un_op(indent, self.op, &self.expr)
16281660
}
16291661
}
16301662

16311663
#[derive(Clone, Debug)]
1632-
pub struct BinaryExpr {
1633-
pub span: Span,
1634-
pub op: BinaryOp,
1635-
pub lhs: ExprStmt,
1636-
pub rhs: ExprStmt,
1664+
pub struct BinaryOpExpr {
1665+
pub op: BinOp,
1666+
pub lhs: Expr,
1667+
pub rhs: Expr,
16371668
}
16381669

1639-
impl Display for BinaryExpr {
1670+
impl Display for BinaryOpExpr {
16401671
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
16411672
let indent = set_indentation(indented(f), 0);
16421673
display_bin_op(indent, self)
@@ -1647,7 +1678,7 @@ impl Display for BinaryExpr {
16471678
pub struct FunctionCall {
16481679
pub span: Span,
16491680
pub name: Identifier,
1650-
pub args: List<ExprStmt>,
1681+
pub args: List<Expr>,
16511682
}
16521683

16531684
impl Display for FunctionCall {
@@ -1665,8 +1696,8 @@ impl Display for FunctionCall {
16651696
#[derive(Clone, Debug)]
16661697
pub struct Cast {
16671698
pub span: Span,
1668-
pub r#type: ScalarType,
1669-
pub arg: ExprStmt,
1699+
pub r#type: TypeDef,
1700+
pub arg: Expr,
16701701
}
16711702

16721703
impl Display for Cast {
@@ -1678,7 +1709,7 @@ impl Display for Cast {
16781709
#[derive(Clone, Debug)]
16791710
pub struct IndexExpr {
16801711
pub span: Span,
1681-
pub collection: ExprStmt,
1712+
pub collection: Expr,
16821713
pub index: IndexElement,
16831714
}
16841715

@@ -1692,65 +1723,6 @@ impl Display for IndexExpr {
16921723
}
16931724
}
16941725

1695-
#[derive(Clone, Copy, Debug)]
1696-
pub enum UnaryOp {
1697-
NegB,
1698-
NegL,
1699-
NegN,
1700-
}
1701-
1702-
impl Display for UnaryOp {
1703-
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1704-
match self {
1705-
UnaryOp::NegB => write!(f, "NegB"),
1706-
UnaryOp::NegL => write!(f, "NegL"),
1707-
UnaryOp::NegN => write!(f, "NegN"),
1708-
}
1709-
}
1710-
}
1711-
1712-
#[derive(Clone, Copy, Debug)]
1713-
pub enum BinaryOp {
1714-
/// `>`
1715-
Gt,
1716-
/// `<`
1717-
Lt,
1718-
/// `>=`
1719-
Gte,
1720-
/// `<=`
1721-
Lte,
1722-
/// `==`
1723-
Eq,
1724-
/// `!=`
1725-
Neq,
1726-
/// `&&`
1727-
AndL,
1728-
/// `||`
1729-
OrL,
1730-
/// `|`
1731-
OrB,
1732-
/// `^`
1733-
XorB,
1734-
/// `&`
1735-
AndB,
1736-
/// `<<`
1737-
ShL,
1738-
/// `>>`
1739-
ShR,
1740-
/// `+`
1741-
Add,
1742-
/// `-`
1743-
Sub,
1744-
/// `*`
1745-
Mul,
1746-
/// `/`
1747-
Div,
1748-
/// `%`
1749-
Mod,
1750-
/// `**`
1751-
Exp,
1752-
}
1753-
17541726
#[derive(Clone, Debug)]
17551727
pub struct Lit {
17561728
pub span: Span,
@@ -1860,10 +1832,19 @@ impl Display for IndexElement {
18601832
}
18611833
}
18621834

1863-
#[derive(Clone, Debug)]
1835+
#[derive(Clone, Debug, Default)]
18641836
pub enum IndexSetItem {
18651837
RangeDefinition(RangeDefinition),
1866-
Expr(ExprStmt),
1838+
Expr(Expr),
1839+
#[default]
1840+
Err,
1841+
}
1842+
1843+
/// This is needed to able to use `IndexSetItem` in the `seq` combinator.
1844+
impl WithSpan for IndexSetItem {
1845+
fn with_span(self, _span: Span) -> Self {
1846+
self
1847+
}
18671848
}
18681849

18691850
impl Display for IndexSetItem {
@@ -1872,13 +1853,14 @@ impl Display for IndexSetItem {
18721853
match self {
18731854
IndexSetItem::RangeDefinition(range) => display_range(indent, range),
18741855
IndexSetItem::Expr(expr) => write!(f, "IndexSetItem {expr}"),
1856+
IndexSetItem::Err => write!(f, "Err"),
18751857
}
18761858
}
18771859
}
18781860

18791861
#[derive(Clone, Debug)]
18801862
pub enum AssignmentOp {
1881-
BinaryOp(BinaryOp),
1863+
BinaryOp(BinOp),
18821864
/// `OpenQASM3` has the `~=` assignment operator.
18831865
/// This enum variant is meant to capture that.
18841866
UnaryOp(UnaryOp),
@@ -1986,7 +1968,7 @@ fn display_assign(mut indent: Indented<Formatter>, lhs: &Expr, rhs: &Expr) -> fm
19861968

19871969
fn display_assign_op(
19881970
mut indent: Indented<Formatter>,
1989-
op: BinaryOp,
1971+
op: BinOp,
19901972
lhs: &Expr,
19911973
rhs: &Expr,
19921974
) -> fmt::Result {
@@ -1997,7 +1979,7 @@ fn display_assign_op(
19971979
Ok(())
19981980
}
19991981

2000-
fn display_bin_op(mut indent: Indented<Formatter>, expr: &BinaryExpr) -> fmt::Result {
1982+
fn display_bin_op(mut indent: Indented<Formatter>, expr: &BinaryOpExpr) -> fmt::Result {
20011983
write!(indent, "BinOp ({:?}):", expr.op)?;
20021984
indent = set_indentation(indent, 1);
20031985
write!(indent, "\n{}", expr.lhs)?;
@@ -2012,6 +1994,20 @@ fn display_un_op(mut indent: Indented<Formatter>, op: UnaryOp, expr: &Expr) -> f
20121994
Ok(())
20131995
}
20141996

1997+
fn display_paren(mut indent: Indented<Formatter>, expr: &Expr) -> fmt::Result {
1998+
write!(indent, "Paren:")?;
1999+
indent = set_indentation(indent, 1);
2000+
write!(indent, "\n{expr}")?;
2001+
Ok(())
2002+
}
2003+
fn display_cast(mut indent: Indented<Formatter>, cast: &Cast) -> fmt::Result {
2004+
let Cast { span, r#type, arg } = cast;
2005+
write!(indent, "Cast {span}:")?;
2006+
indent = set_indentation(indent, 1);
2007+
write!(indent, "\n{type}\n{arg}")?;
2008+
Ok(())
2009+
}
2010+
20152011
fn display_while(mut indent: Indented<Formatter>, cond: &Expr, block: &Block) -> fmt::Result {
20162012
write!(indent, "While:")?;
20172013
indent = set_indentation(indent, 1);

compiler/qsc_qasm3/src/keyword.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use std::{
99

1010
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Sequence)]
1111
pub enum Keyword {
12-
Array,
1312
Barrier,
1413
Box,
1514
Break,
@@ -58,7 +57,6 @@ pub enum Keyword {
5857
impl Keyword {
5958
pub(super) fn as_str(self) -> &'static str {
6059
match self {
61-
Keyword::Array => "array",
6260
Keyword::Barrier => "barrier",
6361
Keyword::Box => "box",
6462
Keyword::Break => "break",
@@ -120,7 +118,6 @@ impl FromStr for Keyword {
120118
// frequency in Q# so that fewer comparisons are needed on average.
121119
fn from_str(s: &str) -> Result<Self, Self::Err> {
122120
match s {
123-
"array" => Ok(Self::Array),
124121
"barrier" => Ok(Self::Barrier),
125122
"box" => Ok(Self::Box),
126123
"break" => Ok(Self::Break),

compiler/qsc_qasm3/src/parser/completion/word_kinds.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ bitflags! {
6262
// Begin keywords.
6363
//
6464

65-
const Array = keyword_bit(Keyword::Array);
6665
const Barrier = keyword_bit(Keyword::Barrier);
6766
const Box = keyword_bit(Keyword::Box);
6867
const Break = keyword_bit(Keyword::Break);

0 commit comments

Comments
 (0)