diff --git a/src/include/parser.h b/src/include/parser.h index 47701e3..ef2f4ce 100644 --- a/src/include/parser.h +++ b/src/include/parser.h @@ -89,6 +89,7 @@ using Node = variant; struct InnerNode { NodeType type; vector children; + CodePosition pos; }; // A Leaf is always corresponding to a Token @@ -170,4 +171,9 @@ ParseReturn parse_par_identifier(vector tokens); */ void _debug_print_tree(const Node& node, int depth, const string& prefix); +/** + * Returns the CodePosition of a node +*/ +CodePosition get_node_pos(Node node); + #endif \ No newline at end of file diff --git a/src/parser.cpp b/src/parser.cpp index 6f5aed5..e85ec2d 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -6,6 +6,11 @@ using namespace std; #include "include/colors.h" #include "include/parser.h" +CodePosition null_pos = { + .line = -1, + .column = -1 +}; + const char* _node_names[] = {"Prog", "Epsilon", "AssignedDeclaration", "Declaration", "Plus", "Minus", "Mult", "Div", "Mod", "UnaryMinus", "UnaryPlus", "Assignment", "LIncr", "RIncr", "LDecr", "RDecr"}; void _debug_print_tree(const Node& node, int depth, const string& prefix = "") { @@ -39,16 +44,17 @@ void _debug_print_tree(const Node& node, int depth, const string& prefix = "") { } } +CodePosition get_node_pos(Node node) { + if (holds_alternative(node)) + return get(node).pos; + return get(node).pos; +} Node parse(vector tokens) { reverse(tokens.begin(), tokens.end()); if (tokens.size() == 0) { - CodePosition pos = { - .line = -1, - .column = -1 - }; - throw SyntaxError("Input must not be empty", pos); + throw SyntaxError("Input must not be empty", null_pos); } @@ -65,7 +71,8 @@ Node parse(vector tokens) { if (!holds_alternative(ret.node) || get(ret.node).type != NodeType::Epsilon) { InnerNode new_node = { .type=NodeType::Prog, - .children={node, ret.node} + .children={node, ret.node}, + .pos=null_pos }; node = new_node; } @@ -114,7 +121,8 @@ ParseReturn parse_instruction(vector tokens) { vector children; InnerNode epsilon_node = { .type=NodeType::Epsilon, - .children=children + .children=children, + .pos=null_pos }; tokens.pop_back(); // On enlève le ';' de la liste de tokens @@ -152,7 +160,8 @@ ParseReturn parse_expr_statement(vector tokens) { if (tokens.size() < 1 || tokens.back().type != TokenType::Equal) { InnerNode node = { .type=NodeType::Declaration, - .children={type, identifier} + .children={type, identifier}, + .pos=type.pos }; return { .node=node, @@ -167,8 +176,9 @@ ParseReturn parse_expr_statement(vector tokens) { ret = parse_expr(tokens); InnerNode node = { - .type=NodeType::AssignedDeclaration, - .children={type, identifier, ret.node} + .type=NodeType::AssignedDeclaration, + .children={type, identifier, ret.node}, + .pos=type.pos }; return { .node=node, @@ -214,7 +224,8 @@ ParseReturn parse_expr(vector tokens) { InnerNode new_node = { .type=type, - .children={node, ret.node} + .children={node, ret.node}, + .pos=get_node_pos(node) }; node = new_node; } catch (const ParseException& pex) { @@ -274,7 +285,8 @@ ParseReturn parse_t(vector tokens) { InnerNode new_node = { .type=type, - .children={node, ret.node} + .children={node, ret.node}, + .pos=get_node_pos(node) }; node = new_node; } catch (const ParseException& pex) { @@ -300,7 +312,8 @@ ParseReturn parse_u(vector tokens) { InnerNode node = { .type=NodeType::UnaryMinus, - .children={ ret.node } + .children={ ret.node }, + .pos=get_node_pos(ret.node) }; return { .node=node, @@ -315,7 +328,8 @@ ParseReturn parse_u(vector tokens) { InnerNode node = { .type=NodeType::UnaryPlus, - .children={ ret.node } + .children={ ret.node }, + .pos=get_node_pos(ret.node) }; return { .node=node, @@ -346,7 +360,8 @@ ParseReturn parse_f(vector tokens) { InnerNode node = { .type = NodeType::LIncr, - .children = { ret.node } + .children = { ret.node }, + .pos=get_node_pos(ret.node) }; return { .node=node, @@ -359,7 +374,8 @@ ParseReturn parse_f(vector tokens) { InnerNode node = { .type = NodeType::LDecr, - .children = { ret.node } + .children = { ret.node }, + .pos=get_node_pos(ret.node) }; return { .node=node, @@ -376,7 +392,8 @@ ParseReturn parse_f(vector tokens) { ret.tokens.pop_back(); InnerNode node = { .type = NodeType::RIncr, - .children = { ret.node } + .children = { ret.node }, + .pos=get_node_pos(ret.node) }; return { .node=node, @@ -387,7 +404,8 @@ ParseReturn parse_f(vector tokens) { ret.tokens.pop_back(); InnerNode node = { .type = NodeType::RDecr, - .children = { ret.node } + .children = { ret.node }, + .pos=get_node_pos(ret.node) }; return { .node=node, @@ -400,7 +418,8 @@ ParseReturn parse_f(vector tokens) { InnerNode node = { .type = NodeType::Assignment, - .children = { ret.node, ret_expr.node } + .children = { ret.node, ret_expr.node }, + .pos=get_node_pos(ret.node) }; return { .node=node, @@ -418,17 +437,14 @@ ParseReturn parse_f(vector tokens) { if (tokens.back().type != TokenType::LParenthese) throw ParseException(); + CodePosition pos = tokens.back().pos; tokens.pop_back(); + ParseReturn ret = parse_expr(tokens); tokens=ret.tokens; - if (tokens.size() < 1 || tokens.back().type != TokenType::RParenthese) { - CodePosition pos = { - .line = -1, - .column = -1 - }; + if (tokens.size() < 1 || tokens.back().type != TokenType::RParenthese) throw SyntaxError("Missing ')'", pos); - } tokens.pop_back();