ArkScript
A small, lisp-inspired, functional scripting language
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
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 generateErrorContextAtCurrentPosition() const;
57
58 /**
59 * @brief Create an error context and throw an error containing said context
60 *
61 * @param error an error message
62 * @param start_at position in the file where the parsing for the erroneous token started
63 * @param additional_context optional context created when a node is being parsed
64 */
65 void error(const std::string& error, FilePosition start_at, const std::optional<CodeErrorContext>& additional_context = std::nullopt) const;
66
67 /**
68 * @brief Fetch the next token (space and paren delimited) to generate an error
69 *
70 * @param message an error message
71 * @param additional_context optional context created when a node is being parsed
72 */
73 void errorWithNextToken(const std::string& message, const std::optional<CodeErrorContext>& additional_context = std::nullopt);
74
75 /**
76 * @brief Check for a closing char or generate an error
77 *
78 * @param suffix a suffix char, eg " or )
79 * @param context can be "string", "node" ; represents a structure
80 * @param additional_context optional context created when a node is being parsed
81 */
82 void expectSuffixOrError(char suffix, const std::string& context, const std::optional<CodeErrorContext>& additional_context = std::nullopt);
83
84 /**
85 *
86 * @return distance in characters from the beginning of the file to the cursor
87 */
88 long getCount() { return static_cast<long>(std::distance(m_str.begin(), m_it)); }
89
90 /**
91 *
92 * @return file size in bytes
93 */
94 [[nodiscard]] std::size_t getSize() const { return m_str.size(); }
95
96 /**
97 *
98 * @return true if the cursor is positioned at the end of the file
99 */
100 [[nodiscard]] bool isEOF() const { return m_it == m_str.end(); }
101
102 /**
103 * @brief Backtrack to a given position (this is NOT an offset!)
104 *
105 * @param n position in the source file (byte number)
106 */
107 void backtrack(long n);
108
109 /**
110 * @brief check if a Character Predicate was able to parse, call next() if matching
111 *
112 * @param t a char predicate to match
113 * @param s optional string to append the matching chars to
114 * @return true if matched
115 */
116 bool accept(const CharPred& t, std::string* s = nullptr);
117
118 /**
119 * @brief heck if a Character Predicate was able to parse, call next() if matching ; throw a CodeError if it doesn't match
120 * @param t a char predicate to match
121 * @param s optional string to append the matching chars to
122 * @return true if matched
123 */
124 bool expect(const CharPred& t, std::string* s = nullptr);
125
126 [[nodiscard]] std::string peek() const;
127
128 // basic parsers
129
130 bool space(std::string* s = nullptr);
131 bool inlineSpace(std::string* s = nullptr);
132 bool comment(std::string* s = nullptr);
133 [[nodiscard]] std::string spaceComment();
134 [[nodiscard]] std::string newlineOrComment();
135 bool prefix(char c);
136 bool number(std::string* s = nullptr);
137 bool signedNumber(std::string* s = nullptr);
138 bool hexNumber(unsigned length, std::string* s = nullptr);
139 bool name(std::string* s = nullptr);
140 bool sequence(const std::string& s);
141 bool packageName(std::string* s = nullptr);
142
143 /**
144 * @brief Match any char that do not match the predicate
145 *
146 * @param delim delimiter predicate
147 * @param s optional string to append the matching chars to
148 * @return true if matched
149 */
150 bool anyUntil(const CharPred& delim, std::string* s = nullptr);
151
152 /**
153 * @brief Fetch a token and try to match one of the given words
154 *
155 * @param words list of words to match against
156 * @param s optional string to append the matching chars to
157 * @return true if matched
158 */
159 bool oneOf(std::initializer_list<std::string> words, std::string* s = nullptr);
160 };
161}
162
163#endif // ARK_COMPILER_AST_BASEPARSER_HPP
ArkScript homemade exceptions.
#define ARK_API
Definition Module.hpp:22
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.