π― A sophisticated compiler that translates C-like source code into optimized Three-Address Code (3AC) with advanced semantic analysis and scope management.
- π Key Features
- ποΈ Architecture
- π Language Support
- π§ Installation
- π Usage
- π Three-Address Code Generation
- π Examples
- π€ Contributing
- β Complete Token Recognition: 40+ token types including keywords, operators, and literals
- β
Advanced Literals Support:
- Integer literals (decimal and hexadecimal)
- Floating-point literals (float and double)
- String literals with escape sequences
- Boolean literals (
true
/false
) - Character literals
- β Comprehensive Operators: Arithmetic, logical, comparison, and assignment operators
- β
Comment Handling: Multi-line C-style comments (
/* */
) with proper nesting - β
Error Recovery: Robust error handling with
setjmp/longjmp
exception mechanism
- β Complete Grammar: 50+ production rules covering full C-like syntax
- β Function Definitions: Support for public/private access modifiers and static functions
- β Variable Declarations: Multiple data types with initialization support
- β
Control Structures:
- Conditional statements (
if
,if-else
) - Loops (
while
,do-while
,for
) - Block statements with proper scoping
- Conditional statements (
- β Expression Evaluation: Complex arithmetic and logical expressions with precedence
- β Array Operations: Array indexing, assignment, and address operations
- β Pointer Support: Pointer declarations, dereferencing, and address-of operations
- β Multi-Level Symbol Tables: Hierarchical scope management with nested function support
- β Type Checking: Comprehensive type compatibility verification
- β Scope Resolution: Proper variable and function lookup across scopes
- β Function Signature Validation: Parameter count and type verification
- β Memory Management: Automatic symbol table cleanup and memory deallocation
- β Optimized 3AC Output: Efficient intermediate code generation
- β
Control Flow Translation:
- Conditional jumps with label generation
- Loop constructs with proper branching
- Short-circuit evaluation for logical operators
- β Function Call Handling: Parameter passing and return value management
- β Expression Optimization: Temporary variable management and reuse
- β Memory Layout: Stack frame calculation and variable offset management
- β
Exception Mechanism:
TRY-CATCH
blocks for graceful error recovery - β Detailed Error Messages: Line number reporting and context information
- β Syntax Error Recovery: Continues parsing after encountering errors
- β Semantic Error Detection: Type mismatches and undeclared variable detection
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β Source Code βββββΆβ Lexical βββββΆβ Token Stream β
β (.c-like) β β Analyzer β β β
βββββββββββββββββββ β (ProjectLex.l) β βββββββββββββββββββ
ββββββββββββββββββββ β
βΌ
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β Three-Address ββββββ Parser & ββββββ Syntax β
β Code (3AC) β β Semantic β β Analysis β
β β β Analyzer β β β
βββββββββββββββββββ β (ProjectYacc.y)β βββββββββββββββββββ
ββββββββββββββββββββ
if, else, while, for, do, return, var, args>>
public, private, static, void, null
bool, char, int, double, float, string
int*, char*, double*, float* // Pointer types
- Primitive Types:
int
,char
,double
,float
,bool
,string
- Pointer Types:
int*
,char*
,double*
,float*
- Literals: Integer, hexadecimal, floating-point, boolean, character, string
- Special:
void
,null
Category | Operators | Description |
---|---|---|
Arithmetic | + , - , * , / |
Basic math operations |
Assignment | <- |
Variable assignment |
Comparison | == , != , <= , >= , < , > |
Relational operators |
Logical | && , || , ! |
Boolean operations |
Memory | & , * |
Address-of and dereference |
- Functions: With access modifiers (
public
,private
,static
) - Control Flow:
if-else
,while
,do-while
,for
loops - Arrays: Declaration, indexing, and manipulation
- Pointers: Declaration, dereferencing, and address operations
- Scoping: Block-level and function-level scope management
- Flex (Fast Lexical Analyzer)
- Bison/Yacc (Parser Generator)
- GCC (GNU Compiler Collection)
- Make (Build automation tool)
# Install using Chocolatey
choco install winflexbison3
choco install mingw
# Or download from:
# https://github.com/lexxmark/winflexbison/releases
# https://www.mingw-w64.org/downloads/
# Ubuntu/Debian
sudo apt-get install flex bison gcc make
# CentOS/RHEL
sudo yum install flex bison gcc make
# Arch Linux
sudo pacman -S flex bison gcc make
# Using Homebrew
brew install flex bison gcc make
# Using MacPorts
sudo port install flex bison gcc make
# Generate lexer
flex ProjectLex.l
# Generate parser
bison -d ProjectYacc.y
# or
yacc -d ProjectYacc.y
# Compile the compiler
gcc -o compiler lex.yy.c y.tab.c -lfl
# Compile a source file
./compiler < input.c
# Or with input redirection
./compiler input.c
# View generated 3AC
./compiler input.c > output.3ac
// sample.c
public int main() {
var int x <- 10;
var int y <- 20;
var int result;
if (x < y) {
result <- x + y;
} else {
result <- x - y;
}
return result;
}
The compiler generates optimized three-address code with the following characteristics:
- Temporary Variables:
t1
,t2
,t3
, ... - Labels:
L1
,L2
,L3
, ... - Operations: Binary and unary operations
- Control Flow: Conditional and unconditional jumps
// For the sample input above
ENTER main, 12 // Function entry with stack size
t1 = 10 // x <- 10
t2 = 20 // y <- 20
t3 = t1 < t2 // Comparison
if t3 goto L1 // Conditional jump
t4 = t1 - t2 // else branch
goto L2
L1: t4 = t1 + t2 // if branch
L2: return t4 // Return result
EXIT main // Function exit
- Temporary Reuse: Efficient temporary variable management
- Dead Code Elimination: Removes unreachable code
- Constant Folding: Evaluates constant expressions at compile time
- Short-Circuit Evaluation: Optimizes logical expressions
// Input
public void fibonacci(int n) {
var int a <- 0;
var int b <- 1;
var int i <- 0;
while (i < n) {
var int temp <- a + b;
a <- b;
b <- temp;
i <- i + 1;
}
}
// Generated 3AC
ENTER fibonacci, 16
t1 = 0 // a <- 0
t2 = 1 // b <- 1
t3 = 0 // i <- 0
L1: t4 = t3 < param1 // while condition
if_false t4 goto L2
t5 = t1 + t2 // temp <- a + b
t1 = t2 // a <- b
t2 = t5 // b <- temp
t3 = t3 + 1 // i <- i + 1
goto L1
L2: EXIT fibonacci
// Input
public int add(int a, int b) {
return a + b;
}
public int main() {
var int result <- add(5, 3);
return result;
}
// Generated 3AC
ENTER add, 8
t1 = param1 + param2
return t1
EXIT add
ENTER main, 4
param1 = 5
param2 = 3
call add, 2
t2 = retval
return t2
EXIT main
If you find any bugs or issues, please:
- Check existing issues first
- Create a detailed bug report with:
- Input code that causes the issue
- Expected vs actual behavior
- System information
We welcome suggestions for:
- New language features
- Optimization improvements
- Better error messages
- Additional output formats
# Fork the repository
git clone https://github.com/yourusername/C-Like-Compiler.git
cd C-Like-Compiler
# Make your changes
# Test thoroughly
# Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
- Flex/Lex - Fast lexical analyzer generator
- Bison/Yacc - Parser generator
- GNU Compiler Collection - For compilation tools
- The Dragon Book - Compilers: Principles, Techniques, and Tools
β Star this repository if you find it helpful! β
Built with β€οΈ for compiler enthusiasts