ArkScript
A small, fast, functional and scripting language for video games
BaseParser.hpp
Go to the documentation of this file.
1#ifndef ARK_COMPILER_AST_BASEPARSER_HPP
2#define ARK_COMPILER_AST_BASEPARSER_HPP
3
4#include <string>
5#include <vector>
6#include <initializer_list>
7
8#include <Ark/Platform.hpp>
9#include <Ark/Exceptions.hpp>
12
13namespace Ark::internal
14{
15 /**
16 * @brief Describe a position in a given file ; handled by the BaseParser
17 */
19 {
20 std::size_t row = 0;
21 std::size_t col = 0;
22 };
23
25 {
26 public:
27 BaseParser() = default;
28
29 private:
30 std::string m_str;
31 std::vector<std::pair<std::string::iterator, std::size_t>> m_it_to_row; ///< A crude map of \n position to line number to speed up line number computing
32 std::string::iterator m_it, m_next_it;
33 utf8_char_t m_sym; ///< The current utf8 character we're on
34 FilePosition m_filepos; ///< The position of the cursor in the file
35
36 /**
37 * @brief Register the position of a new line, with an iterator pointing to the new line and the row number
38 *
39 * @param it
40 * @param row
41 */
42 void registerNewLine(std::string::iterator it, std::size_t row);
43
44 /**
45 * @brief getting next character and changing the values of count/row/col/sym
46 */
47 void next();
48
49 protected:
50 std::string m_filename;
51
52 void initParser(const std::string& filename, const std::string& code);
53
54 [[nodiscard]] FilePosition getCursor() const;
55
56 [[nodiscard]] CodeErrorContext generateErrorContext(const std::string& expr);
57
58 /**
59 *
60 * @param error an error message
61 * @param exp the expression causing the error
62 * @param additional_context optional context created when a node is being parsed
63 */
64 void error(const std::string& error, std::string exp, const std::optional<CodeErrorContext>& additional_context = std::nullopt);
65
66 /**
67 * @brief Fetch the next token (space and paren delimited) to generate an error
68 *
69 * @param message an error message
70 * @param additional_context optional context created when a node is being parsed
71 */
72 void errorWithNextToken(const std::string& message, const std::optional<CodeErrorContext>& additional_context = std::nullopt);
73
74 /**
75 * @brief Check for a closing char or generate an error
76 *
77 * @param suffix a suffix char, eg " or )
78 * @param context can be "string", "node" ; represents a structure
79 * @param additional_context optional context created when a node is being parsed
80 */
81 void expectSuffixOrError(char suffix, const std::string& context, const std::optional<CodeErrorContext>& additional_context = std::nullopt);
82
83 /**
84 *
85 * @return distance in characters from the beginning of the file to the cursor
86 */
87 long getCount() { return std::distance(m_str.begin(), m_it); }
88
89 /**
90 *
91 * @return file size in bytes
92 */
93 [[nodiscard]] std::size_t getSize() const { return m_str.size(); }
94
95 /**
96 *
97 * @return true if the cursor is positioned at the end of the file
98 */
99 [[nodiscard]] bool isEOF() const { return m_it == m_str.end(); }
100
101 /**
102 * @brief Backtrack to a given position (this is NOT an offset!)
103 *
104 * @param n position in the source file (byte number)
105 */
106 void backtrack(long n);
107
108 /**
109 * @brief check if a Character Predicate was able to parse, call next() if matching
110 *
111 * @param t a char predicate to match
112 * @param s optional string to append the matching chars to
113 * @return true if matched
114 */
115 bool accept(const CharPred& t, std::string* s = nullptr);
116
117 /**
118 * @brief heck if a Character Predicate was able to parse, call next() if matching ; throw a CodeError if it doesn't match
119 * @param t a char predicate to match
120 * @param s optional string to append the matching chars to
121 * @return true if matched
122 */
123 bool expect(const CharPred& t, std::string* s = nullptr);
124
125 [[nodiscard]] std::string peek() const;
126
127 // basic parsers
128
129 bool space(std::string* s = nullptr);
130 bool inlineSpace(std::string* s = nullptr);
131 bool comment(std::string* s = nullptr);
132 bool spaceComment(std::string* s = nullptr);
133 bool newlineOrComment(std::string* s = nullptr);
134 bool prefix(char c);
135 bool number(std::string* s = nullptr);
136 bool signedNumber(std::string* s = nullptr);
137 bool hexNumber(unsigned length, std::string* s = nullptr);
138 bool name(std::string* s = nullptr);
139 bool sequence(const std::string& s);
140 bool packageName(std::string* s = nullptr);
141
142 /**
143 * @brief Match any char that do not match the predicate
144 *
145 * @param delim delimiter predicate
146 * @param s optional string to append the matching chars to
147 * @return true if matched
148 */
149 bool anyUntil(const CharPred& delim, std::string* s = nullptr);
150
151 /**
152 * @brief Fetch a token and try to match one of the given words
153 *
154 * @param words list of words to match against
155 * @param s optional string to append the matching chars to
156 * @return true if matched
157 */
158 bool oneOf(std::initializer_list<std::string> words, std::string* s = nullptr);
159 };
160}
161
162#endif // ARK_COMPILER_AST_BASEPARSER_HPP
ArkScript homemade exceptions.
#define ARK_API
Definition Module.hpp:28
ArkScript configuration macros.
FilePosition m_filepos
The position of the cursor in the file.
std::size_t getSize() const
std::string::iterator m_it
std::vector< std::pair< std::string::iterator, std::size_t > > m_it_to_row
A crude map of position to line number to speed up line number computing.
utf8_char_t m_sym
The current utf8 character we're on.
Describe a position in a given file ; handled by the BaseParser.