Skip to content

Commit 5a44377

Browse files
committed
feat: parse and display Gate directly
1 parent 0b268ab commit 5a44377

File tree

4 files changed

+41
-24
lines changed

4 files changed

+41
-24
lines changed

src/instruction.rs

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use std::str::FromStr;
2020
use std::{collections::HashMap, fmt};
2121

2222
use crate::expression::Expression;
23+
use crate::parser::gate::parse_gate;
2324
use crate::parser::{common::parse_memory_reference, lex, ParseError};
2425
use crate::program::{disallow_leftover, frame::FrameMatchCondition, SyntaxError};
2526

@@ -361,6 +362,35 @@ pub struct Gate {
361362
pub modifiers: Vec<GateModifier>,
362363
}
363364

365+
impl std::fmt::Display for Gate {
366+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
367+
let parameter_str = get_expression_parameter_string(&self.parameters);
368+
369+
let qubit_str = format_qubits(&self.qubits);
370+
let modifier_str = self
371+
.modifiers
372+
.iter()
373+
.map(|m| format!("{} ", m))
374+
.collect::<Vec<String>>()
375+
.join("");
376+
write!(
377+
f,
378+
"{}{}{} {}",
379+
modifier_str, self.name, parameter_str, qubit_str
380+
)
381+
}
382+
}
383+
384+
impl FromStr for Gate {
385+
type Err = SyntaxError<Self>;
386+
387+
fn from_str(s: &str) -> Result<Self, Self::Err> {
388+
let input = LocatedSpan::new(s);
389+
let tokens = lex(input)?;
390+
disallow_leftover(parse_gate(&tokens).map_err(ParseError::from_nom_internal_err))
391+
}
392+
}
393+
364394
#[derive(Clone, Debug, PartialEq)]
365395
pub struct CircuitDefinition {
366396
pub name: String,
@@ -837,21 +867,8 @@ impl fmt::Display for Instruction {
837867
.map(|(k, v)| format!("\n\t{}: {}", k, v))
838868
.collect::<String>()
839869
),
840-
Instruction::Gate(Gate {
841-
name,
842-
parameters,
843-
qubits,
844-
modifiers,
845-
}) => {
846-
let parameter_str = get_expression_parameter_string(parameters);
847-
848-
let qubit_str = format_qubits(qubits);
849-
let modifier_str = modifiers
850-
.iter()
851-
.map(|m| format!("{} ", m))
852-
.collect::<Vec<String>>()
853-
.join("");
854-
write!(f, "{}{}{} {}", modifier_str, name, parameter_str, qubit_str)
870+
Instruction::Gate(gate) => {
871+
write!(f, "{gate}")
855872
}
856873
Instruction::GateDefinition(GateDefinition {
857874
name,

src/parser/gate.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
use nom::{combinator::opt, multi::many0, multi::separated_list0, sequence::delimited};
1616

17-
use crate::{instruction::Instruction, token};
17+
use crate::token;
1818

1919
use super::{
2020
common::{self, parse_gate_modifier},
@@ -25,7 +25,7 @@ use crate::instruction::Gate;
2525
use crate::parser::InternalParserResult;
2626

2727
/// Parse a gate instruction.
28-
pub(crate) fn parse_gate<'a>(input: ParserInput<'a>) -> InternalParserResult<'a, Instruction> {
28+
pub(crate) fn parse_gate<'a>(input: ParserInput<'a>) -> InternalParserResult<'a, Gate> {
2929
let (input, modifiers) = many0(parse_gate_modifier)(input)?;
3030
let (input, name) = token!(Identifier(v))(input)?;
3131
let (input, parameters) = opt(delimited(
@@ -37,12 +37,12 @@ pub(crate) fn parse_gate<'a>(input: ParserInput<'a>) -> InternalParserResult<'a,
3737
let (input, qubits) = many0(common::parse_qubit)(input)?;
3838
Ok((
3939
input,
40-
Instruction::Gate(Gate {
40+
Gate {
4141
name,
4242
parameters,
4343
qubits,
4444
modifiers,
45-
}),
45+
},
4646
))
4747
}
4848

@@ -58,11 +58,11 @@ mod test {
5858
test_modifiers,
5959
parse_gate,
6060
"DAGGER CONTROLLED RX(pi) 0 1",
61-
Instruction::Gate(Gate {
61+
Gate {
6262
name: "RX".to_string(),
6363
parameters: vec![Expression::PiConstant],
6464
qubits: vec![Qubit::Fixed(0), Qubit::Fixed(1)],
6565
modifiers: vec![GateModifier::Dagger, GateModifier::Controlled],
66-
})
66+
}
6767
);
6868
}

src/parser/instruction.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// limitations under the License.
1414

1515
use nom::{
16-
combinator::all_consuming,
16+
combinator::{all_consuming, map},
1717
multi::{many0, many1},
1818
sequence::{delimited, preceded},
1919
};
@@ -111,7 +111,7 @@ pub(crate) fn parse_instruction(input: ParserInput) -> InternalParserResult<Inst
111111
},
112112
_ => todo!(),
113113
},
114-
Some((Token::Identifier(_), _)) | Some((Token::Modifier(_), _)) => gate::parse_gate(input),
114+
Some((Token::Identifier(_), _)) | Some((Token::Modifier(_), _)) => map(gate::parse_gate, Instruction::Gate)(input),
115115
Some((_, _)) => Err(nom::Err::Failure(InternalParseError::from_kind(
116116
&input[..1],
117117
ParserErrorKind::NotACommandOrGate,

src/parser/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub(crate) use instruction::parse_instructions;
1919
pub(crate) use lexer::lex;
2020

2121
mod command;
22-
mod gate;
22+
pub(crate) mod gate;
2323
mod macros;
2424

2525
pub(crate) mod common;

0 commit comments

Comments
 (0)