diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | TODO | 3 | ||||
| -rw-r--r-- | cpp.cpp | 21 | ||||
| -rw-r--r-- | cpp.h | 15 | ||||
| -rw-r--r-- | cppbnf.cpp | 209 | ||||
| -rw-r--r-- | tests/test-cpp.cpp | 19 | ||||
| -rw-r--r-- | tests/test-grammer.cpp | 6 | 
7 files changed, 185 insertions, 90 deletions
| @@ -89,7 +89,7 @@ TESTSRC=\  SRC=$(PROGSRC) mcc.cpp  all: test-$(PROJECTNAME) mcc -	./test-$(PROJECTNAME) # --gtest_filter='*preprocessing_tokenize*' +	./test-$(PROJECTNAME) #--gtest_filter='*preprocessing_tokenize'  # testsuite ----------------------------------------------  test-$(PROJECTNAME): $(TESTSRC:.cpp=.o) @@ -1 +1,2 @@ -Update cppbnf.cpp to n4860 +Support/test empty compile unit +grammer.cpp: match() : return point of match error ("Compile error") @@ -20,16 +20,7 @@ using namespace Gram;  namespace fs = std::filesystem; -CPP::CPP(): map_translation_unit ({ - {"/translation-unit/top-level-declaration-seq/top-level-declaration/declaration/function-definition", -  [&](fs::path& path, index_t node_id) -   { -    //std::cout << "DEBUG: " << path << ", " << node_id << ", " << valueOfNode(node_id, m_nodes) << ", " << m_nodes[node_id].node_id << ", " << m_nodes[node_id].pos.node_id << std::endl; -   } - }, -}) -{ -} +CPP::CPP(){}  CPP::~CPP(){} @@ -245,7 +236,8 @@ std::vector<Gram::TreeNode> CPP::analysis(const std::vector<Token>& tokens)   return compiler.compile(tokens);  } -void CPP::traverse(index_t node_id, map_type& map, fs::path parent_path) +#if 0 +void CPP::traverse(index_t node_id)  {   fs::path current_path{parent_path / m_nodes[node_id].type}; @@ -262,6 +254,11 @@ void CPP::traverse(index_t node_id, map_type& map, fs::path parent_path)    }   }  } +#endif + +void CPP::trTranslationUnit(index_t node_id) +{ +}  // Phase 7.c: Translate  void CPP::translate() @@ -269,7 +266,7 @@ void CPP::translate()   if (m_nodes.size() == 0)    throw std::runtime_error("ICE: Tree is empty"); - traverse(0, map_translation_unit); + trTranslationUnit(0);  }  // Phase 8: Instantiate objects @@ -5,6 +5,13 @@  #include <vector> +struct CPPContext { + // global variable declarations + // global variable definitions + // functions declarations + // functions definitions +}; +  class CPP {  public: @@ -34,14 +41,12 @@ public:   std::vector<uint8_t> getData();  private: - typedef std::unordered_map<std::string, std::function<void(fs::path&, index_t)>> map_type; -   std::string m_code; // input from compile()   std::vector<Token> m_tokens; // result of phase 7.a   std::vector<Gram::TreeNode> m_nodes; // result of phase 7.b - void traverse(index_t node_id, map_type& map, fs::path parent_path = "/"); -  - CPP::map_type map_translation_unit; + CPPContext m_cpp_context; + + void trTranslationUnit(index_t node_id);  }; @@ -199,13 +199,15 @@ BNF GetCppBNFLex()    {"hex-quad", {{"hexadecimal-digit", "hexadecimal-digit", "hexadecimal-digit", "hexadecimal-digit"}}},    {"universal-character-name", { -   {"\\", "u", "hex-quad"}, -   {"\\", "U", "hex-quad", "hex-quad"} +   {"\\u", "hex-quad"}, +   {"\\U", "hex-quad", "hex-quad"}    }},    {"preprocessing-token", {     {"header-name"}, -   //{"import-keyword"}, // TODO +   //{"import-keyword"}, // TODO: generated +   //{"module-keyword"}, // TODO +   //{"export-keyword"}, // TODO     {"identifier"},     {"pp-number"},     {"character-literal"}, @@ -220,8 +222,7 @@ BNF GetCppBNFLex()     {"identifier"},     {"keyword"},     {"literal"}, -   {"OPERATOR"}, // conflict with keyword "operator" -   {"punctuator"}, +   {"operator-or-punctuator"},    }},    {"header-name", { @@ -268,10 +269,97 @@ BNF GetCppBNFLex()    {"digit", {{"0"},{"1"},{"2"},{"3"},{"4"},{"5"},{"6"},{"7"},{"8"},{"9"}}}, +  {"keyword", { +   {"alignas"}, +   {"alignof"}, +   {"asm"}, +   {"auto"}, +   {"bool"}, +   {"break"}, +   {"case"}, +   {"catch"}, +   {"char"}, +   {"char8_t"}, +   {"char16_t"}, +   {"char32_t"}, +   {"class"}, +   {"concept"}, +   {"const"}, +   {"consteval"}, +   {"constexpr"}, +   {"constinit"}, +   {"const_cast"}, +   {"continue"}, +   {"co_await"}, +   {"co_return"}, +   {"co_yield"}, +   {"decltype"}, +   {"default"}, +   {"delete"}, +   {"do"}, +   {"double"}, +   {"dynamic_cast"}, +   {"else"}, +   {"enum"}, +   {"explicit"}, +   {"export"}, +   {"extern"}, +   {"false"}, +   {"float"}, +   {"for"}, +   {"friend"}, +   {"goto"}, +   {"if"}, +   {"inline"}, +   {"int"}, +   {"long"}, +   {"mutable"}, +   {"namespace"}, +   {"new"}, +   {"noexcept"}, +   {"nullptr"}, +   {"operator"}, +   {"private"}, +   {"protected"}, +   {"public"}, +   {"register"}, +   {"reinterpret_cast"}, +   {"requires"}, +   {"return"}, +   {"short"}, +   {"signed"}, +   {"sizeof"}, +   {"static"}, +   {"static_assert"}, +   {"static_cast"}, +   {"struct"}, +   {"switch"}, +   {"template"}, +   {"this"}, +   {"thread_local"}, +   {"throw"}, +   {"true"}, +   {"try"}, +   {"typedef"}, +   {"typeid"}, +   {"typename"}, +   {"union"}, +   {"unsigned"}, +   {"using"}, +   {"virtual"}, +   {"void"}, +   {"volatile"}, +   {"wchar_t"}, +   {"while"}, +   //{"import-keyword"}, // TODO +   //{"module-keyword"}, +   //{"export-keyword"}, +  }}, +    {"preprocessing-op-or-punc", { -   {"{"}, {"}"}, {"["}, {"]"}, {"#"}, {"#", "#"}, {"("}, {")"}, -   {"<:"}, {":>"}, {"<%"}, {"%>"}, {"%:"}, {"%:%:"}, {";"}, {":"}, {"..."}, -   {"new"}, {"delete"}, {"?"}, {"::"}, {"."}, {".*"}, {"->"}, {"->*"}, {"~"}, +   {"{"}, {"}"}, {"["}, {"]"}, {"("}, {")"}, +   {"<:"}, {":>"}, {"<%"}, {"%>"}, {";"}, {":"}, {"..."}, +   {"?"}, {"::"}, {"."}, {".*"}, {"->"}, {"->*"}, {"~"},     {"!"}, {"+"}, {"-"}, {"*"}, {"/"}, {"%"}, {"^"}, {"&"}, {"|"},     {"="}, {"+="}, {"-="}, {"*="}, {"/="}, {"%="}, {"^="}, {"&="}, {"|="},     {"=="}, {"!="}, {"<"}, {">"}, {"<="}, {">="}, {"<=>"}, {"&&"}, {"||"}, @@ -453,7 +541,7 @@ BNF GetCppBNFLex()    } },    { "r-char", { -   all_except({")"}), // TODO: actually: non-match from "raw-string" above: ")", optional("d-char-sequence"), "\"" +   all_except({")"}), // TODO: actually: ")", optional("d-char-sequence"), "\""; with d-char-sequence like initial    } },    { "d-char-sequence", { @@ -520,18 +608,8 @@ BNF GetCppBNFGram()    // [gram.basic]    {"translation-unit", { -   {optional("top-level-declaration-seq")}, -   {optional("global-module-fragment"), "module-declaration", optional("top-level-declaration-seq"), optional("private-module-fragment")}, -  }}, -  -  {"top-level-declaration-seq", { -   {"top-level-declaration"}, -   {"top-level-declaration-seq", "top-level-declaration"}, -  }}, -  -  {"top-level-declaration", { -   {"module-import-declaration"}, -   {"declaration"}, +   {optional("declaration-seq")}, +   {optional("global-module-fragment"), "module-declaration", optional("declaration-seq"), optional("private-module-fragment")},    }},    // [gram.expr] @@ -578,6 +656,9 @@ BNF GetCppBNFGram()    }},    {"lambda-introducer", {{"[", optional("lambda-capture"), "]"}}}, + +  {"lambda-declarator", {{"(", "parameter-declaration-clause", ")", optional("decl-specifier-seq"), +                          optional("noexcept-specifier"), optional("attribute-specifier-seq"), optional("trailing-return-type"), optional("requires-clause")}}},    {"lambda-capture", {     {"capture-default"}, @@ -593,31 +674,31 @@ BNF GetCppBNFGram()    }},    {"capture", { -   {"simple-capture", optional("...")}, -   {optional("..."), "init-capture"}, +   {"simple-capture"}, +   {"init-capture"},    }},    {"simple-capture", { -   {"identifier"}, -   {"&", "identifier"}, +   {"identifier", optional("...")}, +   {"&", "identifier", optional("...")},     {"this"},     {"*", "this"},    }},    {"init-capture", { -   {"identifier", "initializer"}, -   {"&", "identifier", "initializer"}, +   {optional("..."), "identifier", "initializer"}, +   {"&", optional("..."), "identifier", "initializer"},    }},    {"fold-expression", { -   {"(", "cast-expression", "fold-operator", ")"}, +   {"(", "cast-expression", "fold-operator", "...", ")"},     {"(", "...", "fold-operator", "cast-expression", ")"},     {"(", "cast-expression", "fold-operator", "...", "fold-operator", "cast-expression", ")"},    }},    {"fold-operator", {     {"+"}, {"-"}, {"*"}, {"/"}, {"%"}, {"^"}, {"&"}, {"|"}, {"<<"}, {">>"}, -   {"+="}, {"-="}, {"*="}, {"/="}, {"%="}, {"^="}, {"&="}, {"|="}, {"<<="}, {">>="}, +   {"+="}, {"-="}, {"*="}, {"/="}, {"%="}, {"^="}, {"&="}, {"|="}, {"<<="}, {">>="}, {"="},     {"=="}, {"!="}, {"<"}, {">"}, {"<="}, {">="}, {"&&"}, {"||"}, {","}, {".*"}, {"->*"},    }}, @@ -927,6 +1008,7 @@ BNF GetCppBNFGram()     {"namespace-definition"},     {"empty-declaration"},     {"attribute-declaration"}, +   {"module-import-declaration"},    }},    { "block-declaration", { @@ -1186,7 +1268,7 @@ BNF GetCppBNFGram()    { "parameter-declaration", {     {optional("attribute-specifier-seq"), "decl-specifier-seq", "declarator"}, -   {optional("attribute-specifier-seq"), "decl-specifier-seq", "declarator", "initializer-clause"}, +   {optional("attribute-specifier-seq"), "decl-specifier-seq", "declarator", "=", "initializer-clause"},     {optional("attribute-specifier-seq"), "decl-specifier-seq", optional("abstract-declarator")},     {optional("attribute-specifier-seq"), "decl-specifier-seq", optional("abstract-declarator"), "=", "initializer-clause"},    } }, @@ -1421,13 +1503,13 @@ BNF GetCppBNFGram()     {"(", optional("balanced-token-seq"), ")"},     {"[", optional("balanced-token-seq"), "]"},     {"{", optional("balanced-token-seq"), "}"}, -   all_except({"(", ")", "[", "]", "{", "}",}), +   all_except({"(", ")", "[", "]", "{", "}",}), // TODO: all tokens except ..., not characters!    }},    // [gram.module]    { "module-declaration", { -   {optional("export"), "module", "module-name", optional("module-partition"), optional("attribute-specifier-seq"), ";"}, +   {optional("export"), "module-keyword", "module-name", optional("module-partition"), optional("attribute-specifier-seq"), ";"},    } },    { "module-name", { @@ -1446,20 +1528,21 @@ BNF GetCppBNFGram()    { "export-declaration", {     {"export", "declaration"},     {"export", "{", optional("declaration-seq"), "}"}, +   {"export-keyword", "module-import-declaration"},    } },    { "module-import-declaration", { -   {optional("export"), "import-keyword", "module-name",      optional("attribute-specifier-seq"), ";"}, -   {optional("export"), "import-keyword", "module-partition", optional("attribute-specifier-seq"), ";"}, -   {optional("export"), "import-keyword", "header-name",      optional("attribute-specifier-seq"), ";"}, +   {"import-keyword", "module-name",      optional("attribute-specifier-seq"), ";"}, +   {"import-keyword", "module-partition", optional("attribute-specifier-seq"), ";"}, +   {"import-keyword", "header-name",      optional("attribute-specifier-seq"), ";"},    } },    { "global-module-fragment", { -   {"module", ";", optional("top-level-declaration-seq")}, +   {"module-keyword", ";", optional("declaration-seq")},    } },    { "private-module-fragment", { -   {"module", ":", "private", ";", optional("top-level-declaration-seq")}, +   {"module-keyword", ":", "private", ";", optional("declaration-seq")},    } },    // [gram.class] @@ -1492,7 +1575,6 @@ BNF GetCppBNFGram()     {"union"},    } }, -    { "member-specification", {     {"member-declaration", optional("member-specification")},     {"access-specifier", ":", optional("member-specification")}, @@ -1553,7 +1635,7 @@ BNF GetCppBNFGram()     {":", "base-specfier-list"},    } }, -  { "base-specfier-list", { +  { "base-specifier-list", {     {"base-specifier", optional("...")},     {"base-specifier-list", ",", "base-specifier", optional("...")},    } }, @@ -1602,7 +1684,7 @@ BNF GetCppBNFGram()    } },    { "OPERATOR", { -   {"new"}, {"delete"}, {"new[]"}, {"delete[]"}, {"co_await()[]"}, {"->"}, {"->*"}, +   {"new"}, {"delete"}, {"new[]"}, {"delete[]"}, {"co_await"}, {"()"}, {"[]"}, {"->"}, {"->*"},     {"~"}, {"!"}, {"+"}, {"-"}, {"*"}, {"/"}, {"%"}, {"^"}, {"&"},     {"|"}, {"="}, {"+="}, {"-="}, {"*="}, {"/="}, {"%="}, {"^="}, {"&="},     {"|="}, {"=="}, {"!="}, {"<"}, {">"}, {"<="}, {">="}, {"<=>"}, {"&&"}, @@ -1654,8 +1736,8 @@ BNF GetCppBNFGram()     {"type-parameter-key", optional("identifier"), "=", "type-id"},     {"type-constraint", optional("...") ,optional("identifier")},     {"type-constraint", optional("identifier"), "=", "type-id"}, -   {"template-head type-parameter-key", optional("..."), optional("identifier")}, -   {"template-head type-parameter-key", optional("identifier"), "=", "id-expression"}, +   {"template-head", "type-parameter-key", optional("..."), optional("identifier")}, +   {"template-head", "type-parameter-key", optional("identifier"), "=", "id-expression"},    } },    { "type-parameter-key", { @@ -1755,8 +1837,21 @@ BNF GetCppBNFGram()    { "preprocessing-file", {     {optional("group")}, +   {"module-file"}    } }, +  { "module-file", { +   {optional("pp-global-module-fragment"), "pp-module", optional("group"), optional("pp-private-module-fragment")}, +  }}, + +  { "pp-global-module-fragment", { +   {"module", ";", "\n", optional("group")}, +  }}, + +  { "pp-private-module-fragment", { +   {"module", ":", "private", ";", "new-line", optional("group")}, +  }}, +    { "group", {     {"group-part"},     {"group", "group-part"}, @@ -1771,7 +1866,7 @@ BNF GetCppBNFGram()    { "control-line", {     {"#", "include", "pp-tokens", "new-line"}, -   {optional("export"), "import", "pp-tokens", "new-line"}, +   {"pp-import"},     {"#", "define", "identifier", "replacement-list", "new-line"},     {"#", "define", "identifier", "lparen", optional("identifier-list"), ")", "replacement-list", "new-line"},     {"#", "define", "identifier", "lparen", "...", ")", "replacement-list", "new-line"}, @@ -1824,7 +1919,7 @@ BNF GetCppBNFGram()    { "identifier-list", {     {"identifier"}, -   {"identifier-list", "identifier"}, +   {"identifier-list", ",", "identifier"},    } },    { "replacement-list", { @@ -1868,34 +1963,16 @@ BNF GetCppBNFGram()     {"__has_cpp_attribute", "(", "pp-tokens", ")"},    } }, +  { "pp-module", { +   {optional("export"), "module", optional("pp-tokens"), ";", "new-line"}, +  }}, +    { "pp-import", {     {optional("export"), "import", "header-name",        optional("pp-tokens"), ";", "new-line"},     {optional("export"), "import", "header-name-tokens", optional("pp-tokens"), ";", "new-line"},     {optional("export"), "import",                                "pp-tokens",  ";", "new-line"},    } }, -  { "pp-global-module-fragment", { -   {"module", ";", "pp-balanced-token-seq", "module"}, -  } }, - -  { "pp-balanced-token-seq", { -   {"pp-balanced-token"}, -   {"pp-balanced-token-seq", "pp-balanced-token"}, -  } }, - -  { "pp-balanced-token", { -   {"pp-ldelim", optional("pp-balanced-token-seq"), "pp-rdelim"}, -   // TODO: + any preprocessing-token except pp-ldelim and pp-rdelim -  } }, - -  { "pp-ldelim", { -   {"(", "[", "{", "<:", "<%"}, -  } }, - -  { "pp-rdelim", { -   {")", "]", "}", ":>", "%>"}, -  } }, -    { "va-opt-replacement", {     {"__VA_OPT__", "(", optional("pp-tokens"), ")"},    } }, diff --git a/tests/test-cpp.cpp b/tests/test-cpp.cpp index e5b2a1a..adfa54b 100644 --- a/tests/test-cpp.cpp +++ b/tests/test-cpp.cpp @@ -24,7 +24,7 @@ class CppTest: public ::testing::Test  {  protected:   CppTest() { -  //debug = true; +  debug = true;   }   ~CppTest() {   } @@ -42,7 +42,22 @@ TEST_F(CppTest, preprocessing_tokenize) {   auto nodes = cpp.analysis(tokens); - ASSERT_EQ(nodes.size(), 60/*44*/); + ASSERT_EQ(nodes.size(), 58/*44*/); +} + +TEST_F(CppTest, preprocessing_tokenize_empty) { + CPP cpp; + auto pp_tokens = cpp.preprocessing_tokenize(""); + + ASSERT_EQ(pp_tokens.size(), 0); + + auto tokens = cpp.tokens_from_pptokens(pp_tokens); + + ASSERT_EQ(tokens.size(), 0); + + auto nodes = cpp.analysis(tokens); +  + ASSERT_EQ(nodes.size(), 0);  }  TEST_F(CppTest, preprocessing_tokenize_compile_error) { diff --git a/tests/test-grammer.cpp b/tests/test-grammer.cpp index 1734da2..6af6992 100644 --- a/tests/test-grammer.cpp +++ b/tests/test-grammer.cpp @@ -50,7 +50,7 @@ TEST_F(GrammerTest, minimumSymbolsNeeded) {   EXPECT_EQ(minimumSymbolsNeeded(compiler, "logical-or-expression"), 1);   EXPECT_EQ(minimumSymbolsNeeded(compiler, "assignment-expression"), 1);   EXPECT_EQ(minimumSymbolsNeeded(compiler, "declaration"), 1); - EXPECT_EQ(minimumSymbolsNeeded(compiler, "block-declaration"), 3); + EXPECT_EQ(minimumSymbolsNeeded(compiler, "block-declaration"), 2);   EXPECT_EQ(minimumSymbolsNeeded(compiler, "simple-declaration"), 2);   EXPECT_EQ(minimumSymbolsNeeded(compiler, "asm-declaration"), 5);   EXPECT_EQ(minimumSymbolsNeeded(compiler, "namespace-alias-definition"), 5); @@ -58,8 +58,8 @@ TEST_F(GrammerTest, minimumSymbolsNeeded) {   EXPECT_EQ(minimumSymbolsNeeded(compiler, "using-enum-declaration"), 4);   EXPECT_EQ(minimumSymbolsNeeded(compiler, "using-directive"), 4);   EXPECT_EQ(minimumSymbolsNeeded(compiler, "static_assert-declaration"), 5); - EXPECT_EQ(minimumSymbolsNeeded(compiler, "alias-declaration"), 7); + EXPECT_EQ(minimumSymbolsNeeded(compiler, "alias-declaration"), 5);   EXPECT_EQ(minimumSymbolsNeeded(compiler, "opaque-enum-declaration"), 3); - EXPECT_EQ(minimumSymbolsNeeded(compiler, "function-definition"), 4); + EXPECT_EQ(minimumSymbolsNeeded(compiler, "function-definition"), 3);  } | 
