diff options
| author | Roland Reichwein <mail@reichwein.it> | 2020-11-01 22:26:56 +0100 | 
|---|---|---|
| committer | Roland Reichwein <mail@reichwein.it> | 2020-11-01 22:26:56 +0100 | 
| commit | 62aafc5c9273cb0b7a91bf2e4dee1ac2d3658bb3 (patch) | |
| tree | 4c3e2943b48260c173733ffa1199bc09c907f131 | |
| parent | e0d6dac4b103a557b37f4850fe76dacf87df7cb9 (diff) | |
translate() translation-unit and declaration (WIP)
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | cpp.cpp | 85 | ||||
| -rw-r--r-- | cpp.h | 10 | ||||
| -rw-r--r-- | tests/test-cpp.cpp | 4 | 
4 files changed, 81 insertions, 20 deletions
| @@ -89,7 +89,7 @@ TESTSRC=\  SRC=$(PROGSRC) mcc.cpp  all: test-$(PROJECTNAME) mcc -	./test-$(PROJECTNAME) #--gtest_filter='*preprocessing_tokenize' +	./test-$(PROJECTNAME) --gtest_filter='CppTest.compile'  # testsuite ----------------------------------------------  test-$(PROJECTNAME): $(TESTSRC:.cpp=.o) @@ -64,7 +64,7 @@ void CPP::concatenate_strings()   // TODO  } -std::string CPP::valueOfNode(index_t node_index, const std::vector<TreeNode>& Tree) +std::string CPP::valueOfNode(index_t node_index) const  {   std::string result;   std::optional<size_t> pos0; @@ -84,7 +84,7 @@ std::string CPP::valueOfNode(index_t node_index, const std::vector<TreeNode>& Tr     last_index = TokenIdFromChildId(current_index);    } else { -   const TreeNode &node{Tree[current_index]}; +   const TreeNode &node{m_nodes[current_index]};     // iterate backwards in childs, to get depth-first search in tree, from the beginning     std::for_each(node.child_ids.rbegin(), node.child_ids.rend(), [&](int32_t child){ @@ -99,6 +99,13 @@ std::string CPP::valueOfNode(index_t node_index, const std::vector<TreeNode>& Tr   return m_code.substr(*pos0, m_tokens[last_index].location.pos - *pos0) + m_tokens[last_index].value;  }; +std::string CPP::typeOfNode(index_t node_id) const +{ + if (node_id >= m_nodes.size()) +  throw std::runtime_error("CPP::typeOfNode(): node_id="s + std::to_string(node_id) + ", m_nodes.size()="s + std::to_string(m_nodes.size())); + return m_nodes[node_id].type; +} +  namespace {   std::unordered_set<std::string> pp_types {    "identifier", @@ -236,28 +243,76 @@ std::vector<Gram::TreeNode> CPP::analysis(const std::vector<Token>& tokens)   return compiler.compile(tokens);  } -#if 0 -void CPP::traverse(index_t node_id) +std::string CPP::locationOfNode(index_t node_index) const  { - fs::path current_path{parent_path / m_nodes[node_id].type}; + if (node_index >= m_nodes.size()) +  throw std::runtime_error("ICE: locationOfNode(): Bad node_index "s + std::to_string(node_index) + " vs. "s + std::to_string(m_nodes.size())); - // execute callbacks - auto it{map.find(current_path.generic_string())}; - if (it != map.end()) { -  it->second(current_path, node_id); - } - - // recurse tree - for (const auto& child_id: m_nodes[node_id].child_ids) { + for (const auto& child_id: m_nodes[node_index].child_ids) {    if (ChildIdIsNode(child_id)) { -   traverse(child_id, map, current_path); +   std::string location{locationOfNode(child_id)}; +   if (location.size() > 0) +    return location; +  } else { // ChildIdIsToken +   return m_tokens[TokenIdFromChildId(child_id)].location.toString();    }   } + + return ""; // not found +} + +void CPP::compileError(index_t node_id, const std::string& msg) const +{ + std::string location{locationOfNode(node_id)}; + if (location.size() == 0) +  location = "Node "s + std::to_string(node_id) + "doesn't have any token"; + throw std::runtime_error("Compile error: "s + location + ": "s + msg); +} + +std::string CPP::typeOfChild(int32_t child_id) const +{ + if (ChildIdIsToken(child_id)) { +  index_t token_id {TokenIdFromChildId(child_id)}; +  return m_tokens[token_id].type; + } else { // ChildIdIsNode +  return m_nodes[child_id].type; + } +} + +bool CPP::childTypesOfNodeMatch(index_t node_id, const std::vector<std::string>& pattern) const +{ + const std::vector<int32_t>& child_ids{m_nodes[node_id].child_ids}; + + if (child_ids.size() != pattern.size()) +  return false; // mismatch + + for (size_t i = 0; i < child_ids.size(); i++) { +  if (pattern[i] != "" && typeOfChild(child_ids[i]) != pattern[i]) +   return false; // mismatch + } + + return true; // match +} + +void CPP::trDeclaration(index_t node_id) +{ +  std::cout << "DEBUG" << std::endl;  } -#endif  void CPP::trTranslationUnit(index_t node_id)  { + if (childTypesOfNodeMatch(node_id, {"declaration-seq"})) { +  // resolve sequence +  do { +   node_id = m_nodes[node_id].child_ids[0]; +   if (childTypesOfNodeMatch(node_id, {"declaration"})) { +    trDeclaration(m_nodes[node_id].child_ids[0]); +    return; +   } +  } while (childTypesOfNodeMatch(node_id, {"declaration-seq", "declaration"})); +  compileError(node_id, "ICE: bad declaration-seq"); + } else +  compileError(node_id, "declaration-seq expected");  }  // Phase 7.c: Translate @@ -19,8 +19,6 @@ public:   CPP();   ~CPP(); - std::string valueOfNode(index_t node_index, const std::vector<Gram::TreeNode>& Tree); -   // phases of translation, according to standard   void source_charset_map(); // phase 1   void backslash_escape(); // phase 2 @@ -47,6 +45,14 @@ private:   CPPContext m_cpp_context; + std::string valueOfNode(index_t node_index) const; + std::string typeOfNode(index_t node_index) const; + std::string locationOfNode(index_t node_index) const; ///< Empty if no location available + void compileError(index_t node_id, const std::string& msg) const; + std::string typeOfChild(int32_t child_id) const; + bool childTypesOfNodeMatch(index_t, const std::vector<std::string>& pattern) const; ///< returns true iff specified type list matches; "" -> don't care +   void trTranslationUnit(index_t node_id); + void trDeclaration(index_t node_id);  }; diff --git a/tests/test-cpp.cpp b/tests/test-cpp.cpp index adfa54b..0a0276e 100644 --- a/tests/test-cpp.cpp +++ b/tests/test-cpp.cpp @@ -78,13 +78,13 @@ TEST_F(CppTest, preprocessing_tokenize_compile_error) {   FAIL() << "Exception expected";  } -TEST(Cpp, compile) { +TEST_F(CppTest, compile) {   CPP cpp;   cpp.compile("int main() { return 1 + 1; }");  } -TEST(Cpp, compile_2_times) { +TEST_F(CppTest, compile_2_times) {   CPP cpp;   cpp.compile("int main() { return (1 + 2) * 2; }"); | 
