aboutsummaryrefslogtreecommitdiff
path: root/boot/driver.cc
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-07-03 11:09:44 +0200
committerEugen Wissner <belka@caraus.de>2026-07-03 11:09:44 +0200
commitb6b68b25043fc4008af6c7bfb4573593a858a9de (patch)
tree4fdf4a1fc8030993f0fe3fe9829337c6548f212a /boot/driver.cc
parentd9cd03ffeb13a5c30d8337ba27f15e1ba2959e4d (diff)
downloadelna-b6b68b25043fc4008af6c7bfb4573593a858a9de.tar.gz
Rename frontend to boot(strap)HEADcpp
Diffstat (limited to 'boot/driver.cc')
-rw-r--r--boot/driver.cc118
1 files changed, 118 insertions, 0 deletions
diff --git a/boot/driver.cc b/boot/driver.cc
new file mode 100644
index 0000000..abbf0f1
--- /dev/null
+++ b/boot/driver.cc
@@ -0,0 +1,118 @@
+/* Parsing driver.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "elna/boot/driver.h"
+
+namespace elna::boot
+{
+ position make_position(const yy::location& location)
+ {
+ position result;
+ result.line = static_cast<std::size_t>(location.begin.line);
+ result.column = static_cast<std::size_t>(location.begin.column);
+
+ return result;
+ }
+
+ syntax_error::syntax_error(const std::string& message,
+ const char *input_file, const yy::location& location)
+ : error(input_file, make_position(location)), message(message)
+ {
+ }
+
+ std::string syntax_error::what() const
+ {
+ return message;
+ }
+
+ driver::driver(const char *input_file)
+ : error_container(input_file)
+ {
+ }
+
+ char escape_char(char escape)
+ {
+ switch (escape)
+ {
+ case 'n':
+ return '\n';
+ case 't':
+ return '\t';
+ case 'f':
+ return '\f';
+ case 'r':
+ return '\r';
+ case 'v':
+ return '\v';
+ case '\\':
+ return '\\';
+ case '\'':
+ return '\'';
+ case '"':
+ return '"';
+ case '0':
+ return '\0';
+ default:
+ return escape_invalid_char;
+ }
+ }
+
+ std::optional<std::string> escape_string(const char *escape)
+ {
+ std::string result;
+ const char *current_position = escape + 1;
+
+ while (*current_position != '\0')
+ {
+ if (*current_position == '\\' && *(current_position + 1) == 'x')
+ {
+ current_position += 2;
+
+ std::size_t processed;
+ char character = static_cast<char>(std::stoi(current_position, &processed, 16));
+ if (processed == 0)
+ {
+ return std::nullopt;
+ }
+ else
+ {
+ current_position += processed - 1;
+ result.push_back(character);
+ }
+ }
+ else if (*current_position == '\\')
+ {
+ ++current_position;
+
+ char escape = escape_char(*current_position);
+ if (escape == escape_invalid_char)
+ {
+ return std::nullopt;
+ }
+ result.push_back(escape);
+ }
+ else
+ {
+ result.push_back(*current_position);
+ }
+ ++current_position;
+ }
+ result.pop_back(); // Remove the terminating quote character.
+
+ return result;
+ }
+}