Skip to content

Aubin9/mini_compiler

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Mini Arithmetic Language Compiler

A complete implementation of a compiler for a simple arithmetic expression language, demonstrating lexical analysis, syntactic analysis, and formal language concepts.

Output

Image Image2

πŸ“‹ Table of Contents

πŸ“– Overview

This project implements a mini compiler for an arithmetic expression language as part of a formal language theory demonstration. It covers the fundamental stages of compiler front-end design including:

  • Lexical Analysis: Token identification using Deterministic Finite Automata (DFA)
  • Syntactic Analysis: Recursive descent parsing with Context-Free Grammar (CFG)
  • Grammar Analysis: Left recursion elimination, FIRST and FOLLOW sets
  • Semantic Analysis: Expression validation and error detection

The project demonstrates how formal language theory provides the theoretical foundation for modern compilers and interpreters.

✨ Features

Core Features

  • βœ… Tokenization: Identifies identifiers, numbers, operators, and parentheses
  • βœ… DFA Implementation: Deterministic Finite Automata for identifiers and numbers
  • βœ… Grammar Analysis: Original grammar with left recursion elimination
  • βœ… Recursive Descent Parser: Predictive parsing using grammar after left recursion removal
  • βœ… Parse Tree Generation: Visual representation of syntactic structure
  • βœ… Expression Validation: Accepts/rejects expressions based on language rules
  • βœ… Error Detection: Clear error messages for syntax and semantic errors

Language Support

  • Identifiers: a, b, x, total1, num2
  • Numbers: 12, 50, 1000
  • Operators: +, -, *, /
  • Parentheses: (, )

Modes of Operation

  • Demonstration Mode: Shows complete compilation pipeline with examples
  • Interactive Mode: Enter expressions to compile in real-time
  • Command-Line Mode: Compile specific expressions directly

πŸ“ Project Structure


mini_compiler/
β”œβ”€β”€ main.py # Entry point and demonstration
β”œβ”€β”€ lexer/
β”‚ β”œβ”€β”€ **init**.py
β”‚ β”œβ”€β”€ token.py # Token classes and enums
β”‚ └── lexer.py # Lexical analyzer with DFA
β”œβ”€β”€ parser/
β”‚ β”œβ”€β”€ **init**.py
β”‚ β”œβ”€β”€ ast.py # Abstract Syntax Tree nodes
β”‚ └── parser.py # Recursive descent parser
β”œβ”€β”€ analyzer/
β”‚ β”œβ”€β”€ **init**.py
β”‚ β”œβ”€β”€ grammar.py # Grammar analysis utilities
β”‚ └── validator.py # Expression validation
└── utils/
β”œβ”€β”€ **init**.py
└── printer.py # Pretty printing utilities

πŸ”§ Installation

Prerequisites

  • Python 3.6 or higher
  • No external dependencies required

Setup

  1. Clone the repository:
git clone link
cd mini-compiler
  1. Verify installation:
python main.py --help

πŸš€ Usage

Method 1: Run Full Demonstration

python main.py

This runs a comprehensive demonstration with:

  • All test expressions
  • Grammar analysis
  • DFA diagrams
  • Parse tree visualization

Method 2: Compile a Specific Expression

python main.py "a+b*c"
python main.py "(a+b)*(c+d)"
python main.py "100+25*2"

Method 3: Interactive Mode

python main.py
# Then type 'y' when prompted for interactive mode
# Enter expressions one by one

Method 4: Use as a Module

from lexer import Lexer
from parser import Parser

# Lexical analysis
lexer = Lexer("a+b*c")
tokens = lexer.tokenize()

# Syntactic analysis
parser = Parser(tokens)
ast = parser.parse()

πŸ“š Language Specification

Grammar (After Left Recursion Elimination)

E  -> T E'
E' -> + T E' | - T E' | Ξ΅
T  -> F T'
T' -> * F T' | / F T' | Ξ΅
F  -> (E) | id | num

Token Definitions

Token Type Pattern Example
IDENTIFIER letter(letter|digit)* a, b, x1
NUMBER digit+ 12, 50, 1000
PLUS + +
MINUS - -
MULT * *
DIV / /
LPAREN ( (
RPAREN ) )

Accepted Expressions

  • a+b
  • a*b+c
  • (a+b)*c
  • x+y*z
  • (a+b)*(c+d)
  • 100+25
  • num1*value2

Rejected Expressions

  • +a (starts with operator)
  • a+ (ends with operator)
  • a** (invalid operator sequence)
  • (a+b (unbalanced parentheses)
  • a+b) (unbalanced parentheses)
  • */ab (invalid operator sequence)
  • a+*b (invalid operator sequence)

πŸ—οΈ Compiler Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           SOURCE PROGRAM                        β”‚
β”‚         (a+b*c, x+y*z, etc.)                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           LEXICAL ANALYZER                      β”‚
β”‚         (Scanner/Tokenizer)                    β”‚
β”‚      Identifies: id, num, +, -, *, /, (, )    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           TOKEN STREAM                         β”‚
β”‚   [id, +, id, *, id, EOF]                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           SYNTAX ANALYZER                      β”‚
β”‚         (Parser)                              β”‚
β”‚      Recursive Descent Parsing                β”‚
β”‚      Grammar: E -> T E'                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           PARSE TREE                          β”‚
β”‚          (AST)                                β”‚
β”‚      Represents the syntactic structure       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           SEMANTIC ANALYSIS                    β”‚
β”‚         (Optional)                            β”‚
β”‚      Type checking, validation                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ’‘ Examples

Example 1: Compiling "a+b*c"

Token Stream:

Token(IDENTIFIER, 'a', line=1, col=1)
Token(PLUS, '+', line=1, col=2)
Token(IDENTIFIER, 'b', line=1, col=3)
Token(MULT, '*', line=1, col=4)
Token(IDENTIFIER, 'c', line=1, col=5)
Token(EOF, 'EOF', line=1, col=6)

Parse Tree:

E
β”œβ”€β”€ T
β”‚   β”œβ”€β”€ F
β”‚   β”‚   └── a
β”‚   └── T'
β”‚       └── Ξ΅
└── E'
    β”œβ”€β”€ '+'
    β”œβ”€β”€ T
    β”‚   β”œβ”€β”€ F
    β”‚   β”‚   └── b
    β”‚   └── T'
    β”‚       β”œβ”€β”€ '*'
    β”‚       β”œβ”€β”€ F
    β”‚       β”‚   └── c
    β”‚       └── T'
    β”‚           └── Ξ΅
    └── E'
        └── Ξ΅

Example 2: Leftmost Derivation for "a+b*c"

E
=> T E'
=> F T' E'
=> id T' E'
=> a E'
=> a + T E'
=> a + F T' E'
=> a + b T' E'
=> a + b * F T' E'
=> a + b * c

Example 3: Rightmost Derivation for "a+b*c"

E
=> T E'
=> T + T E'
=> T + T
=> T + F T'
=> T + b T'
=> T + b * F
=> T + b * c
=> a + b * c

πŸ”¬ Technical Details

DFA for Identifiers

State q0 = Start
State q1 = Accept

q0 --letter--> q1
q1 --letter/digit--> q1

DFA for Numbers

State q0 = Start
State q1 = Accept

q0 --digit--> q1
q1 --digit--> q1

FIRST and FOLLOW Sets

Symbol FIRST FOLLOW
E {(, id, num} {), $}
T {(, id, num} {+, -, ), $}
F {(, id, num} {*, /, +, -, ), $}
E' {+, -, Ξ΅} {), $}
T' {*, /, Ξ΅} {+, -, ), $}

Operator Precedence

  1. Highest: Parentheses ( )
  2. Medium: Multiplication *, Division /
  3. Lowest: Addition +, Subtraction -

πŸ§ͺ Testing

Test Expressions

The project includes a comprehensive test suite with both accepted and rejected expressions:

Accepted:

test_expressions = [
    "a+b",
    "a*b+c",
    "(a+b)*c",
    "x+y*z",
    "(a+b)*(c+d)",
    "100+25",
    "num1*value2"
]

Rejected:

test_expressions = [
    "+a",      # Starts with operator
    "a+",      # Ends with operator
    "a**",     # Invalid operator sequence
    "(a+b",    # Unbalanced parentheses
    "a+b)",    # Unbalanced parentheses
    "*/ab",    # Invalid operator sequence
    "a+*b"     # Invalid operator sequence
]

Running Tests

# Run all tests
python main.py

# Test specific expression
python main.py "a+b*c"

πŸ“– Educational Value

This project demonstrates:

  1. Formal Language Theory in practice
  2. Compiler Design fundamentals
  3. Automata Theory (DFA implementation)
  4. Grammar Theory (left recursion elimination)
  5. Parsing Techniques (recursive descent)
  6. Software Engineering principles (modular design)

🀝 Contributing

Contributions are welcome! Here's how you can help:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

Areas for Improvement

  • Add support for more operators (e.g., %, ^)
  • Implement semantic analysis (type checking)
  • Add code generation (e.g., generate Python bytecode)
  • Implement error recovery in the parser
  • Add unit tests
  • Create a web interface

πŸ“ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • Based on the project requirements from the Faculty of Engineering and Technology, Department of Computer Engineering
  • Inspired by the formal language theory concepts from:
    • "Compilers: Principles, Techniques and Tools" by Aho, Lam, Sethi, and Ullman
    • "Introduction to Automata Theory, Languages and Computation" by Hopcroft, Motwani, and Ullman

πŸ“§ Contact

For questions or feedback, please contact:

  • Project Lead: [SIAHA TOUKO AUBIN]
  • Email: [[email protected]]
  • Department: Department of Computer Engineering
  • Faculty: Faculty of Engineering and Technology

πŸ“š References

  1. A. V. Aho, M. Lam, R. Sethi, and J. Ullman, Compilers: Principles, Techniques and Tools, 2nd Edition.
  2. J. Hopcroft, R. Motwani, and J. Ullman, Introduction to Automata Theory, Languages and Computation.
  3. K. Louden, Compiler Construction: Principles and Practice.
  4. M. Sipser, Introduction to the Theory of Computation.

🌟 Quick Start

# Clone the repository
git clone [Repo_link]
cd mini-compiler

# Run the demonstration
python main.py

# Compile an expression
python main.py "a+b*c"

About

Mini compiler: A complete implementation of a compiler for a simple arithmetic expression language, demonstrating lexical analysis, syntactic analysis, and formal language concepts.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages