diff options
| author | Fuwn <[email protected]> | 2022-07-03 19:44:59 -0700 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2022-07-03 19:44:59 -0700 |
| commit | 9ab0f74aa643dc5d27508e9b2043f0c476f8f928 (patch) | |
| tree | 28865c9003efc06615258a965b1d766386fb8805 /src/parser.cc | |
| parent | fix(cli): initialise padding (diff) | |
| download | cait-9ab0f74aa643dc5d27508e9b2043f0c476f8f928.tar.xz cait-9ab0f74aa643dc5d27508e9b2043f0c476f8f928.zip | |
chore(ninja): rename src_dir
Diffstat (limited to 'src/parser.cc')
| -rw-r--r-- | src/parser.cc | 371 |
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 |