ArkScript
A small, fast, functional and scripting language for video games
Parser.hpp
Go to the documentation of this file.
1/**
2 * @file Parser.hpp
3 * @author Alexandre Plateau ([email protected])
4 * @brief Parses a token stream into an AST by using the Ark::Node
5 * @version 0.4
6 * @date 2020-10-27
7 *
8 * @copyright Copyright (c) 2020-2021
9 *
10 */
11
12#ifndef COMPILER_AST_PARSER_HPP
13#define COMPILER_AST_PARSER_HPP
14
15#include <string>
16#include <list>
17#include <ostream>
18#include <vector>
19#include <cinttypes>
20
21#include <Ark/Constants.hpp>
24
25namespace Ark::internal
26{
28 {
29 if (tt == TokenType::Capture)
30 return NodeType::Capture;
31 else if (tt == TokenType::GetField)
32 return NodeType::GetField;
33 else if (tt == TokenType::Spread)
34 return NodeType::Spread;
35
36 return NodeType::Symbol;
37 }
38
39 /**
40 * @brief The parser is responsible of constructing the Abstract Syntax Tree from a token list
41 *
42 */
43 class Parser
44 {
45 public:
46 /**
47 * @brief Construct a new Parser object
48 *
49 * @param debug the debug level
50 * @param options the parsing options
51 * @param lib_env fallback library search path
52 */
53 Parser(unsigned debug, uint16_t options, const std::vector<std::string>& lib_env) noexcept;
54
55 /**
56 * @brief Give the code to parse
57 *
58 * @param code the ArkScript code
59 * @param filename the name of the file
60 */
61 void feed(const std::string& code, const std::string& filename = ARK_NO_NAME_FILE);
62
63 /**
64 * @brief Return the generated AST
65 *
66 * @return const Node&
67 */
68 const Node& ast() const noexcept;
69
70 /**
71 * @brief Return the list of files imported by the code given to the parser
72 *
73 * Each path of each imported file is relative to the filename given when feeding the parser.
74 *
75 * @return const std::vector<std::string>&
76 */
77 const std::vector<std::string>& getImports() const noexcept;
78
79 friend std::ostream& operator<<(std::ostream& os, const Parser& P) noexcept;
80
81 private:
82 unsigned m_debug;
83 std::vector<std::string> m_libenv;
84 uint16_t m_options;
88
89 // path of the current file
90 std::string m_file;
91 // source code of the current file
92 std::string m_code;
93 // the files included by the "includer" to avoid multiple includes
94 std::vector<std::string> m_parent_include;
95
96 /**
97 * @brief Applying syntactic sugar: {...} => (begin...), [...] => (list ...)
98 *
99 * @param tokens a list of tokens
100 */
101 void sugar(std::vector<Token>& tokens) noexcept;
102
103 /**
104 * @brief Parse a list of tokens recursively
105 *
106 * @param tokens
107 * @param authorize_capture if we are authorized to consume TokenType::Capture tokens
108 * @param authorize_field_read if we are authorized to consume TokenType::GetField tokens
109 * @param in_macro if we are in a macro, there a bunch of things we can tolerate
110 * @return Node
111 */
112 Node parse(std::list<Token>& tokens, bool authorize_capture = false, bool authorize_field_read = false, bool in_macro = false);
113
114 void parseIf(Node&, std::list<Token>&, bool);
115 void parseLetMut(Node&, Token&, std::list<Token>&, bool);
116 void parseSet(Node&, Token&, std::list<Token>&, bool);
117 void parseFun(Node&, Token&, std::list<Token>&, bool);
118 void parseWhile(Node&, Token&, std::list<Token>&, bool);
119 void parseBegin(Node&, std::list<Token>&, bool);
120 void parseImport(Node&, std::list<Token>&);
121 void parseQuote(Node&, std::list<Token>&, bool);
122 void parseDel(Node&, std::list<Token>&);
123 Node parseShorthand(Token&, std::list<Token>&, bool);
124 void checkForInvalidTokens(Node&, Token&, bool, bool, bool);
125
126 /**
127 * @brief Get the next token if possible, from a list of tokens
128 *
129 * The list of tokens is modified.
130 *
131 * @param tokens list of tokens to get the next token from
132 * @return Token
133 */
134 Token nextToken(std::list<Token>& tokens);
135
136 /**
137 * @brief Convert a token to a node
138 *
139 * @param token the token to converts
140 * @return Node
141 */
142 Node atom(const Token& token);
143
144 /**
145 * @brief Search for all the includes in a given node, in its sub-nodes and replace them by the code of the included file
146 *
147 * @param n
148 * @param parent the parent node of the current one
149 * @param pos the position of the child node in the parent node list
150 * @return true if we found an import and replaced it by the corresponding code
151 */
152 bool checkForInclude(Node& n, Node& parent, std::size_t pos = 0);
153
154 /**
155 * @brief Seek a file in the lib folder and everywhere
156 *
157 * @param file
158 * @return std::string
159 */
160 std::string seekFile(const std::string& file);
161
162 /**
163 * @brief Throw a parse exception is the given predicated is false
164 *
165 * @param pred
166 * @param message error message to use
167 * @param token concerned token
168 */
169 void expect(bool pred, const std::string& message, Token token);
170
171 /**
172 * @brief Throw a parse error related to a token (seek it in the related file and highlight the error)
173 *
174 * @param message
175 * @param token
176 */
177 [[noreturn]] void throwParseError(const std::string& message, Token token);
178 };
179}
180
181#endif
Constants used by ArkScript.
#define ARK_NO_NAME_FILE
Definition: Constants.hpp:26
Tokenize ArkScript code.
AST node used by the parser, optimizer and compiler.
The lexer, in charge of creating a list of tokens.
Definition: Lexer.hpp:27
A node of an Abstract Syntax Tree for ArkScript.
Definition: Node.hpp:29
The parser is responsible of constructing the Abstract Syntax Tree from a token list.
Definition: Parser.hpp:44
void parseImport(Node &, std::list< Token > &)
Definition: Parser.cpp:321
void parseBegin(Node &, std::list< Token > &, bool)
Definition: Parser.cpp:308
std::string m_code
Definition: Parser.hpp:92
void parseLetMut(Node &, Token &, std::list< Token > &, bool)
Definition: Parser.cpp:227
void parseDel(Node &, std::list< Token > &)
Definition: Parser.cpp:336
Node atom(const Token &token)
Convert a token to a node.
Definition: Parser.cpp:411
uint16_t m_options
Definition: Parser.hpp:84
void sugar(std::vector< Token > &tokens) noexcept
Applying syntactic sugar: {...} => (begin...), [...] => (list ...)
Definition: Parser.cpp:69
friend std::ostream & operator<<(std::ostream &os, const Parser &P) noexcept
Definition: Parser.cpp:597
void expect(bool pred, const std::string &message, Token token)
Throw a parse exception is the given predicated is false.
Definition: Parser.cpp:579
const Node & ast() const noexcept
Return the generated AST.
Definition: Parser.cpp:59
void parseQuote(Node &, std::list< Token > &, bool)
Definition: Parser.cpp:330
void feed(const std::string &code, const std::string &filename=ARK_NO_NAME_FILE)
Give the code to parse.
Definition: Parser.cpp:21
void throwParseError(const std::string &message, Token token)
Throw a parse error related to a token (seek it in the related file and highlight the error)
Definition: Parser.cpp:585
std::string seekFile(const std::string &file)
Seek a file in the lib folder and everywhere.
Definition: Parser.cpp:547
std::vector< std::string > m_libenv
Definition: Parser.hpp:83
std::string m_file
Definition: Parser.hpp:90
void parseFun(Node &, Token &, std::list< Token > &, bool)
Definition: Parser.cpp:276
void parseSet(Node &, Token &, std::list< Token > &, bool)
Definition: Parser.cpp:250
void checkForInvalidTokens(Node &, Token &, bool, bool, bool)
Definition: Parser.cpp:377
void parseIf(Node &, std::list< Token > &, bool)
Definition: Parser.cpp:204
Node parse(std::list< Token > &tokens, bool authorize_capture=false, bool authorize_field_read=false, bool in_macro=false)
Parse a list of tokens recursively.
Definition: Parser.cpp:102
std::vector< std::string > m_parent_include
Definition: Parser.hpp:94
void parseWhile(Node &, Token &, std::list< Token > &, bool)
Definition: Parser.cpp:291
bool checkForInclude(Node &n, Node &parent, std::size_t pos=0)
Search for all the includes in a given node, in its sub-nodes and replace them by the code of the inc...
Definition: Parser.cpp:480
Node parseShorthand(Token &, std::list< Token > &, bool)
Definition: Parser.cpp:345
Token nextToken(std::list< Token > &tokens)
Get the next token if possible, from a list of tokens.
Definition: Parser.cpp:401
const std::vector< std::string > & getImports() const noexcept
Return the list of files imported by the code given to the parser.
Definition: Parser.cpp:64
NodeType
The different node types available.
Definition: Common.hpp:29
NodeType similarNodetypeFromTokentype(TokenType tt)
Definition: Parser.hpp:27