More detailed error messages for lex errors.
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Deukhoofd 2021-01-06 00:25:08 +01:00
parent 2327134e36
commit 807fe63828
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
5 changed files with 21 additions and 13 deletions

View File

@ -4,7 +4,7 @@
namespace MalachScript::Diagnostics {
enum class DiagnosticType : uint8_t {
UnknownToken,
UnknownCharacter,
InvalidNumericalBase,
ExpectedEndOfString,
UnexpectedToken,

View File

@ -9,9 +9,12 @@ namespace MalachScript::Diagnostics {
public:
static std::string ToEnglishString(const Diagnostic* diag) {
switch (diag->GetType()) {
case DiagnosticType::UnknownToken: return "Unknown token";
case DiagnosticType::InvalidNumericalBase: return "Invalid numerical base";
case DiagnosticType::ExpectedEndOfString: return "Expected end of string";
case DiagnosticType::UnknownCharacter:
return util::Format("Unknown character: '{0}'", diag->GetFormats());
case DiagnosticType::InvalidNumericalBase:
return util::Format("Invalid numerical base: '0{0}'", diag->GetFormats());
case DiagnosticType::ExpectedEndOfString:
return util::Format("Expected end of string, found {0}", diag->GetFormats());
case DiagnosticType::UnexpectedToken:
return util::Format("Unexpected Token. Expected any of: {0}, but found {1}", diag->GetFormats());
case DiagnosticType::DoubleProperty: return "Property block found twice.";

View File

@ -22,8 +22,9 @@ namespace MalachScript::Diagnostics {
inline void LogWarning(DiagnosticType type, std::u8string_view scriptName, TextSpan span) {
Log(DiagnosticLevel::Warning, type, scriptName, span);
}
inline void LogError(DiagnosticType type, std::u8string_view scriptName, TextSpan span) {
Log(DiagnosticLevel::Error, type, scriptName, span);
inline void LogError(DiagnosticType type, std::u8string_view scriptName, TextSpan span,
const std::vector<std::string>& formats = {}) {
Log(DiagnosticLevel::Error, type, scriptName, span, formats);
}
inline void LogCritical(DiagnosticType type, std::u8string_view scriptName, TextSpan span) {
Log(DiagnosticLevel::Critical, type, scriptName, span);

View File

@ -254,7 +254,8 @@ namespace MalachScript::Parser {
Progress(2);
return Create<LexTokenImpl<LexTokenKind::Whitespace>>(TextSpan(start, start + 3));
}
LogError(Diagnostics::DiagnosticType::UnknownToken, TextSpan(start, start + 1));
LogError(Diagnostics::DiagnosticType::UnknownCharacter, TextSpan(start, start + 1),
{std::string(1, c)});
return Create<LexTokenImpl<LexTokenKind::Unknown>>(TextSpan(start, start + 1));
}
case u8'0':
@ -278,7 +279,8 @@ namespace MalachScript::Parser {
default:
if (IsAlphaNumericalOrUnderscore(c))
return LexKeywordOrIdentifier();
LogError(Diagnostics::DiagnosticType::UnknownToken, TextSpan(start, start + 1));
LogError(Diagnostics::DiagnosticType::UnknownCharacter, TextSpan(start, start + 1),
{std::string(1, (char)c)});
return Create<LexTokenImpl<LexTokenKind::Unknown>>(TextSpan(start, start + 1));
}
}
@ -302,7 +304,7 @@ namespace MalachScript::Parser {
case 'B': numericalSystem = 2; break;
default:
LogError(Diagnostics::DiagnosticType::InvalidNumericalBase,
TextSpan(_position - 1, _position + 1));
TextSpan(_position - 1, _position + 1), {std::string(1, secondChar)});
// Set to the largest numerical system, so we can prevent errors down the line.
numericalSystem = 16;
break;
@ -449,11 +451,13 @@ namespace MalachScript::Parser {
break;
}
if (current == u8'\0') {
LogError(Diagnostics::DiagnosticType::ExpectedEndOfString, TextSpan(start, start + offset));
LogError(Diagnostics::DiagnosticType::ExpectedEndOfString, TextSpan(start, start + offset),
{"EndOfFile"});
break;
}
if (!heredoc && (current == u8'\n' || current == u8'\r')) {
LogError(Diagnostics::DiagnosticType::ExpectedEndOfString, TextSpan(start, start + offset));
LogError(Diagnostics::DiagnosticType::ExpectedEndOfString, TextSpan(start, start + offset),
{"Newline"});
break;
}
offset++;

View File

@ -57,8 +57,8 @@ namespace MalachScript::Parser {
return _allocator.Create<T>(args...);
}
inline void LogError(Diagnostics::DiagnosticType type, TextSpan span) {
_diagnostics->LogError(type, _scriptName, span);
inline void LogError(Diagnostics::DiagnosticType type, TextSpan span, const std::vector<std::string>& formats) {
_diagnostics->LogError(type, _scriptName, span, formats);
}
};
}