summaryrefslogtreecommitdiff
path: root/src/parser.cc
diff options
context:
space:
mode:
authorFuwn <[email protected]>2022-07-03 19:44:59 -0700
committerFuwn <[email protected]>2022-07-03 19:44:59 -0700
commit9ab0f74aa643dc5d27508e9b2043f0c476f8f928 (patch)
tree28865c9003efc06615258a965b1d766386fb8805 /src/parser.cc
parentfix(cli): initialise padding (diff)
downloadcait-9ab0f74aa643dc5d27508e9b2043f0c476f8f928.tar.xz
cait-9ab0f74aa643dc5d27508e9b2043f0c476f8f928.zip
chore(ninja): rename src_dir
Diffstat (limited to 'src/parser.cc')
-rw-r--r--src/parser.cc371
1 files changed, 0 insertions, 371 deletions
diff --git a/src/parser.cc b/src/parser.cc
deleted file mode 100644
index 734be2f..0000000
--- a/src/parser.cc
+++ /dev/null
@@ -1,371 +0,0 @@
-// This file is part of Cait <https://github.com/Fuwn/cait>.
-// Copyright (C) 2022-2022 Fuwn <[email protected]>
-//
-// This program 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, version 3.
-//
-// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
-//
-// Copyright (C) 2022-2022 Fuwn <[email protected]>
-// SPDX-License-Identifier: GPL-3.0-only
-
-#include <iostream>
-
-#include "parser.hh"
-#include "utility.hh"
-
-namespace cait {
-
-parser_exception::parser_exception(const std::string &message)
- : std::runtime_error(message) {}
-
-auto parser_exception::x() -> void {}
-
-token_bundle::token_bundle(std::size_t &_j, token_t &bundle_token,
- std::vector<token_t> &_parsed_token_line,
- std::vector<token_t> &_token_line)
- : j(_j), token(bundle_token), parsed_token_line(_parsed_token_line),
- token_line(_token_line) {}
-
-template <typename T>
-range_t<T>::range_t(T begin, T end) : _begin(begin), _end(end) {}
-
-template <typename T> auto range_t<T>::begin() -> T { return this->_begin; }
-
-template <typename T> auto range_t<T>::end() -> T { return this->_end; }
-
-template <typename T> auto range(T b, T e) -> range_t<T> {
- return range_t<T>(b, e);
-}
-
-parser::parser(token_tree &token_tree) {
- this->fix_tree(token_tree);
- this->prune_empty_token_lines();
-}
-
-[[nodiscard]] auto parser::tree() const noexcept -> const token_tree & {
- return this->_tree;
-}
-
-[[nodiscard]] auto parser::nodes() const noexcept -> const node_tree & {
- return this->_nodes;
-}
-
-auto parser::token_parse_assignment_operator(token_bundle bundle) -> void {
- auto &local = bundle.token_line[bundle.j - 1];
-
- if (local.type != token_type::pool_depth) {
- local = local.with_type(token_type::variable_declaration);
- }
-
- bundle.parsed_token_line.push_back(local);
- bundle.parsed_token_line.push_back(bundle.token);
-
- for (auto &token_line_item :
- range(bundle.token_line.begin() + 2, bundle.token_line.end())) {
- token_line_item.type = token_type::variable_value;
- }
-
- bundle.parsed_token_line.insert(bundle.parsed_token_line.end(),
- bundle.token_line.begin() + 2,
- bundle.token_line.end());
-
- bundle.j += bundle.token_line.size() - 1;
-}
-
-auto parser::token_parse_rule_pool_declaration(token_bundle bundle) -> void {
- bundle.parsed_token_line.push_back(bundle.token);
- bundle.parsed_token_line.push_back(
- bundle.token_line[bundle.j + 1].with_type(token_type::identifier));
-
- bundle.j += bundle.token_line.size();
-}
-
-auto parser::token_parse_default_declaration(token_bundle bundle) -> void {
- bundle.parsed_token_line.push_back(bundle.token);
-
- for (auto &token_line_item :
- range(bundle.token_line.begin() + 1, bundle.token_line.end())) {
- token_line_item.type = token_type::default_target;
- }
-
- bundle.parsed_token_line.insert(bundle.parsed_token_line.end(),
- bundle.token_line.begin() + 1,
- bundle.token_line.end());
-
- bundle.j += bundle.token_line.size();
-}
-
-auto parser::token_parse_include_subninja_declaration(token_bundle bundle)
- -> void {
- bundle.parsed_token_line.push_back(bundle.token);
- bundle.parsed_token_line.push_back(
- bundle.token_line[bundle.j + 1].with_type(token_type::string_literal));
-
- bundle.j += bundle.token_line.size();
-}
-
-auto parser::token_parse_rule_variable(token_bundle bundle) -> void {
- bundle.parsed_token_line.push_back(bundle.token);
-
- for (auto &token_line_item :
- range(bundle.token_line.begin() + 2, bundle.token_line.end())) {
- token_line_item.type = token_type::variable_value;
- }
-
- bundle.parsed_token_line.insert(bundle.parsed_token_line.end(),
- bundle.token_line.begin() + 1,
- bundle.token_line.end());
-
- bundle.j += bundle.token_line.size() - 1;
-}
-
-auto parser::token_parse_build_declaration(token_bundle bundle) -> void {
- bundle.parsed_token_line.push_back(bundle.token);
-
- {
- auto &output_file_token = bundle.token_line[bundle.j + 1];
-
- output_file_token.word =
- output_file_token.word.substr(0, output_file_token.word.size() - 1);
-
- bundle.parsed_token_line.push_back(
- output_file_token.with_type(token_type::build_output));
-
- // We can actually just throw away the colon...
- // parsed_token_line.push_back(
- // cait::token(output_file_token.line, output_file_token.begin +
- // 1,
- // output_file_token.end + 1, ":")
- // .with_type(token_type::colon));
- }
-
- bundle.token_line[2].type = token_type::build_rule;
-
- for (auto &token_line_item :
- range(bundle.token_line.begin() + 3, bundle.token_line.end())) {
- token_line_item.type = token_type::build_input;
- }
-
- bundle.parsed_token_line.insert(bundle.parsed_token_line.end(),
- bundle.token_line.begin() + 2,
- bundle.token_line.end());
-
- bundle.j += bundle.token_line.size();
-}
-
-auto parser::fix_tree(token_tree &token_tree) -> void {
- for (auto &token_line : token_tree) {
- std::vector<token> parsed_token_line;
-
- for (std::size_t j = 0; j < token_line.size(); ++j) {
- auto &token = token_line[j];
-
- switch (token.type) {
- case token_type::assignment_operator: {
- this->token_parse_assignment_operator(
- token_bundle(j, token, parsed_token_line, token_line));
- } break;
- case token_type::rule_declaration:
- case token_type::pool_declaration: {
- this->token_parse_rule_pool_declaration(
- token_bundle(j, token, parsed_token_line, token_line));
- } break;
- case token_type::default_declaration: {
- this->token_parse_default_declaration(
- token_bundle(j, token, parsed_token_line, token_line));
- } break;
- case token_type::include_declaration:
- case token_type::subninja_declaration: {
- this->token_parse_include_subninja_declaration(
- token_bundle(j, token, parsed_token_line, token_line));
- } break;
- case token_type::rule_command:
- case token_type::rule_depfile:
- case token_type::rule_deps:
- case token_type::rule_msvc_deps_prefix:
- case token_type::rule_description:
- case token_type::rule_dyndep:
- case token_type::rule_generator:
- case token_type::rule_in:
- case token_type::rule_in_newline:
- case token_type::rule_out:
- case token_type::rule_restat:
- case token_type::rule_rspfile:
- case token_type::rule_rspfile_content: {
- this->token_parse_rule_variable(
- token_bundle(j, token, parsed_token_line, token_line));
- } break;
- case token_type::build_declaration: {
- this->token_parse_build_declaration(
- token_bundle(j, token, parsed_token_line, token_line));
- } break;
- case token_type::string_literal:
- case token_type::variable_declaration:
- case token_type::identifier:
- case token_type::build_output:
- case token_type::build_input:
- case token_type::build_rule:
- case token_type::default_target:
- case token_type::variable_value:
- case token_type::pool_depth:
- break;
- }
-
- this->_tree.push_back(parsed_token_line);
- }
- }
-}
-
-auto parser::generate_nodes(const std::string &file_name,
- const std::vector<std::string> &lines) -> void {
- for (std::size_t i = 0; i < this->_tree.size(); ++i) {
- auto &token_line = this->_tree[i];
-
- for (std::size_t j = 0; j < token_line.size(); ++j) {
- auto &token = token_line[j];
-
- switch (token.type) {
- case token_type::variable_declaration: {
- this->_nodes.push_back(
- node::variable(token_line[0], std::vector(token_line.begin() + 2,
- token_line.end())));
-
- j += token_line.size();
- } break;
- case token_type::default_declaration: {
- this->_nodes.push_back(node::default_(
- std::vector(token_line.begin() + 1, token_line.end())));
- } break;
- case token_type::include_declaration: {
- this->_nodes.push_back(node::include(token_line[1]));
- } break;
- case token_type::subninja_declaration: {
- this->_nodes.push_back(node::subninja(token_line[1]));
- } break;
- case token_type::build_declaration: {
- this->_nodes.push_back(
- node::build(token_line[1], token_line[2],
- std::vector(token_line.begin() + 3, token_line.end())));
- } break;
- case token_type::rule_declaration: {
- auto command_line_index = i + 1;
- auto &command_line = this->_tree[command_line_index];
- node::item_map_type item_map;
-
- while (command_line[0].type == token_type::rule_command ||
- command_line[0].type == token_type::rule_description ||
- command_line[0].type == token_type::rule_depfile ||
- command_line[0].type == token_type::rule_deps ||
- command_line[0].type == token_type::rule_msvc_deps_prefix ||
- command_line[0].type == token_type::rule_dyndep ||
- command_line[0].type == token_type::rule_generator ||
- command_line[0].type == token_type::rule_in ||
- command_line[0].type == token_type::rule_in_newline ||
- command_line[0].type == token_type::rule_out ||
- command_line[0].type == token_type::rule_restat ||
- command_line[0].type == token_type::rule_rspfile ||
- command_line[0].type == token_type::rule_rspfile_content) {
- item_map.insert(std::make_pair(
- command_line[0].word,
- std::vector(command_line.begin() + 2, command_line.end())));
-
- command_line_index += 1;
- command_line = this->_tree[command_line_index];
- }
-
- // Handle unknown rule variable error
- if (command_line[1].type == token_type::assignment_operator) {
- std::ostringstream error;
-
- error << "cait: error: " << file_name << ":" << command_line[0].line
- << ": unexpected variable '" << command_line[0].word << "'\n"
- << lines[command_line[0].line - 1] << "\n";
-
- for (auto &word : command_line) {
- error << std::string(word.word.size(), ' ');
- }
-
- auto leading_spaces = [](const std::string &string) -> std::size_t {
- std::size_t count = 0;
-
- while (string[count] == ' ') {
- count += 1;
- }
-
- return count;
- };
-
- error << std::string(leading_spaces(lines[command_line[0].line - 1]),
- ' ')
- << " ^ near here\n";
-
- throw parser_exception(error.str());
- }
-
- // Handle no command line error
- if (item_map.count("command") == 0) {
- std::ostringstream error;
-
- error << "cait: error: " << file_name << ":" << command_line[0].line
- << ": expected 'command =' line\n";
-
- throw parser_exception(error.str());
- }
-
- this->_nodes.push_back(node::rule(token_line[1], item_map));
-
- i += 1;
- } break;
- case token_type::pool_declaration: {
- this->_nodes.push_back(
- node::pool(token_line[1], this->_tree[i + 1][2]));
-
- i += 1;
- } break;
- case token_type::string_literal:
- std::cout << "string: " << token.word << "\n";
- break;
- case token_type::rule_command:
- case token_type::assignment_operator:
- case token_type::identifier:
- case token_type::build_output:
- case token_type::rule_depfile:
- case token_type::rule_deps:
- case token_type::rule_msvc_deps_prefix:
- case token_type::rule_description:
- case token_type::rule_dyndep:
- case token_type::rule_generator:
- case token_type::rule_in:
- case token_type::rule_in_newline:
- case token_type::rule_out:
- case token_type::rule_restat:
- case token_type::rule_rspfile:
- case token_type::rule_rspfile_content:
- case token_type::build_input:
- case token_type::build_rule:
- case token_type::default_target:
- case token_type::variable_value:
- case token_type::pool_depth:
- break;
- }
- }
- }
-}
-
-auto parser::prune_empty_token_lines() -> void {
- for (int j = 0; static_cast<size_t>(j) < this->_tree.size(); ++j) {
- if (this->_tree[static_cast<size_t>(j)].empty()) {
- this->_tree.erase(this->_tree.begin() + j);
- }
- }
-}
-
-} // namespace cait