Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions crates/oq3_parser/src/grammar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,4 +201,8 @@ impl SyntaxKind {
pub fn is_type(&self) -> bool {
self.is_classical_type() || self.is_quantum_type()
}

pub fn is_creg_or_qreg(&self) -> bool {
matches!(self, T![qreg] | T![creg])
}
}
16 changes: 11 additions & 5 deletions crates/oq3_parser/src/grammar/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,24 +148,30 @@ pub(crate) fn stmt(p: &mut Parser<'_>) {
}
}

fn q_or_c_reg_declaration(p: &mut Parser<'_>, m: Marker) {
p.bump_any();
/// The designator is on the identifier, rather than the type
/// in OQ2. So we don't parse the identifier and type separately
/// as we do for OQ3 constructions.
pub fn q_or_c_reg_param(p: &mut Parser<'_>) {
let m = p.start();
p.bump_any(); // creg or qreg
if !p.at(IDENT) {
p.error("Expected qubit register name");
m.abandon(p);
return;
}
let m1 = p.start();
p.bump_any();
if p.at(T!['[']) && !p.at(EOF) {
index_operator(p);
} else {
p.error("Expected index operator");
m1.abandon(p);
m.abandon(p);
return;
}
m1.complete(p, INDEXED_IDENTIFIER);
m.complete(p, OLD_TYPED_PARAM);
}

fn q_or_c_reg_declaration(p: &mut Parser<'_>, m: Marker) {
q_or_c_reg_param(p);
p.expect(T![;]);
m.complete(p, OLD_STYLE_DECLARATION_STATEMENT);
}
Expand Down
11 changes: 10 additions & 1 deletion crates/oq3_parser/src/grammar/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,11 @@ fn _param_list_openqasm(p: &mut Parser<'_>, flavor: DefFlavor) {
// Allowed starts for an item: either a type or a first-token of a param/expression,
// or first token of array literal.
if matches!(flavor, DefParams) && (p.at(T![mutable]) || p.at(T![readonly])) {
} else if !(p.current().is_type() || p.at_ts(PARAM_FIRST) || inner_array_literal) {
} else if !(p.current().is_type()
|| p.at_ts(PARAM_FIRST)
|| inner_array_literal
|| p.current().is_creg_or_qreg())
{
p.error("expected value parameter");
m.abandon(p);
break;
Expand Down Expand Up @@ -294,6 +298,11 @@ fn param_untyped_or_hardware_qubit(p: &mut Parser<'_>, m: Marker) -> bool {
/// Parse one parameter in the list of parameters in the signature
/// of a subroutine defintion (that is, a `def` statement)
fn param_typed(p: &mut Parser<'_>, m: Marker) -> bool {
if p.at(T![creg]) || p.at(T![qreg]) {
m.abandon(p);
expressions::q_or_c_reg_param(p);
return true;
}
expressions::param_type_spec(p);
expressions::var_name(p);
m.complete(p, TYPED_PARAM);
Expand Down
1 change: 1 addition & 0 deletions crates/oq3_parser/src/syntax_kind/syntax_kind_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ pub enum SyntaxKind {
RANGE_EXPR,
TYPE,
TYPED_PARAM,
OLD_TYPED_PARAM,
TYPED_PARAM_LIST,
TYPE_LIST,
VERSION,
Expand Down
8 changes: 7 additions & 1 deletion crates/oq3_semantics/src/syntax_to_semantics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1471,7 +1471,13 @@ fn bind_typed_parameter_list(
param_list
.typed_params()
.map(|param| {
let typ = param_type_to_type(&param.param_type().unwrap(), false, context);
let typ = if let Some(pt) = param.param_type() {
param_type_to_type(&pt, false, context)
} else if param.old_typed_param().is_some() {
Type::ToDo
} else {
panic!("You have found a bug in oq3_parser")
};
let namestr = param.name().unwrap().string();
context.new_binding(namestr.as_ref(), &typ, &param)
})
Expand Down
1 change: 1 addition & 0 deletions crates/oq3_syntax/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ mod sourcegen {
"RANGE_EXPR",
"TYPE",
"TYPED_PARAM",
"OLD_TYPED_PARAM",
"TYPED_PARAM_LIST",
"TYPE_LIST",
"VERSION",
Expand Down
7 changes: 5 additions & 2 deletions crates/oq3_syntax/openqasm3.ungram
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,10 @@ ParamType =
(ScalarType | ArrayRefType)

TypedParam =
ParamType Name
(ParamType Name) | OldTypedParam

OldTypedParam =
('creg' | 'qreg') Name Designator?

TypedParamList =
'(' (TypedParam (',' TypedParam)* ','?)? ')'
Expand Down Expand Up @@ -446,7 +449,7 @@ IODeclarationStatement =
('input' | 'output') (ScalarType | ArrayType) Name ';'

OldStyleDeclarationStatement =
('creg' | 'qreg') Name Designator? ';'
OldTypedParam ';'

QuantumDeclarationStatement =
QubitType (Name | HardwareQubit) ';'
Expand Down
50 changes: 41 additions & 9 deletions crates/oq3_syntax/src/ast/generated/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,15 +405,8 @@ impl Measure {
pub struct OldStyleDeclarationStatement {
pub(crate) syntax: SyntaxNode,
}
impl ast::HasName for OldStyleDeclarationStatement {}
impl OldStyleDeclarationStatement {
pub fn creg_token(&self) -> Option<SyntaxToken> {
support::token(&self.syntax, T![creg])
}
pub fn qreg_token(&self) -> Option<SyntaxToken> {
support::token(&self.syntax, T![qreg])
}
pub fn designator(&self) -> Option<Designator> {
pub fn old_typed_param(&self) -> Option<OldTypedParam> {
support::child(&self.syntax)
}
pub fn semicolon_token(&self) -> Option<SyntaxToken> {
Expand Down Expand Up @@ -761,6 +754,25 @@ impl TypedParam {
pub fn param_type(&self) -> Option<ParamType> {
support::child(&self.syntax)
}
pub fn old_typed_param(&self) -> Option<OldTypedParam> {
support::child(&self.syntax)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct OldTypedParam {
pub(crate) syntax: SyntaxNode,
}
impl ast::HasName for OldTypedParam {}
impl OldTypedParam {
pub fn creg_token(&self) -> Option<SyntaxToken> {
support::token(&self.syntax, T![creg])
}
pub fn qreg_token(&self) -> Option<SyntaxToken> {
support::token(&self.syntax, T![qreg])
}
pub fn designator(&self) -> Option<Designator> {
support::child(&self.syntax)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ArrayExpr {
Expand Down Expand Up @@ -1955,6 +1967,21 @@ impl AstNode for TypedParam {
&self.syntax
}
}
impl AstNode for OldTypedParam {
fn can_cast(kind: SyntaxKind) -> bool {
kind == OLD_TYPED_PARAM
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
if Self::can_cast(syntax.kind()) {
Some(Self { syntax })
} else {
None
}
}
fn syntax(&self) -> &SyntaxNode {
&self.syntax
}
}
impl AstNode for ArrayExpr {
fn can_cast(kind: SyntaxKind) -> bool {
kind == ARRAY_EXPR
Expand Down Expand Up @@ -3037,10 +3064,10 @@ impl AstNode for AnyHasName {
| GATE
| I_O_DECLARATION_STATEMENT
| LET_STMT
| OLD_STYLE_DECLARATION_STATEMENT
| QUANTUM_DECLARATION_STATEMENT
| PARAM
| TYPED_PARAM
| OLD_TYPED_PARAM
| GATE_CALL_EXPR
| HARDWARE_QUBIT
| INDEXED_IDENTIFIER
Expand Down Expand Up @@ -3318,6 +3345,11 @@ impl std::fmt::Display for TypedParam {
std::fmt::Display::fmt(self.syntax(), f)
}
}
impl std::fmt::Display for OldTypedParam {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
}
}
impl std::fmt::Display for ArrayExpr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ [email protected]: input
[email protected]:
[email protected]:
[email protected]: qreg myvar[4];
INDEXED_IDENTIFIER@41..49: myvar[4]
OLD_TYPED_PARAM@36..49: qreg myvar[4]
[email protected]: [4]
[email protected]: 4
[email protected]: 4
[email protected]: output
[email protected]:
[email protected]:
[email protected]: qreg myvar[4];
INDEXED_IDENTIFIER@63..71: myvar[4]
OLD_TYPED_PARAM@58..71: qreg myvar[4]
[email protected]: [4]
[email protected]: 4
[email protected]: 4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ [email protected]: >
[email protected]: b;
[email protected]: b
[email protected]: creg a[1]
INDEXED_IDENTIFIER@68..72: a[1]
OLD_TYPED_PARAM@63..72: creg a[1]
[email protected]: [1]
[email protected]: 1
[email protected]: 1
Expand All @@ -63,7 +63,7 @@ [email protected]: measure $0
[email protected]: $0
[email protected]: >
[email protected]: creg a[1];
INDEXED_IDENTIFIER@106..110: a[1]
OLD_TYPED_PARAM@101..110: creg a[1]
[email protected]: [1]
[email protected]: 1
[email protected]: 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ [email protected]: [2]
[email protected]: 2
[email protected]: a
[email protected]: creg b[2];
INDEXED_IDENTIFIER@16..20: b[2]
OLD_TYPED_PARAM@11..20: creg b[2]
[email protected]: [2]
[email protected]: 2
[email protected]: 2
Expand All @@ -37,7 +37,7 @@ [email protected]: [5]
[email protected]: 5
[email protected]: q1
[email protected]: qreg q2[7];
INDEXED_IDENTIFIER@40..45: q2[7]
OLD_TYPED_PARAM@35..45: qreg q2[7]
[email protected]: [7]
[email protected]: 7
[email protected]: 7
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ [email protected]: [2]
[email protected]: 2
[email protected]: b
[email protected]: creg b[2];
INDEXED_IDENTIFIER@26..30: b[2]
OLD_TYPED_PARAM@21..30: creg b[2]
[email protected]: [2]
[email protected]: 2
[email protected]: 2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ source: crates/pipeline-tests/tests/runner.rs
expression: parse_snap
---
id: tests/snippets/reference/subroutine/subroutine.qasm
expect-parse: Todo
expect-parse: Ok
--- parser ---
ok: false
ok: true
panicked: false
errors: 14
errors: 0
--- ast ---
[email protected]:
def test_sub1(int[5] i, qubit[2] q1, qreg q2[5]) -> int[10] {
Expand All @@ -24,9 +24,13 @@ def returns_a_measure(qubit q) {
return measure q;
}

[email protected]: def test_sub1(int[5] i, qubit[2] q1,
[email protected]: def test_sub1(int[5] i, qubit[2] q1, qreg q2[5]) -> int[10] {
int[10] result;
if (result == 2) return 1 + result;
return result;
}
[email protected]: test_sub1
TYPED_PARAM_LIST@14..37: (int[5] i, qubit[2] q1,
TYPED_PARAM_LIST@14..49: (int[5] i, qubit[2] q1, qreg q2[5])
[email protected]: int[5] i
[email protected]: int[5]
[email protected]: [5]
Expand All @@ -37,24 +41,14 @@ [email protected]: qubit[2]
[email protected]: [2]
[email protected]: 2
[email protected]: q1
[email protected]: qreg q2[5]
[email protected]: q2[5]
[email protected]: qreg q2[5]
[email protected]: [5]
[email protected]: 5
[email protected]: 5
[email protected]: )
[email protected]: ->
[email protected]: ->
[email protected]: >
[email protected]: -> int[10]
[email protected]: int[10]
[email protected]: [10]
[email protected]: 10
[email protected]:
[email protected]: {
int[10] result;
if (result == 2) return 1 + result;
return result;
}
[email protected]: {
int[10] result;
if (result == 2) return 1 + result;
Expand All @@ -77,9 +71,13 @@ [email protected]: result
[email protected]: return result;
[email protected]: return result
[email protected]: result
[email protected]: def test_sub2(int[5] i, bit[2] b,
[email protected]: def test_sub2(int[5] i, bit[2] b, creg c[3]) {
for int[5] j in {2, 3}
i += j;
return i+1;
}
[email protected]: test_sub2
TYPED_PARAM_LIST@151..171: (int[5] i, bit[2] b,
TYPED_PARAM_LIST@151..182: (int[5] i, bit[2] b, creg c[3])
[email protected]: int[5] i
[email protected]: int[5]
[email protected]: [5]
Expand All @@ -90,17 +88,10 @@ [email protected]: bit[2]
[email protected]: [2]
[email protected]: 2
[email protected]: b
[email protected]: creg c[3]
[email protected]: c[3]
[email protected]: creg c[3]
[email protected]: [3]
[email protected]: 3
[email protected]: 3
[email protected]: )
[email protected]: {
for int[5] j in {2, 3}
i += j;
return i+1;
}
[email protected]: {
for int[5] j in {2, 3}
i += j;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// lex: ok
// parse: todo
// parse: ok
// sema: skip

def test_sub1(int[5] i, qubit[2] q1, qreg q2[5]) -> int[10] {
Expand Down
Loading