main: add pretty errors

This commit is contained in:
augustin64 2023-11-15 15:23:33 +01:00
parent cef08d30e1
commit ced173d80f
4 changed files with 38 additions and 27 deletions

View File

@ -11,7 +11,6 @@ void pretty_print_error(vector<string> history, CodePosition pos) {
if (pos.column == -1 || pos.line == -1) if (pos.column == -1 || pos.line == -1)
return; return;
cout << pos.column << ";" << pos.line << endl;
string line = history[pos.line]; string line = history[pos.line];
printf(BOLD "%4d " RESET , pos.line+1); printf(BOLD "%4d " RESET , pos.line+1);

View File

@ -1,8 +1,9 @@
#include <string.h> #include <cstring>
#include <iostream> #include <iostream>
using namespace std; using namespace std;
#include "include/input.h" #include "include/input.h"
#include "include/errors.h"
#include "include/colors.h" #include "include/colors.h"
#include "include/parser.h" #include "include/parser.h"
#include "include/tokenize.h" #include "include/tokenize.h"
@ -20,10 +21,12 @@ int main(int argc, char* argv[]) {
i++; i++;
} }
vector<string> input;
vector<Token> tokens;
while (true) { while (true) {
try { try {
vector<string> input = get_input(); input = get_input();
vector<Token> tokens = tokenize(input); tokens = tokenize(input);
Node ast = parse(tokens); Node ast = parse(tokens);
@ -32,8 +35,11 @@ int main(int argc, char* argv[]) {
EvalResult res = eval(ast); EvalResult res = eval(ast);
cout << get<int>(res) << endl; cout << get<int>(res) << endl;
} catch (const SyntaxError& e) { } catch (const SyntaxError& e) {
cout << RED "SyntaxError: " RESET << e.what() << endl; pretty_print_error(input, e.pos);
cout << BOLD RED "Syntax Error: " RESET << e.what() << endl;
} catch (const ParseException& e) { } catch (const ParseException& e) {
cout << RED "ParsingError" RESET << endl; cout << RED "ParsingError" RESET << endl;
} }

View File

@ -64,21 +64,25 @@ Node parse(vector<Token> tokens) {
Node node = ret.node; Node node = ret.node;
while (tokens.size() != 0) { try {
ParseReturn ret = parse_instruction(tokens); while (tokens.size() != 0) {
tokens = ret.tokens; ParseReturn ret = parse_instruction(tokens);
tokens = ret.tokens;
if (!holds_alternative<InnerNode>(ret.node) || get<InnerNode>(ret.node).type != NodeType::Epsilon) { if (!holds_alternative<InnerNode>(ret.node) || get<InnerNode>(ret.node).type != NodeType::Epsilon) {
InnerNode new_node = { InnerNode new_node = {
.type=NodeType::Prog, .type=NodeType::Prog,
.children={node, ret.node}, .children={node, ret.node},
.pos=null_pos .pos=get_node_pos(ret.node)
}; };
node = new_node; node = new_node;
}
} }
return node;
} catch (const ParseException& pex) {
CodePosition pos = tokens.back().pos;
throw SyntaxError("Unable to parse", pos);
} }
return node;
} }
ParseReturn parse_instruction(vector<Token> tokens) { ParseReturn parse_instruction(vector<Token> tokens) {
@ -161,7 +165,7 @@ ParseReturn parse_expr_statement(vector<Token> tokens) {
InnerNode node = { InnerNode node = {
.type=NodeType::Declaration, .type=NodeType::Declaration,
.children={type, identifier}, .children={type, identifier},
.pos=type.pos .pos=identifier.pos
}; };
return { return {
.node=node, .node=node,
@ -178,7 +182,7 @@ ParseReturn parse_expr_statement(vector<Token> tokens) {
InnerNode node = { InnerNode node = {
.type=NodeType::AssignedDeclaration, .type=NodeType::AssignedDeclaration,
.children={type, identifier, ret.node}, .children={type, identifier, ret.node},
.pos=type.pos .pos=get_node_pos(ret.node)
}; };
return { return {
.node=node, .node=node,
@ -225,7 +229,7 @@ ParseReturn parse_expr(vector<Token> tokens) {
InnerNode new_node = { InnerNode new_node = {
.type=type, .type=type,
.children={node, ret.node}, .children={node, ret.node},
.pos=get_node_pos(node) .pos=get_node_pos(ret.node)
}; };
node = new_node; node = new_node;
} catch (const ParseException& pex) { } catch (const ParseException& pex) {
@ -286,7 +290,7 @@ ParseReturn parse_t(vector<Token> tokens) {
InnerNode new_node = { InnerNode new_node = {
.type=type, .type=type,
.children={node, ret.node}, .children={node, ret.node},
.pos=get_node_pos(node) .pos=get_node_pos(ret.node)
}; };
node = new_node; node = new_node;
} catch (const ParseException& pex) { } catch (const ParseException& pex) {
@ -419,7 +423,7 @@ ParseReturn parse_f(vector<Token> tokens) {
InnerNode node = { InnerNode node = {
.type = NodeType::Assignment, .type = NodeType::Assignment,
.children = { ret.node, ret_expr.node }, .children = { ret.node, ret_expr.node },
.pos=get_node_pos(ret.node) .pos=get_node_pos(ret_expr.node)
}; };
return { return {
.node=node, .node=node,
@ -437,14 +441,17 @@ ParseReturn parse_f(vector<Token> tokens) {
if (tokens.back().type != TokenType::LParenthese) if (tokens.back().type != TokenType::LParenthese)
throw ParseException(); throw ParseException();
CodePosition pos = tokens.back().pos;
tokens.pop_back(); tokens.pop_back();
ParseReturn ret = parse_expr(tokens); ParseReturn ret = parse_expr(tokens);
tokens=ret.tokens; tokens=ret.tokens;
_debug_print_tokens(tokens);
CodePosition pos = tokens.back().pos;
cout << pos.line << ";" << pos.column << endl;
if (tokens.size() < 1 || tokens.back().type != TokenType::RParenthese) if (tokens.size() < 1 || tokens.back().type != TokenType::RParenthese)
throw SyntaxError("Missing ')'", pos); throw SyntaxError("Missing ')'", tokens.back().pos);
tokens.pop_back(); tokens.pop_back();

View File

@ -71,9 +71,8 @@ vector<Token> tokenize(vector<string> input) {
string line = input[i]; string line = input[i];
int j = 0; int j = 0;
CodePosition pos = { .line = i, .column = j };
while (j < int(line.length())) { while (j < int(line.length())) {
CodePosition pos = { .line = i, .column = j };
string str = line.substr(j, string::npos); string str = line.substr(j, string::npos);
smatch m; smatch m;