diff --git a/.clang-format b/.clang-format index 5f8be78..7911803 100644 --- a/.clang-format +++ b/.clang-format @@ -81,6 +81,8 @@ IfMacros: - KJ_IF_MAYBE IncludeBlocks: Regroup IncludeCategories: + - Regex: '^$' + Priority: 3 - Regex: '^$' Priority: 3 - Regex: '^$' diff --git a/bootstrap/error.cc b/bootstrap/error.cc new file mode 100644 index 0000000..0ccc5d2 --- /dev/null +++ b/bootstrap/error.cc @@ -0,0 +1,23 @@ +#include +#include + +namespace xlang { + +ErrorListener::ErrorListener(std::string_view inputfile) + : file{inputfile}, has_error{false} {} + +bool ErrorListener::hasError() { + return has_error; +} + +void ErrorListener::syntaxError([[maybe_unused]] antlr4::Recognizer *recognizer, + [[maybe_unused]] antlr4::Token *offendingSymbol, + size_t line, size_t charPositionInLine, + const std::string &msg, + [[maybe_unused]] std::exception_ptr e) { + std::cerr << file << ":" << line << ":" << charPositionInLine << ": " << msg + << std::endl; + has_error = true; +} + +} // namespace xlang diff --git a/bootstrap/error.hh b/bootstrap/error.hh new file mode 100644 index 0000000..7772106 --- /dev/null +++ b/bootstrap/error.hh @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +namespace xlang { + +class ErrorListener : public antlr4::BaseErrorListener { + std::string_view file; + bool has_error; + + public: + ErrorListener(std::string_view inputfile); + bool hasError(); + void syntaxError(antlr4::Recognizer *recognizer, + antlr4::Token *offendingSymbol, size_t line, + size_t charPositionInLine, const std::string &msg, + std::exception_ptr e) override; +}; + +} // namespace xlang diff --git a/bootstrap/main.cc b/bootstrap/main.cc index 888b0b7..0ea2670 100644 --- a/bootstrap/main.cc +++ b/bootstrap/main.cc @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -41,7 +42,14 @@ int main(int argc, char **argv) { xlang::xlangLexer lexer{&input}; antlr4::CommonTokenStream tokens{&lexer}; xlang::xlangParser parser{&tokens}; + xlang::ErrorListener errorlistener{inputfile}; + + parser.removeErrorListeners(); + parser.addErrorListener(&errorlistener); auto *tree = parser.file(); + if (errorlistener.hasError()) { + exit(1); + } xlang::EmitVisitor emit{outputfile}; emit.visitFile(tree); diff --git a/bootstrap/meson.build b/bootstrap/meson.build index 989be3d..6fa7c8e 100644 --- a/bootstrap/meson.build +++ b/bootstrap/meson.build @@ -2,6 +2,7 @@ xc_exe = executable('xc', sources : [ 'main.cc', 'emit.cc', + 'error.cc', antlr4.process('xlang.g4'), ], dependencies : [