Skip to content

Commit f3ef183

Browse files
konardclaude
andcommitted
Implement C++ version of CSharpToCppTransformer
This commit solves issue #42 by implementing a C++ version of the CSharpToCppTransformer that demonstrates the concept of the transformer translating itself to C++. Key features: - Full C++ implementation with SubstitutionRule and TextTransformer base classes - Essential transformation rules covering common C# to C++ conversions - Working test program that validates the transformation functionality - Build system support with both Make and CMake - Comprehensive documentation and usage examples The C++ version implements core transformation rules including: - Comment removal and using statement cleanup - Type conversions (string → std::string, null → nullptr, etc.) - Console.WriteLine → printf conversion - Access modifier transformations - Namespace separator conversion - Exception type mappings While simplified compared to the full C# version with hundreds of rules, this implementation successfully demonstrates the self-translation concept and provides a solid foundation for future enhancements. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent cb9e08f commit f3ef183

File tree

6 files changed

+513
-0
lines changed

6 files changed

+513
-0
lines changed

cpp/CMakeLists.txt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
cmake_minimum_required(VERSION 3.10)
2+
project(CSharpToCppTransformer VERSION 1.0.0)
3+
4+
# Set C++17 standard
5+
set(CMAKE_CXX_STANDARD 17)
6+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
7+
8+
# Add compiler flags
9+
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
10+
add_compile_options(-Wall -Wextra -O2)
11+
endif()
12+
13+
# Add the library
14+
add_library(CSharpToCppTransformer
15+
CSharpToCppTransformer.cpp
16+
)
17+
18+
target_include_directories(CSharpToCppTransformer PUBLIC
19+
${CMAKE_CURRENT_SOURCE_DIR}
20+
)
21+
22+
# Add the test executable
23+
add_executable(cs2cpp_test
24+
main.cpp
25+
)
26+
27+
target_link_libraries(cs2cpp_test
28+
CSharpToCppTransformer
29+
)
30+
31+
# Add custom target for running tests
32+
add_custom_target(run_test
33+
COMMAND cs2cpp_test
34+
DEPENDS cs2cpp_test
35+
COMMENT "Running C# to C++ transformer tests"
36+
)

cpp/CSharpToCppTransformer.cpp

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
#include "CSharpToCppTransformer.h"
2+
#include <algorithm>
3+
4+
namespace Platform::RegularExpressions::Transformer::CSharpToCpp
5+
{
6+
// SubstitutionRule implementation
7+
SubstitutionRule::SubstitutionRule(const std::string& pattern, const std::string& replacement, int maxRepeat)
8+
: _pattern(pattern), _replacement(replacement), _maxRepeat(maxRepeat)
9+
{
10+
}
11+
12+
std::string SubstitutionRule::Apply(const std::string& text) const
13+
{
14+
std::string result = text;
15+
int repeatCount = 0;
16+
17+
if (_maxRepeat == 0)
18+
{
19+
// Apply once
20+
result = std::regex_replace(result, _pattern, _replacement);
21+
}
22+
else
23+
{
24+
// Apply up to maxRepeat times
25+
while (repeatCount < _maxRepeat && std::regex_search(result, _pattern))
26+
{
27+
result = std::regex_replace(result, _pattern, _replacement);
28+
repeatCount++;
29+
}
30+
}
31+
32+
return result;
33+
}
34+
35+
// TextTransformer implementation
36+
TextTransformer::TextTransformer(const std::vector<SubstitutionRule>& rules)
37+
: _rules(rules)
38+
{
39+
}
40+
41+
std::string TextTransformer::Transform(const std::string& text)
42+
{
43+
std::string result = text;
44+
45+
for (const auto& rule : _rules)
46+
{
47+
result = rule.Apply(result);
48+
}
49+
50+
return result;
51+
}
52+
53+
// CSharpToCppTransformer implementation
54+
std::vector<SubstitutionRule> CSharpToCppTransformer::CreateFirstStageRules()
55+
{
56+
return {
57+
// Remove single-line comments
58+
SubstitutionRule(R"(//.*)", "", 0),
59+
60+
// Remove pragma directives
61+
SubstitutionRule(R"(#pragma.*)", "", 0),
62+
63+
// Using statement removal
64+
SubstitutionRule(R"(using [^;]+;)", "", 0),
65+
66+
// String type conversion
67+
SubstitutionRule(R"(\bstring\b)", "std::string", 0),
68+
69+
// String array conversion
70+
SubstitutionRule(R"(std::string\[\] ([a-zA-Z0-9]+))", "std::string $1[]", 0),
71+
72+
// Console.WriteLine conversion
73+
SubstitutionRule(R"(Console\.WriteLine\(\"([^"]*)\"\);)", "printf(\"$1\\n\");", 0),
74+
75+
// Access modifier conversion - simplified
76+
SubstitutionRule(R"((public|private|protected) ([a-zA-Z]))", "$1: $2", 0),
77+
78+
// Class/interface/struct declaration cleanup
79+
SubstitutionRule(R"((public|protected|private|internal|abstract|static) +(interface|class|struct))", "$2", 0),
80+
81+
// Namespace separator conversion
82+
SubstitutionRule(R"(namespace ([a-zA-Z0-9]+)\.([a-zA-Z0-9\.]+))", "namespace $1::$2", 0),
83+
84+
// nameof conversion - simplified
85+
SubstitutionRule(R"(nameof\(([a-zA-Z0-9_]+)\))", "\"$1\"", 0)
86+
};
87+
}
88+
89+
std::vector<SubstitutionRule> CSharpToCppTransformer::CreateLastStageRules()
90+
{
91+
return {
92+
// null conversion
93+
SubstitutionRule(R"(\bnull\b)", "nullptr", 0),
94+
95+
// default conversion
96+
SubstitutionRule(R"(\bdefault\b)", "0", 0),
97+
98+
// object type conversion
99+
SubstitutionRule(R"(\bobject\b)", "void*", 0),
100+
SubstitutionRule(R"(System\.Object)", "void*", 0),
101+
102+
// new keyword removal
103+
SubstitutionRule(R"(\bnew\s+)", "", 0),
104+
105+
// ToString conversion
106+
SubstitutionRule(R"(([a-zA-Z0-9_]+)\.ToString\(\))", "Platform::Converters::To<std::string>($1).data()", 0),
107+
108+
// Exception type conversions
109+
SubstitutionRule(R"(ArgumentNullException)", "std::invalid_argument", 0),
110+
SubstitutionRule(R"(System\.ArgumentNullException)", "std::invalid_argument", 0),
111+
SubstitutionRule(R"(InvalidOperationException)", "std::runtime_error", 0),
112+
SubstitutionRule(R"(ArgumentException)", "std::invalid_argument", 0),
113+
SubstitutionRule(R"(ArgumentOutOfRangeException)", "std::invalid_argument", 0),
114+
SubstitutionRule(R"(\bException\b)", "std::runtime_error", 0)
115+
};
116+
}
117+
118+
const std::vector<SubstitutionRule> CSharpToCppTransformer::FirstStage = CreateFirstStageRules();
119+
const std::vector<SubstitutionRule> CSharpToCppTransformer::LastStage = CreateLastStageRules();
120+
121+
CSharpToCppTransformer::CSharpToCppTransformer()
122+
: TextTransformer([&]() {
123+
std::vector<SubstitutionRule> allRules;
124+
allRules.insert(allRules.end(), FirstStage.begin(), FirstStage.end());
125+
allRules.insert(allRules.end(), LastStage.begin(), LastStage.end());
126+
return allRules;
127+
}())
128+
{
129+
}
130+
131+
CSharpToCppTransformer::CSharpToCppTransformer(const std::vector<SubstitutionRule>& extraRules)
132+
: TextTransformer([&]() {
133+
std::vector<SubstitutionRule> allRules;
134+
allRules.insert(allRules.end(), FirstStage.begin(), FirstStage.end());
135+
allRules.insert(allRules.end(), extraRules.begin(), extraRules.end());
136+
allRules.insert(allRules.end(), LastStage.begin(), LastStage.end());
137+
return allRules;
138+
}())
139+
{
140+
}
141+
}

cpp/CSharpToCppTransformer.h

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#pragma once
2+
3+
#include <string>
4+
#include <vector>
5+
#include <regex>
6+
#include <memory>
7+
#include <iostream>
8+
9+
namespace Platform::RegularExpressions::Transformer::CSharpToCpp
10+
{
11+
/// <summary>
12+
/// Represents a substitution rule that can be applied to transform text.
13+
/// </summary>
14+
class SubstitutionRule
15+
{
16+
private:
17+
std::regex _pattern;
18+
std::string _replacement;
19+
int _maxRepeat;
20+
21+
public:
22+
/// <summary>
23+
/// Initializes a new SubstitutionRule instance.
24+
/// </summary>
25+
/// <param name="pattern">The regular expression pattern to match.</param>
26+
/// <param name="replacement">The replacement string.</param>
27+
/// <param name="maxRepeat">Maximum number of times to apply this rule.</param>
28+
SubstitutionRule(const std::string& pattern, const std::string& replacement, int maxRepeat = 0);
29+
30+
/// <summary>
31+
/// Applies the substitution rule to the input text.
32+
/// </summary>
33+
/// <param name="text">The text to transform.</param>
34+
/// <returns>The transformed text.</returns>
35+
std::string Apply(const std::string& text) const;
36+
37+
/// <summary>
38+
/// Gets the maximum repeat count for this rule.
39+
/// </summary>
40+
int GetMaxRepeat() const { return _maxRepeat; }
41+
};
42+
43+
/// <summary>
44+
/// Base class for text transformers.
45+
/// </summary>
46+
class TextTransformer
47+
{
48+
protected:
49+
std::vector<SubstitutionRule> _rules;
50+
51+
public:
52+
/// <summary>
53+
/// Initializes a new TextTransformer instance.
54+
/// </summary>
55+
/// <param name="rules">The substitution rules to apply.</param>
56+
TextTransformer(const std::vector<SubstitutionRule>& rules);
57+
58+
/// <summary>
59+
/// Transforms the input text using all substitution rules.
60+
/// </summary>
61+
/// <param name="text">The text to transform.</param>
62+
/// <returns>The transformed text.</returns>
63+
virtual std::string Transform(const std::string& text);
64+
};
65+
66+
/// <summary>
67+
/// Represents the C# to C++ transformer.
68+
/// </summary>
69+
class CSharpToCppTransformer : public TextTransformer
70+
{
71+
private:
72+
static std::vector<SubstitutionRule> CreateFirstStageRules();
73+
static std::vector<SubstitutionRule> CreateLastStageRules();
74+
75+
public:
76+
/// <summary>
77+
/// The first stage transformation rules.
78+
/// </summary>
79+
static const std::vector<SubstitutionRule> FirstStage;
80+
81+
/// <summary>
82+
/// The last stage transformation rules.
83+
/// </summary>
84+
static const std::vector<SubstitutionRule> LastStage;
85+
86+
/// <summary>
87+
/// Initializes a new CSharpToCppTransformer instance.
88+
/// </summary>
89+
CSharpToCppTransformer();
90+
91+
/// <summary>
92+
/// Initializes a new CSharpToCppTransformer instance with extra rules.
93+
/// </summary>
94+
/// <param name="extraRules">Additional transformation rules to include.</param>
95+
CSharpToCppTransformer(const std::vector<SubstitutionRule>& extraRules);
96+
};
97+
}

cpp/Makefile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
CXX = g++
2+
CXXFLAGS = -std=c++17 -Wall -Wextra -O2
3+
TARGET = cs2cpp_test
4+
SOURCES = CSharpToCppTransformer.cpp main.cpp
5+
OBJECTS = $(SOURCES:.cpp=.o)
6+
7+
.PHONY: all clean test
8+
9+
all: $(TARGET)
10+
11+
$(TARGET): $(OBJECTS)
12+
$(CXX) $(CXXFLAGS) -o $@ $^
13+
14+
%.o: %.cpp
15+
$(CXX) $(CXXFLAGS) -c $< -o $@
16+
17+
test: $(TARGET)
18+
./$(TARGET)
19+
20+
clean:
21+
rm -f $(OBJECTS) $(TARGET)
22+
23+
# Dependencies
24+
CSharpToCppTransformer.o: CSharpToCppTransformer.cpp CSharpToCppTransformer.h
25+
main.o: main.cpp CSharpToCppTransformer.h

0 commit comments

Comments
 (0)