added readme, and fixed linnux compilation
This commit is contained in:
parent
b011a5d94c
commit
15e16138bd
6 changed files with 57 additions and 14 deletions
45
README.md
Normal file
45
README.md
Normal file
|
|
@ -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.
|
||||
3
makefile
3
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
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
#pragma once
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include "base.hpp"
|
||||
#include "operators.hpp"
|
||||
#include "literals.hpp"
|
||||
|
|
@ -210,4 +213,4 @@ struct Tuple : Expr
|
|||
}
|
||||
return oss.str();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
#pragma once
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include "string_utils.hpp"
|
||||
|
|
@ -247,4 +249,4 @@ struct While : Stmt
|
|||
}
|
||||
return oss.str();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
|||
12
src/main.cpp
12
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<kind>(tok));
|
||||
break;
|
||||
}
|
||||
|
||||
// std::cout << Parser::symbol_name(static_cast<kind>(tok));
|
||||
|
||||
if (tok == Parser::token::TOK_IDENTIFIER || tok == Parser::token::TOK_NUMBER || tok == Parser::token::TOK_STRING)
|
||||
{
|
||||
// std::cout << " " << lval.as<std::string>();
|
||||
}
|
||||
|
||||
// std::cout << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -97,4 +87,4 @@ int main(int argc, char *argv[])
|
|||
RubyGenerator generator;
|
||||
std::cout << generator.generate(*ast_root);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
%code requires {
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "ast.hpp"
|
||||
class Scanner;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue