summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-01-13 21:06:05 +0100
committerRoland Reichwein <mail@reichwein.it>2020-01-13 21:06:05 +0100
commit0ba6606eecb39929a628cb254e8bf5283e811c26 (patch)
tree8fe30189c432aae88b0d5e0f44e2f18bae9c5757
First commit
-rw-r--r--Makefile77
-rw-r--r--minicc.cpp92
2 files changed, 169 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..af47b09
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,77 @@
+PROJECTNAME=minicc
+
+CXX=clang++-8
+#CXX=g++-8
+
+#CXXFLAGS=-O0 -D_DEBUG
+# -fprofile-instr-generate -fcoverage-mapping
+# gcc:--coverage
+CXXFLAGS=-O2 -DNDEBUG
+
+CXXFLAGS+= -Wall -std=c++17 -I. -Ilib
+
+ifeq ($(CXX),clang++-8)
+# currently broken:
+# ld.lld-8: error: undefined symbol: boost::re_detail_106700::cpp_regex_traits_implementation<char>::transform(char const*, char const*) const
+#CXXFLAGS+= -stdlib=libc++
+endif
+
+CXXTESTFLAGS=-Igoogletest/include -Igooglemock/include/ -Igoogletest -Igooglemock
+
+LIBS=\
+-lboost_context \
+-lboost_coroutine \
+-lboost_program_options \
+-lboost_system \
+-lboost_thread \
+-lboost_filesystem \
+-lboost_regex \
+-lpthread
+
+ifeq ($(CXX),clang++-8)
+LIBS+= \
+-fuse-ld=lld-8 \
+-lstdc++ \
+-lstdc++fs
+#-lc++ \
+#-lc++abi \
+#-lc++fs
+else
+LIBS+= \
+-lstdc++ \
+-lstdc++fs
+endif
+
+SRC=\
+ minicc.cpp \
+ googletest/src/gtest-all.cpp \
+ googlemock/src/gmock-all.cpp
+
+all: test-$(PROJECTNAME)
+ ./test-$(PROJECTNAME)
+
+# testsuite ----------------------------------------------
+test-$(PROJECTNAME): $(SRC:.cpp=.o)
+ $(CXX) $(CXXFLAGS) $^ $(LIBS) -o $@
+
+%.o: %.cpp
+ $(CXX) $(CXXFLAGS) $(CXXTESTFLAGS) -c $< -o $@
+
+googletest/src/%.o: googletest/src/%.cc
+ $(CXX) $(CXXFLAGS) $(CXXTESTFLAGS) -c $< -o $@
+
+# dependencies
+
+ADD_DEP=Makefile
+
+# misc ---------------------------------------------------
+clean:
+ -rm -f test-$(PROJECTNAME)
+ -find . -name '*.o' -o -name '*.d' -o -name '*.gcno' -o -name '*.gcda' | xargs rm
+
+zip: clean
+ -rm -f ../$(PROJECTNAME).zip
+ zip -r ../$(PROJECTNAME).zip *
+ ls -l ../$(PROJECTNAME).zip
+
+.PHONY: clean all zip
diff --git a/minicc.cpp b/minicc.cpp
new file mode 100644
index 0000000..704c465
--- /dev/null
+++ b/minicc.cpp
@@ -0,0 +1,92 @@
+#include <boost/algorithm/string.hpp>
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+#include <deque>
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+using namespace std::string_literals;
+
+using BNF = std::map<std::string, std::vector<std::vector<std::string>>>;
+using Terminals = std::set<std::string>;
+using ProgramNode = std::deque<std::string>;
+using PathElement = std::pair<std::string, size_t>; // Name, Index
+
+std::vector<std::string> split(std::string s)
+{
+ std::vector<std::string> result;
+ boost::algorithm::split(result, s, boost::algorithm::is_any_of(s), boost::algorithm::token_compress_on);
+ while (result.size() > 0 && result.back() == ""s)
+ result.pop_back();
+ return result;
+}
+
+std::vector<std::string> Lex(std::string s)
+{
+ return split(s);
+}
+
+BNF Reverse(BNF bnf){
+ return {}; // TODO
+}
+
+std::vector<PathElement> GetPath(std::string Token, BNF ReverseBNF, std::string Top, Terminals terminals, std::vector<PathElement> PreviousPath = {})
+{
+ throw std::runtime_error("Compile error");
+ return {}; // TODO
+}
+
+ProgramNode Compile(std::vector<std::string> Tokens, std::string Top, BNF bnf, Terminals terminals)
+{
+ BNF ReverseBNF{ Reverse(bnf)};
+
+ if (Tokens.size()){
+ std::string Token = Tokens[0];
+ auto Path = GetPath(Token, ReverseBNF, Top, terminals);
+ if (Path.size()) {
+ size_t Index{1};
+ while (Index < Tokens.size()) {
+ Path = GetPath(Token, ReverseBNF, Top, terminals, Path);
+ Index++;
+ }
+ } else
+ throw std::runtime_error("Invalid token: "s + Token);
+ } else
+ throw std::runtime_error("No tokens!");
+
+ return {};
+}
+
+class Test: public ::testing::Test {
+protected:
+ Test(){}
+ ~Test() override {}
+};
+
+TEST_F(Test, BNF) {
+ std::string Top{"program"};
+ BNF bnf{
+ {"program", {{"statement-list"}}},
+ {"statement-list", {{"statement", "statement-list"}}},
+ {"statement-list", {}},
+ {"statement", {{"assigmnent", ";"}}},
+ {"assignment", {{"identifier", "=", "identifier"}}}
+ };
+
+ std::set<std::string> Terminals{"identifier", "=", ";"};
+
+ std::string Code{"a = b ; c = d ; e = f ;"};
+
+ auto tokens = Lex(Code);
+ auto Program = Compile(tokens, Top, bnf, Terminals);
+}
+
+int main(int argc, char* argv[]) {
+ ::testing::InitGoogleMock(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+