Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
Compiler_Parser_Utils.H
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
43#ifndef COMPILER_PARSER_UTILS_H
44#define COMPILER_PARSER_UTILS_H
45
46#include <string>
47#include <string_view>
48
49#include <Compiler_Lexer.H>
50
51namespace Aleph {
77
79inline bool compiler_is_statement_start(const Compiler_Token_Kind kind) noexcept
80{
81 switch (kind)
82 {
90 return true;
91 default:
93 }
94}
95
98{
99 switch (kind)
100 {
106 return true;
107 default:
108 return false;
109 }
110}
111
113inline std::string compiler_unquote_string_token(const Compiler_Token &token)
114{
116 return token.lexeme;
117 if (token.lexeme.size() >= 2 and token.lexeme.front() == '"' and token.lexeme.back() == '"')
118 return token.lexeme.substr(1, token.lexeme.size() - 2);
119 return token.lexeme;
120}
121
129{
132
133 void emit_error(const Source_Span &span,
134 const std::string &message,
135 const std::string &code,
136 const std::string &note = "",
137 const std::string &help = "") const
138 {
139 if (diagnostics == nullptr)
140 return;
141
142 auto builder = diagnostics->error(span, message).code(code);
143 if (not note.empty())
144 builder.note(note);
145 if (not help.empty())
146 builder.help(help);
147 builder.emit();
148 }
149
150public:
155
158 {
159 return lexer->peek();
160 }
161
164 {
165 return lexer->next();
166 }
167
170 {
171 return peek().kind == kind;
172 }
173
175 bool match(const Compiler_Token_Kind kind)
176 {
177 if (not check(kind))
178 return false;
179 (void) next();
180 return true;
181 }
182
185 const std::string &message,
186 const std::string &code,
187 const std::string &note = "",
188 const std::string &help = "")
189 {
190 const auto tok = peek();
191 if (tok.kind == kind)
192 return next();
193
194 emit_error(tok.span, message, code, note, help);
195 return {kind, "", tok.span};
196 }
197
199 [[nodiscard]] Compiler_Token expect_identifier(const std::string_view context,
200 const std::string &code = "PAR002")
201 {
202 const auto tok = peek();
204 return next();
205
206 emit_error(tok.span, "expected identifier " + std::string(context), code);
207 return {Compiler_Token_Kind::Identifier, "", tok.span};
208 }
209
218 template <typename Parse_Item>
220 const Compiler_Token_Kind terminator,
222 const bool allow_trailing_separator = false)
223 {
224 if (check(terminator))
225 return true;
226
227 while (true)
228 {
229 if (not parse_item())
230 return false;
231
232 if (not match(separator))
233 return true;
234
235 if (allow_trailing_separator and check(terminator))
236 return true;
237 }
238 }
239
249 {
250 while (true)
251 {
252 const auto tok = peek();
253 if (tok.is_eof() or tok.kind == Compiler_Token_Kind::RBrace
255 return;
256
257 switch (tok.kind)
258 {
266 return;
267 default:
268 break;
269 }
270
272 {
273 (void) next();
274 return;
275 }
276
277 (void) next();
278 }
279 }
280};
281} // namespace Aleph
282
283#endif
Lexical analyzer (Lexer) based on Source_Manager.
Token generator for a single source file.
Compiler_Token next()
Consumes and returns the next token from the stream.
const Compiler_Token & peek()
Peeks at the next token without advancing the cursor.
Lightweight token stream facade for recursive-descent parsers.
void emit_error(const Source_Span &span, const std::string &message, const std::string &code, const std::string &note="", const std::string &help="") const
bool check(const Compiler_Token_Kind kind)
Returns whether the next token has the requested kind.
bool parse_separated_list(const Compiler_Token_Kind separator, const Compiler_Token_Kind terminator, Parse_Item &&parse_item, const bool allow_trailing_separator=false)
Parses one separated list until a terminator token is reached.
Compiler_Parser_Stream(Compiler_Lexer &token_source, Diagnostic_Engine *dx=nullptr) noexcept
Builds one parser stream over an existing lexer.
bool match(const Compiler_Token_Kind kind)
Consumes the next token if it matches kind.
void synchronize_statement()
Skips tokens until a statement boundary suitable for recovery.
Compiler_Token peek()
Returns the next token without consuming it.
Compiler_Token expect(const Compiler_Token_Kind kind, const std::string &message, const std::string &code, const std::string &note="", const std::string &help="")
Consumes a token of kind kind or emits one diagnostic error.
Compiler_Token expect_identifier(const std::string_view context, const std::string &code="PAR002")
Consumes one identifier token or emits one diagnostic error.
Compiler_Token next()
Consumes and returns the next token.
Diagnostic_Builder & code(const std::string &value)
Sets the stable diagnostic code.
size_t emit() const noexcept
Finalizes the builder and returns the diagnostic index.
Diagnostic_Builder & help(const std::string &msg)
Appends a help line.
Diagnostic_Builder & note(const std::string &msg)
Appends a note line.
Diagnostic accumulator and renderer.
Diagnostic_Builder error(const Source_Span &span, const std::string &msg)
Starts an error diagnostic.
static void separator(const string &title)
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
bool compiler_is_expression_start(const Compiler_Token_Kind kind) noexcept
Returns whether a token kind can start an expression in the MVP grammar.
void message(const char *file, int line, const char *format,...)
Print an informational message with file and line info.
Definition ahDefs.C:95
and
Check uniqueness with explicit hash + equality functors.
std::string code(Node *root)
Compute a string with the Lukasiewicz`s word of a tree.
bool compiler_is_top_level_declaration_start(const Compiler_Token_Kind kind) noexcept
Returns whether a token kind starts one top-level declaration.
Compiler_Token_Kind
Token kinds supported by the compiler MVP.
@ Identifier
Named identifier (e.g., variable or function name).
@ Integer_Literal
Integer constant.
@ Char_Literal
Single character constant.
@ String_Literal
String constant (with escape sequences).
bool compiler_is_statement_start(const Compiler_Token_Kind kind) noexcept
Returns whether a token kind can start a statement in the MVP grammar.
std::string compiler_unquote_string_token(const Compiler_Token &token)
Removes surrounding double quotes from one string-literal token.
Lexical token representation with its value and location.
Compiler_Token_Kind kind
Logical category (e.g., Kw_If).
std::string lexeme
Exact text found in the source.
Half-open byte range inside a source file.
Definition ah-source.H:100