summaryrefslogtreecommitdiff
path: root/frontend/driver.cc
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2025-12-02 10:22:06 +0100
committerEugen Wissner <belka@caraus.de>2025-12-02 17:14:18 +0100
commit23b6f074c7f560d701e9a1fa5713a965af3a18a3 (patch)
tree87549a4eba3da8d8ed6e3fbb2e337e152a8bc96a /frontend/driver.cc
parent5f7d83974114c73327ce9fff3635927df050b5e4 (diff)
downloadelna-23b6f074c7f560d701e9a1fa5713a965af3a18a3.tar.gz
Merge GCC frontend into the branch
Diffstat (limited to 'frontend/driver.cc')
-rw-r--r--frontend/driver.cc124
1 files changed, 124 insertions, 0 deletions
diff --git a/frontend/driver.cc b/frontend/driver.cc
new file mode 100644
index 0000000..1c20d09
--- /dev/null
+++ b/frontend/driver.cc
@@ -0,0 +1,124 @@
+/* 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/frontend/driver.h"
+
+namespace elna::frontend
+{
+ 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 'a':
+ return '\a';
+ case 'b':
+ return '\b';
+ case 't':
+ return '\t';
+ case 'f':
+ return '\f';
+ case 'r':
+ return '\r';
+ case 'v':
+ return '\v';
+ case '\\':
+ return '\\';
+ 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;
+ }
+}