Skip to content

Commit 76eee5d

Browse files
orpuente-MSidavis
authored andcommitted
fix lexer bug
1 parent aeab4ba commit 76eee5d

File tree

4 files changed

+69
-28
lines changed

4 files changed

+69
-28
lines changed

compiler/qsc_qasm3/src/lex/cooked.rs

+5-10
Original file line numberDiff line numberDiff line change
@@ -554,19 +554,14 @@ impl<'a> Lexer<'a> {
554554
raw::TokenKind::Number(number) => {
555555
// after reading a decimal number or a float there could be a whitespace
556556
// followed by a fragment, which will change the type of the literal.
557-
match (self.first(), self.second()) {
558-
(Some(raw::TokenKind::LiteralFragment(fragment)), _)
559-
| (
560-
Some(raw::TokenKind::Whitespace),
561-
Some(raw::TokenKind::LiteralFragment(fragment)),
562-
) => {
557+
self.next_if_eq(raw::TokenKind::Whitespace);
558+
559+
match self.first() {
560+
Some(raw::TokenKind::LiteralFragment(fragment)) => {
563561
use self::Literal::{Imaginary, Timing};
564562
use TokenKind::Literal;
565563

566-
// if first() was a whitespace, we need to consume an extra token
567-
if self.first() == Some(raw::TokenKind::Whitespace) {
568-
self.next();
569-
}
564+
// Consume the fragment.
570565
self.next();
571566

572567
Ok(Some(match fragment {

compiler/qsc_qasm3/src/lex/cooked/tests.rs

+31
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,37 @@ fn imag_with_whitespace() {
363363
);
364364
}
365365

366+
#[test]
367+
fn imag_with_whitespace_semicolon() {
368+
check(
369+
"123 im;",
370+
&expect![[r#"
371+
[
372+
Ok(
373+
Token {
374+
kind: Literal(
375+
Imaginary,
376+
),
377+
span: Span {
378+
lo: 0,
379+
hi: 6,
380+
},
381+
},
382+
),
383+
Ok(
384+
Token {
385+
kind: Semicolon,
386+
span: Span {
387+
lo: 6,
388+
hi: 7,
389+
},
390+
},
391+
),
392+
]
393+
"#]],
394+
);
395+
}
396+
366397
#[test]
367398
fn negative_imag() {
368399
check(

compiler/qsc_qasm3/src/lex/raw/tests.rs

+32
Original file line numberDiff line numberDiff line change
@@ -1274,3 +1274,35 @@ fn hardware_qubit_with_underscore_in_the_middle() {
12741274
"#]],
12751275
);
12761276
}
1277+
1278+
#[test]
1279+
fn decimal_space_imag_semicolon() {
1280+
check("10 im;", &expect![[r#"
1281+
[
1282+
Token {
1283+
kind: Number(
1284+
Int(
1285+
Decimal,
1286+
),
1287+
),
1288+
offset: 0,
1289+
},
1290+
Token {
1291+
kind: Whitespace,
1292+
offset: 2,
1293+
},
1294+
Token {
1295+
kind: LiteralFragment(
1296+
Imag,
1297+
),
1298+
offset: 4,
1299+
},
1300+
Token {
1301+
kind: Single(
1302+
Semi,
1303+
),
1304+
offset: 6,
1305+
},
1306+
]
1307+
"#]]);
1308+
}

compiler/qsc_qasm3/src/parser/expr/tests.rs

+1-18
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,10 @@
44
use super::expr;
55
use crate::{
66
ast::StmtKind,
7-
parser::{scan::ParserContext, stmt, tests::check, Parser},
7+
parser::{scan::ParserContext, stmt, tests::check},
88
};
99
use expect_test::{expect, Expect};
1010

11-
fn check_map<T>(
12-
mut parser: impl Parser<T>,
13-
input: &str,
14-
expect: &Expect,
15-
f: impl FnOnce(&T) -> String,
16-
) {
17-
let mut scanner = ParserContext::new(input);
18-
let result = parser(&mut scanner);
19-
let errors = scanner.into_errors();
20-
match result {
21-
Ok(value) if errors.is_empty() => expect.assert_eq(&f(&value)),
22-
Ok(value) => expect.assert_eq(&format!("{}\n\n{errors:#?}", f(&value))),
23-
Err(error) if errors.is_empty() => expect.assert_debug_eq(&error),
24-
Err(error) => expect.assert_eq(&format!("{error:#?}\n\n{errors:#?}")),
25-
}
26-
}
27-
2811
/// This function checks two things:
2912
/// 1. That the input `Expr` is parsed correctly.
3013
/// 2. That if we add a semicolon at the end it parses correctly as a `ExprStmt`

0 commit comments

Comments
 (0)