-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f436493
commit 01e0bb9
Showing
8 changed files
with
115 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#pragma once | ||
|
||
#include "BaseErrorListener.h" | ||
#include "antlr4-runtime.h" | ||
|
||
#define _NC "\033[0m" | ||
#define _RED "\033[0;31m" | ||
#define _BLUE "\033[0;34m" | ||
|
||
class LexerErrorListener : public antlr4::BaseErrorListener { | ||
public: | ||
void syntaxError(antlr4::Recognizer* recognizer, | ||
antlr4::Token* offending_symbol, | ||
size_t line, | ||
size_t char_position_in_line, | ||
const std::string& msg, | ||
std::exception_ptr e) override; | ||
}; | ||
|
||
class SyntaxErrorListener : public antlr4::BaseErrorListener { | ||
public: | ||
void syntaxError(antlr4::Recognizer* recognizer, | ||
antlr4::Token* offending_symbol, | ||
size_t line, | ||
size_t char_position_in_line, | ||
const std::string& msg, | ||
std::exception_ptr e) override; | ||
}; | ||
|
||
void underline_error(antlr4::Recognizer* recognizer, | ||
antlr4::Token* offending_symbol, | ||
size_t line, | ||
size_t char_position_in_line, | ||
std::ostream& out); | ||
|
||
void show_rule_stack(antlr4::Recognizer* recognizer, std::ostream& out); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
#include "errors/syntax.h" | ||
#include "errors/errors.h" | ||
|
||
void SyntaxErrorListener::syntaxError(antlr4::Recognizer* recognizer, | ||
antlr4::Token* offending_symbol, | ||
size_t line, | ||
size_t char_position_in_line, | ||
const std::string& msg, | ||
std::exception_ptr e) { | ||
std::ostringstream out; | ||
underline_error(recognizer, offending_symbol, line, char_position_in_line, | ||
out); | ||
show_rule_stack(recognizer, out); | ||
throw SyntaxError(line, msg + out.rdbuf()->str()); | ||
} | ||
|
||
void LexerErrorListener::syntaxError(antlr4::Recognizer* recognizer, | ||
antlr4::Token* offending_symbol, | ||
size_t line, | ||
size_t char_position_in_line, | ||
const std::string& msg, | ||
std::exception_ptr e) { | ||
throw SyntaxError(line, msg); | ||
} | ||
|
||
void underline_error(antlr4::Recognizer* recognizer, | ||
antlr4::Token* offending_symbol, | ||
size_t line, | ||
size_t char_position_in_line, | ||
std::ostream& out) { | ||
auto tokens = | ||
dynamic_cast<antlr4::CommonTokenStream*>(recognizer->getInputStream()); | ||
auto input = tokens->getTokenSource()->getInputStream()->toString(); | ||
std::string error_line = "\n"; | ||
for (size_t i = 0, line_counter = 0; | ||
i < input.size() && line_counter <= line; i++) { | ||
if (input[i] == '\n') { | ||
line_counter++; | ||
} else if (line_counter == line - 1) { | ||
error_line += input[i]; | ||
} | ||
} | ||
auto length = offending_symbol->getStopIndex() - | ||
offending_symbol->getStartIndex() + 1; | ||
out << error_line << std::endl | ||
<< _RED << std::string(char_position_in_line, ' ') | ||
<< std::string(length, '^') << _NC << std::endl; | ||
} | ||
|
||
void show_rule_stack(antlr4::Recognizer* recognizer, std::ostream& out) { | ||
auto parser = dynamic_cast<antlr4::Parser*>(recognizer); | ||
auto rule_stack = parser->getRuleInvocationStack(); | ||
out << "Rule stack:" << std::endl; | ||
size_t i = rule_stack.size(); | ||
out << _BLUE << rule_stack[--i] << std::endl; | ||
for (size_t indent_level = 0; i-- > 0; indent_level++) { | ||
out << std::string(indent_level * 2, ' ') << "└─" << rule_stack[i] | ||
<< std::endl; | ||
} | ||
out << _NC; | ||
} |