From 15e16138bdba852a58697b3dae63a2e2c0d3fab5 Mon Sep 17 00:00:00 2001 From: bronku Date: Fri, 9 Jan 2026 01:35:49 +0100 Subject: [PATCH] added readme, and fixed linnux compilation --- README.md | 45 +++++++++++++++++++++++++++++++++++++++++ makefile | 3 ++- src/ast/expressions.hpp | 5 ++++- src/ast/statements.hpp | 4 +++- src/main.cpp | 12 +---------- src/parser.y | 2 ++ 6 files changed, 57 insertions(+), 14 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..c45bed7 --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +# Python-to-Ruby Transpiler (py2rb) + +A source-to-source transpiler that converts Python syntax into Ruby code. Built using **Flex** for lexical analysis and **Bison** for LALR(1) parsing, this project implements a full compilation pipeline from tokenization to code generation. + +## Technical Architecture + +The transpiler is architected into three distinct phases: + +1. **Lexical Analysis (`Flex`):** Handles Python-specific challenges like indentation-based scoping using a custom `indent_stack`. It supports complex literals including f-strings, triple-quoted strings, and various numeric bases (hex, binary). +2. **LALR Parsing (`Bison`):** Implements a formal grammar for a significant subset of Python, including class definitions, function nesting, and control flow. It constructs a strongly-typed Abstract Syntax Tree (AST) using C++17 smart pointers. +3. **Code Generation:** A recursive AST visitor (via the `RubyGenerator`) that maps Python semantics to Ruby equivalents. This includes specialized mapping for Python dunder methods (e.g., `__init__` → `initialize`, `__str__` → `to_s`) and boolean literals. + + + +## Key Features + +* **Semantic Mapping:** Automatically converts Python-specific constructs (like `self`) into Ruby syntax. +* **Indentation-to-Block Conversion:** Correctly translates Python's significant whitespace into Ruby's `end`-delimited blocks. +* **Comprehensive Test Suite:** Includes test cases covering lexing, parsing, and end-to-end Ruby generation. +* **AST Auditing:** Built-in support for AST and token stream dumping for debugging and verification. + +## Build and Usage + +### Prerequisites +* `g++` +* `flex` +* `bison` + +### Build +```bash +make +``` + +### Usage +```bash +# Transpile a file and output to stdout +./build/py2rb --file input.py + +# Run the automated test suite +make test +``` + +Implementation Details & Shortcomings + +For a list of current language subset limitations (e.g., tuple-to-list conversion, specific string processing logic), see shortcomings.md. diff --git a/makefile b/makefile index aeb4ac4..8cfec19 100644 --- a/makefile +++ b/makefile @@ -1,6 +1,7 @@ CXX = g++ ARGS = -std=c++17 -Ibuild -Isrc -BISON = /opt/homebrew/opt/bison/bin/bison +#BISON = /opt/homebrew/opt/bison/bin/bison +BISON = bison FLEX = flex TARGET = build/py2rb diff --git a/src/ast/expressions.hpp b/src/ast/expressions.hpp index a35188b..c9898ae 100644 --- a/src/ast/expressions.hpp +++ b/src/ast/expressions.hpp @@ -1,5 +1,8 @@ #pragma once #include +#include +#include +#include #include "base.hpp" #include "operators.hpp" #include "literals.hpp" @@ -210,4 +213,4 @@ struct Tuple : Expr } return oss.str(); } -}; \ No newline at end of file +}; diff --git a/src/ast/statements.hpp b/src/ast/statements.hpp index 338a9ed..1809dc0 100644 --- a/src/ast/statements.hpp +++ b/src/ast/statements.hpp @@ -1,4 +1,6 @@ #pragma once +#include +#include #include #include #include "string_utils.hpp" @@ -247,4 +249,4 @@ struct While : Stmt } return oss.str(); } -}; \ No newline at end of file +}; diff --git a/src/main.cpp b/src/main.cpp index 9203afd..26716c6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,18 +17,8 @@ void dump_tokens(Scanner &scanner) int tok = scanner.lex(&lval); if (tok == Parser::token::TOK_EOF) { - // std::cout << Parser::symbol_name(static_cast(tok)); break; } - - // std::cout << Parser::symbol_name(static_cast(tok)); - - if (tok == Parser::token::TOK_IDENTIFIER || tok == Parser::token::TOK_NUMBER || tok == Parser::token::TOK_STRING) - { - // std::cout << " " << lval.as(); - } - - // std::cout << "\n"; } } @@ -97,4 +87,4 @@ int main(int argc, char *argv[]) RubyGenerator generator; std::cout << generator.generate(*ast_root); } -} \ No newline at end of file +} diff --git a/src/parser.y b/src/parser.y index 6929c06..d64005c 100644 --- a/src/parser.y +++ b/src/parser.y @@ -11,6 +11,8 @@ %code requires { #include + #include + #include #include "ast.hpp" class Scanner; }