From 414fe24c10fb068e98c01f4a9cab0753a68d3980 Mon Sep 17 00:00:00 2001 From: Lukas Burgholzer Date: Tue, 12 Mar 2024 18:21:56 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fix=20scientific=20notation=20in?= =?UTF-8?q?=20QASM=20import=20(#560)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description This PR fixes a small bug in the QASM importer that would prevent it from properly importing floating point numbers in scientific notation. ## Checklist: - [x] The pull request only contains commits that are related to it. - [x] I have added appropriate tests and documentation. - [x] I have made sure that all CI jobs on GitHub pass. - [x] The pull request introduces no new warnings and follows the project's style guidelines. --------- Signed-off-by: burgholzer --- src/parsers/qasm3_parser/Scanner.cpp | 30 +++++++++++++++++++++++----- test/unittests/test_qasm3_parser.cpp | 4 +++- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/parsers/qasm3_parser/Scanner.cpp b/src/parsers/qasm3_parser/Scanner.cpp index 2f2b8f8ba..c0946a0d2 100644 --- a/src/parsers/qasm3_parser/Scanner.cpp +++ b/src/parsers/qasm3_parser/Scanner.cpp @@ -1,6 +1,12 @@ #include "parsers/qasm3_parser/Scanner.hpp" +#include +#include +#include #include +#include +#include +#include namespace qasm3 { char Scanner::readUtf8Codepoint(std::istream* in) { @@ -186,12 +192,26 @@ Token Scanner::consumeNumberLiteral() { error("Float literals are only allowed in base 10"); } - char const sep = ch; - nextCh(); - auto valAfterDecimalSeparator = consumeNumberLiteral(base); + std::stringstream ss{}; + ss << valBeforeDecimalSeparator; + + if (ch == '.') { + ss << ch; + nextCh(); + const auto valAfterDecimalSeparator = consumeNumberLiteral(base); + ss << valAfterDecimalSeparator; + } - std::stringstream ss; - ss << valBeforeDecimalSeparator << sep << valAfterDecimalSeparator; + if (ch == 'e' || ch == 'E') { + ss << ch; + nextCh(); + if (ch == '+' || ch == '-') { + ss << ch; + nextCh(); + } + const auto valAfterExponent = consumeNumberLiteral(base); + ss << valAfterExponent; + } try { t.valReal = std::stod(ss.str()); diff --git a/test/unittests/test_qasm3_parser.cpp b/test/unittests/test_qasm3_parser.cpp index 79093d083..be3c9b775 100644 --- a/test/unittests/test_qasm3_parser.cpp +++ b/test/unittests/test_qasm3_parser.cpp @@ -743,7 +743,7 @@ TEST_F(Qasm3ParserTest, ImportQasm3CPrefix) { TEST_F(Qasm3ParserTest, ImportQasmScanner) { std::stringstream ss{}; const std::string testfile = - "$1 : . .5 -1. -= += ++ *= **= ** /= % %= |= || | &= " + "$1 : . .5 -1. 1.25e-3 1e3 -= += ++ *= **= ** /= % %= |= || | &= " "&& & ^= ^ ~= ~ ! <= <<= << < >= >>= >> >"; const auto tokens = std::vector{ qasm3::Token::Kind::HardwareQubit, @@ -751,6 +751,8 @@ TEST_F(Qasm3ParserTest, ImportQasmScanner) { qasm3::Token::Kind::Dot, qasm3::Token::Kind::FloatLiteral, qasm3::Token::Kind::FloatLiteral, + qasm3::Token::Kind::FloatLiteral, + qasm3::Token::Kind::FloatLiteral, qasm3::Token::Kind::MinusEquals, qasm3::Token::Kind::PlusEquals, qasm3::Token::Kind::DoublePlus,