summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-11-01 22:26:56 +0100
committerRoland Reichwein <mail@reichwein.it>2020-11-01 22:26:56 +0100
commit62aafc5c9273cb0b7a91bf2e4dee1ac2d3658bb3 (patch)
tree4c3e2943b48260c173733ffa1199bc09c907f131
parente0d6dac4b103a557b37f4850fe76dacf87df7cb9 (diff)
translate() translation-unit and declaration (WIP)
-rw-r--r--Makefile2
-rw-r--r--cpp.cpp85
-rw-r--r--cpp.h10
-rw-r--r--tests/test-cpp.cpp4
4 files changed, 81 insertions, 20 deletions
diff --git a/Makefile b/Makefile
index dbc8d2b..84a17fa 100644
--- a/Makefile
+++ b/Makefile
@@ -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)
diff --git a/cpp.cpp b/cpp.cpp
index 21f4df1..2135e67 100644
--- a/cpp.cpp
+++ b/cpp.cpp
@@ -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
diff --git a/cpp.h b/cpp.h
index 3be03e2..95289fc 100644
--- a/cpp.h
+++ b/cpp.h
@@ -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; }");