Skip to content

Commit 386f5be

Browse files
authored
🚸 Better QASM parser exceptions (cda-tum#618)
## Description This PR augments the QASM parser exceptions with a proper overload of the `std::exception::what()` method so that they print proper error messages when raised. This came up in the light of cda-tum/mqt-ddvis#259 ## Checklist: <!--- This checklist serves as a reminder of a couple of things that ensure your pull request will be merged swiftly. --> - [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 <burgholzer@me.com>
1 parent 5310b72 commit 386f5be

File tree

6 files changed

+33
-17
lines changed

6 files changed

+33
-17
lines changed

include/mqt-core/parsers/qasm3_parser/Exception.hpp

+18
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class CompilerError final : public std::exception {
1313
public:
1414
std::string message;
1515
std::shared_ptr<DebugInfo> debugInfo;
16+
mutable std::string cachedMessage;
1617

1718
CompilerError(std::string msg, std::shared_ptr<DebugInfo> debug)
1819
: message(std::move(msg)), debugInfo(std::move(debug)) {}
@@ -31,27 +32,44 @@ class CompilerError final : public std::exception {
3132

3233
return ss.str();
3334
}
35+
36+
[[nodiscard]] const char* what() const noexcept override {
37+
cachedMessage = toString();
38+
return cachedMessage.c_str();
39+
}
3440
};
3541
} // namespace qasm3
3642

3743
class ConstEvalError final : public std::exception {
3844
public:
3945
std::string message;
46+
mutable std::string cachedMessage;
4047

4148
explicit ConstEvalError(std::string msg) : message(std::move(msg)) {}
4249

4350
[[nodiscard]] std::string toString() const {
4451
return "Constant Evaluation: " + message;
4552
}
53+
54+
[[nodiscard]] const char* what() const noexcept override {
55+
cachedMessage = toString();
56+
return cachedMessage.c_str();
57+
}
4658
};
4759

4860
class TypeCheckError final : public std::exception {
4961
public:
5062
std::string message;
63+
mutable std::string cachedMessage;
5164

5265
explicit TypeCheckError(std::string msg) : message(std::move(msg)) {}
5366

5467
[[nodiscard]] std::string toString() const {
5568
return "Type Check Error: " + message;
5669
}
70+
71+
[[nodiscard]] const char* what() const noexcept override {
72+
cachedMessage = toString();
73+
return cachedMessage.c_str();
74+
}
5775
};

include/mqt-core/parsers/qasm3_parser/Parser.hpp

-2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,6 @@ class Parser {
7171
std::shared_ptr<DebugInfo> includeDebugInfo{nullptr};
7272

7373
[[noreturn]] void error(const Token& token, const std::string& msg) {
74-
std::cerr << "Error at line " << token.line << ", column " << token.col
75-
<< ": " << msg << '\n';
7674
throw CompilerError(msg, makeDebugInfo(token));
7775
}
7876

include/mqt-core/parsers/qasm3_parser/passes/ConstEvalPass.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ class ConstEvalPass : public CompilerPass,
123123
try {
124124
statement.accept(this);
125125
} catch (const ConstEvalError& e) {
126-
throw CompilerError(e.toString(), statement.debugInfo);
126+
throw CompilerError(e.what(), statement.debugInfo);
127127
}
128128
}
129129

include/mqt-core/parsers/qasm3_parser/passes/TypeCheckPass.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,10 @@ class TypeCheckPass : public CompilerPass,
7878
statement.accept(this);
7979

8080
if (hasError) {
81-
throw CompilerError("Type check failed.", statement.debugInfo);
81+
throw TypeCheckError("Type check failed.");
8282
}
8383
} catch (const TypeCheckError& e) {
84-
throw CompilerError(e.toString(), statement.debugInfo);
84+
throw CompilerError(e.what(), statement.debugInfo);
8585
}
8686
}
8787

src/parsers/QASM3Parser.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ class OpenQasm3Parser final : public InstVisitor {
179179
typeCheckPass.processStatement(*statement);
180180
statement->accept(this);
181181
} catch (CompilerError& e) {
182-
std::cerr << e.toString() << '\n';
182+
std::cerr << e.what() << '\n';
183183
throw;
184184
}
185185
}

test/unittests/test_qasm3_parser.cpp

+11-11
Original file line numberDiff line numberDiff line change
@@ -989,7 +989,7 @@ TEST_F(Qasm3ParserTest, ImportQasmAssignmentUnknownIdentifier) {
989989
try {
990990
const auto qc = QuantumComputation::fromQASM(testfile);
991991
} catch (const qasm3::CompilerError& e) {
992-
EXPECT_EQ(e.message, "Type check failed.");
992+
EXPECT_EQ(e.message, "Type Check Error: Type check failed.");
993993
throw;
994994
}
995995
},
@@ -1007,7 +1007,7 @@ TEST_F(Qasm3ParserTest, ImportQasmAssignmentConstVar) {
10071007
try {
10081008
const auto qc = QuantumComputation::fromQASM(testfile);
10091009
} catch (const qasm3::CompilerError& e) {
1010-
EXPECT_EQ(e.message, "Type check failed.");
1010+
EXPECT_EQ(e.message, "Type Check Error: Type check failed.");
10111011
throw;
10121012
}
10131013
},
@@ -1325,7 +1325,7 @@ TEST_F(Qasm3ParserTest, ImportQasmTypeMismatchAssignment) {
13251325
try {
13261326
const auto qc = QuantumComputation::fromQASM(testfile);
13271327
} catch (const qasm3::CompilerError& e) {
1328-
EXPECT_EQ(e.message, "Type check failed.");
1328+
EXPECT_EQ(e.message, "Type Check Error: Type check failed.");
13291329
throw;
13301330
}
13311331
},
@@ -1341,7 +1341,7 @@ TEST_F(Qasm3ParserTest, ImportQasmTypeMismatchBinaryExpr) {
13411341
try {
13421342
const auto qc = QuantumComputation::fromQASM(testfile);
13431343
} catch (const qasm3::CompilerError& e) {
1344-
EXPECT_EQ(e.message, "Type check failed.");
1344+
EXPECT_EQ(e.message, "Type Check Error: Type check failed.");
13451345
throw;
13461346
}
13471347
},
@@ -1373,7 +1373,7 @@ TEST_F(Qasm3ParserTest, ImportQasmUnaryTypeMismatchLogicalNot) {
13731373
try {
13741374
const auto qc = QuantumComputation::fromQASM(testfile);
13751375
} catch (const qasm3::CompilerError& e) {
1376-
EXPECT_EQ(e.message, "Type check failed.");
1376+
EXPECT_EQ(e.message, "Type Check Error: Type check failed.");
13771377
throw;
13781378
}
13791379
},
@@ -1389,7 +1389,7 @@ TEST_F(Qasm3ParserTest, ImportQasmUnaryTypeMismatchBitwiseNot) {
13891389
try {
13901390
const auto qc = QuantumComputation::fromQASM(testfile);
13911391
} catch (const qasm3::CompilerError& e) {
1392-
EXPECT_EQ(e.message, "Type check failed.");
1392+
EXPECT_EQ(e.message, "Type Check Error: Type check failed.");
13931393
throw;
13941394
}
13951395
},
@@ -1404,7 +1404,7 @@ TEST_F(Qasm3ParserTest, ImportQasmBinaryTypeMismatch) {
14041404
try {
14051405
const auto qc = QuantumComputation::fromQASM(testfile);
14061406
} catch (const qasm3::CompilerError& e) {
1407-
EXPECT_EQ(e.message, "Type check failed.");
1407+
EXPECT_EQ(e.message, "Type Check Error: Type check failed.");
14081408
throw;
14091409
}
14101410
},
@@ -1420,7 +1420,7 @@ TEST_F(Qasm3ParserTest, ImportQasmAssignmentIndexType) {
14201420
try {
14211421
const auto qc = QuantumComputation::fromQASM(testfile);
14221422
} catch (const qasm3::CompilerError& e) {
1423-
EXPECT_EQ(e.message, "Type check failed.");
1423+
EXPECT_EQ(e.message, "Type Check Error: Type check failed.");
14241424
throw;
14251425
}
14261426
},
@@ -1435,7 +1435,7 @@ TEST_F(Qasm3ParserTest, ImportQasmUnknownIdentifier) {
14351435
try {
14361436
const auto qc = QuantumComputation::fromQASM(testfile);
14371437
} catch (const qasm3::CompilerError& e) {
1438-
EXPECT_EQ(e.message, "Type check failed.");
1438+
EXPECT_EQ(e.message, "Type Check Error: Type check failed.");
14391439
throw;
14401440
}
14411441
},
@@ -1450,7 +1450,7 @@ TEST_F(Qasm3ParserTest, ImportQasmUnknownQubit) {
14501450
try {
14511451
const auto qc = QuantumComputation::fromQASM(testfile);
14521452
} catch (const qasm3::CompilerError& e) {
1453-
EXPECT_EQ(e.message, "Type check failed.");
1453+
EXPECT_EQ(e.message, "Type Check Error: Type check failed.");
14541454
throw;
14551455
}
14561456
},
@@ -1465,7 +1465,7 @@ TEST_F(Qasm3ParserTest, ImportQasmNegativeTypeDesignator) {
14651465
try {
14661466
const auto qc = QuantumComputation::fromQASM(testfile);
14671467
} catch (const qasm3::CompilerError& e) {
1468-
EXPECT_EQ(e.message, "Type check failed.");
1468+
EXPECT_EQ(e.message, "Type Check Error: Type check failed.");
14691469
throw;
14701470
}
14711471
},

0 commit comments

Comments
 (0)