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 {
NodeType type;
vector<Node> children;
CodePosition pos;
};
// 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);
/**
* Returns the CodePosition of a node
*/
CodePosition get_node_pos(Node node);
#endif

View File

@ -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<InnerNode>(node))
return get<InnerNode>(node).pos;
return get<Token>(node).pos;
}
Node parse(vector<Token> 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<Token> tokens) {
if (!holds_alternative<InnerNode>(ret.node) || get<InnerNode>(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<Token> tokens) {
vector<Node> 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<Token> 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<Token> 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<Token> 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<Token> 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<Token> 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<Token> 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<Token> 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<Token> 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<Token> 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<Token> 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<Token> 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<Token> 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();