miniC to MIPS Compiler

May 9, 2026 · 3 min read
miniC source code translated into optimized MIPS assembly
projects

Description

A complete compiler from miniC, a small C-like language, to MIPS assembly, built for the Compilers course at the University of Murcia (2025/2026) in a team of two.

The compiler covers the four classic phases: lexical analysis (Flex), parsing (Bison), semantic analysis over a symbol table, and MIPS code generation. The generated assembly was validated by running it in the MARS 4.5 simulator.

Language Support

  • Declarations: variables and constants (constants require an initializer).
  • Expressions: +, -, *, /, unary minus, and the six relational operators (==, !=, <, >, <=, >=), which are non-associative.
  • Control flow: if, if-else, while, do-while and break (with correct handling of nested loops).
  • I/O: print (integers and string literals) and read.

Compiler Pipeline

  • Lexer (Flex): exclusive start conditions for multi-line comments and strings, longest-match ordering for keywords and two-character operators, identifier length limit, integer overflow check, and panic-mode recovery that reports one error per invalid sequence.
  • Parser (Bison): operator precedence and associativity declared explicitly, dangling else resolved with %precedence, and a grammar with no unresolved conflicts (110 states).
  • Error recovery: synchronization on ; and }, %destructor rules to free discarded symbols, and a reset of the temporary-register pool after every recovery, which fixed false “no registers available” errors in cascading-error programs.
  • Semantic analysis: program must be named main, no redeclarations, constants cannot be reassigned or read into, no use of undeclared identifiers, and break only inside loops. All errors are reported, not just the first.
  • Code generation: each main non-terminal carries a list of MIPS quadruples that is concatenated on every reduction, with a pool of ten temporary registers ($t0-$t9).

Optimizations

  • Constant folding with lazy materialization: expressions carry an attribute with a compile-time value and a flag. A constant is only turned into a li instruction if it is actually used, so 3 + 4 * 2 becomes a single li $t0, 11. Division by zero in a constant expression produces a compile-time warning.
  • Dead-code elimination: conditions known at compile time remove branches entirely (if (0), if (K), while (0), and if (3 > 5) after folding).
  • Peephole optimizer (separate module): six patterns, including add R, X, 0 to move, mul R, X, 1 to move, mul R, X, 0 to li R, 0, and multiplication by a power of two to sll. It tracks the last known li value per register across a basic block and stops at labels.
  • String literal deduplication in the .data section through the symbol table.

Example

Input:

void main() {
  var int x = 3 + 4 * 2;
  print(x, "\n");
}

Generated MIPS (the initialization collapses to one instruction instead of five):

li $t0, 11
sw $t0, _x
lw $t0, _x
move $a0, $t0
li $v0, 1
syscall

Testing

  • Eleven small single-purpose test programs: valid programs for each feature (spec example, folding, dead code, peephole patterns, relational operators, do-while, nested break, a full integration program) and invalid programs for lexical, syntactic and semantic errors.
  • A script checks the expected error counts per phase and, for valid programs, runs the generated assembly in MARS and checks the output.
  • One command (make test) builds the compiler and runs the whole suite.

Known Limitations

  • Constant folding does not propagate through declared constants (const int c = 5; var int x = c * 2; is not folded).
  • The peephole pass runs once instead of until a fixed point.
  • The ten-register pool has no spilling.
  • A few small dynamically allocated strings (labels and variable names) are not freed, because the provided list structure does not distinguish heap strings from literals.

Installation & Execution

  • Technical Requirements: gcc, flex, bison, make on Linux; Java to run MARS 4.5.
  • Build and test:
    make
    make test
    
  • Compile and run a program:
    ./minic program.mc > program.s
    java -jar tests/Mars4_5.jar nc program.s
    

Tools & Technologies

  • C
  • Flex
  • Bison
  • MIPS Assembly (MARS 4.5)
  • Make
  • Shell scripting
Guillermo F. Parra
Authors
Mathematics & Computer Science Student | Founder & President @ Club de Finanzas FIUM

Mathematics and Computer Engineering student with a focus on the intersection of rigorous theory and high-performance implementation. With a background marked by 23+ “Matrículas de Honor” and multiple Regional Olympiad awards, I thrive on bridging the gap between abstract mathematical models and efficient computational systems.

My core interests lie in Quantitative Finance, Stochastic Calculus, and Numerical Optimization. I am particularly passionate about transforming complex financial frameworks into high-performance algorithmic solutions. Currently, I balance my research in Quant Finance and Deep Learning with active leadership in university commissions.