Add CodePosition to AST

This commit is contained in:
augustin64 2023-11-15 14:59:28 +01:00
parent 1cc9868567
commit cef08d30e1
2 changed files with 47 additions and 25 deletions

View File

@ -89,6 +89,7 @@ using Node = variant<InnerNode, Token>;
struct InnerNode { struct InnerNode {
NodeType type; NodeType type;
vector<Node> children; vector<Node> children;
CodePosition pos;
}; };
// A Leaf is always corresponding to a Token // A Leaf is always corresponding to a Token
@ -170,4 +171,9 @@ ParseReturn parse_par_identifier(vector<Token> tokens);
*/ */
void _debug_print_tree(const Node& node, int depth, const string& prefix); 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 #endif

View File

@ -6,6 +6,11 @@ using namespace std;
#include "include/colors.h" #include "include/colors.h"
#include "include/parser.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"}; 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 = "") { 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<InnerNode>(node))
return get<InnerNode>(node).pos;
return get<Token>(node).pos;
}
Node parse(vector<Token> tokens) { Node parse(vector<Token> tokens) {
reverse(tokens.begin(), tokens.end()); reverse(tokens.begin(), tokens.end());
if (tokens.size() == 0) { if (tokens.size() == 0) {
CodePosition pos = { throw SyntaxError("Input must not be empty", null_pos);
.line = -1,
.column = -1
};
throw SyntaxError("Input must not be empty", pos);
} }
@ -65,7 +71,8 @@ Node parse(vector<Token> 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
}; };
node = new_node; node = new_node;
} }
@ -114,7 +121,8 @@ ParseReturn parse_instruction(vector<Token> tokens) {
vector<Node> children; vector<Node> children;
InnerNode epsilon_node = { InnerNode epsilon_node = {
.type=NodeType::Epsilon, .type=NodeType::Epsilon,
.children=children .children=children,
.pos=null_pos
}; };
tokens.pop_back(); // On enlève le ';' de la liste de tokens tokens.pop_back(); // On enlève le ';' de la liste de tokens
@ -152,7 +160,8 @@ ParseReturn parse_expr_statement(vector<Token> tokens) {
if (tokens.size() < 1 || tokens.back().type != TokenType::Equal) { if (tokens.size() < 1 || tokens.back().type != TokenType::Equal) {
InnerNode node = { InnerNode node = {
.type=NodeType::Declaration, .type=NodeType::Declaration,
.children={type, identifier} .children={type, identifier},
.pos=type.pos
}; };
return { return {
.node=node, .node=node,
@ -168,7 +177,8 @@ 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
}; };
return { return {
.node=node, .node=node,
@ -214,7 +224,8 @@ 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)
}; };
node = new_node; node = new_node;
} catch (const ParseException& pex) { } catch (const ParseException& pex) {
@ -274,7 +285,8 @@ 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)
}; };
node = new_node; node = new_node;
} catch (const ParseException& pex) { } catch (const ParseException& pex) {
@ -300,7 +312,8 @@ ParseReturn parse_u(vector<Token> tokens) {
InnerNode node = { InnerNode node = {
.type=NodeType::UnaryMinus, .type=NodeType::UnaryMinus,
.children={ ret.node } .children={ ret.node },
.pos=get_node_pos(ret.node)
}; };
return { return {
.node=node, .node=node,
@ -315,7 +328,8 @@ ParseReturn parse_u(vector<Token> tokens) {
InnerNode node = { InnerNode node = {
.type=NodeType::UnaryPlus, .type=NodeType::UnaryPlus,
.children={ ret.node } .children={ ret.node },
.pos=get_node_pos(ret.node)
}; };
return { return {
.node=node, .node=node,
@ -346,7 +360,8 @@ ParseReturn parse_f(vector<Token> tokens) {
InnerNode node = { InnerNode node = {
.type = NodeType::LIncr, .type = NodeType::LIncr,
.children = { ret.node } .children = { ret.node },
.pos=get_node_pos(ret.node)
}; };
return { return {
.node=node, .node=node,
@ -359,7 +374,8 @@ ParseReturn parse_f(vector<Token> tokens) {
InnerNode node = { InnerNode node = {
.type = NodeType::LDecr, .type = NodeType::LDecr,
.children = { ret.node } .children = { ret.node },
.pos=get_node_pos(ret.node)
}; };
return { return {
.node=node, .node=node,
@ -376,7 +392,8 @@ ParseReturn parse_f(vector<Token> tokens) {
ret.tokens.pop_back(); ret.tokens.pop_back();
InnerNode node = { InnerNode node = {
.type = NodeType::RIncr, .type = NodeType::RIncr,
.children = { ret.node } .children = { ret.node },
.pos=get_node_pos(ret.node)
}; };
return { return {
.node=node, .node=node,
@ -387,7 +404,8 @@ ParseReturn parse_f(vector<Token> tokens) {
ret.tokens.pop_back(); ret.tokens.pop_back();
InnerNode node = { InnerNode node = {
.type = NodeType::RDecr, .type = NodeType::RDecr,
.children = { ret.node } .children = { ret.node },
.pos=get_node_pos(ret.node)
}; };
return { return {
.node=node, .node=node,
@ -400,7 +418,8 @@ 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)
}; };
return { return {
.node=node, .node=node,
@ -418,17 +437,14 @@ 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;
if (tokens.size() < 1 || tokens.back().type != TokenType::RParenthese) { if (tokens.size() < 1 || tokens.back().type != TokenType::RParenthese)
CodePosition pos = {
.line = -1,
.column = -1
};
throw SyntaxError("Missing ')'", pos); throw SyntaxError("Missing ')'", pos);
}
tokens.pop_back(); tokens.pop_back();