Compilation / Playground

Compilation Playground

Three interactive labs. Each exposes a different slice of the compiler — run them on your own input and see every phase emit its artifact.

Choose a lab

Type your own lex, grammar, and source. Watch tokens → parse tree live.

Full-pipeline playground

Type your own lex rules, grammar, and source. Watch each compiler phase in sequence.

Load sample:
31 lines
18 lines
6 lines
·
Stage 1
Lexical Analysis — Tokens
Click Run
·
Stage 2
Syntax Analysis — Parse Tree (Earley)
·
Stage 3
Semantic Analysis — AST
·
Stage 4
IR — Three-address code
·
Stage 5
CFG — Control-Flow Graph
·
Stage 6
Optimisations — constant folding + DCE

Reference — how the rule files look

The defaults on the left show the exact syntax.

📄 Full MiniC lex file (flex-style)
%{
/* minic.l — lexer spec for our running example language */
#include "minic.tab.h"
%}

DIGIT   [0-9]
LETTER  [a-zA-Z_]

%%

"int"       { return INT; }
"while"     { return WHILE; }
"return"    { return RETURN; }
"if"        { return IF; }
"else"      { return ELSE; }

{LETTER}({LETTER}|{DIGIT})*   { yylval.s = strdup(yytext); return IDENT; }
{DIGIT}+                       { yylval.i = atoi(yytext); return NUM; }

"=="        { return EQ; }
"<"         { return LT; }
">"         { return GT; }
"="         { return ASSIGN; }
"+"         { return PLUS; }
"-"         { return MINUS; }
"*"         { return TIMES; }
"/"         { return DIV; }

"("         { return LPAREN; }
")"         { return RPAREN; }
"{"         { return LBRACE; }
"}"         { return RBRACE; }
";"         { return SEMI; }
","         { return COMMA; }

[ \t\n]+    { /* skip whitespace */ }
.           { fprintf(stderr, "unexpected char %c\n", *yytext); }

%%
📄 Full MiniC grammar file (yacc-style)
/* minic.y — grammar for our running example language */
%token INT WHILE RETURN IF ELSE
%token IDENT NUM
%token EQ LT GT ASSIGN PLUS MINUS TIMES DIV
%token LPAREN RPAREN LBRACE RBRACE SEMI COMMA
%left  EQ
%left  LT GT
%left  PLUS MINUS
%left  TIMES DIV

%%

program   : fn_decl                      ;
fn_decl   : type IDENT LPAREN params RPAREN block ;
type      : INT                          ;
params    : /* empty */                  | param_list ;
param_list: param                        | param_list COMMA param ;
param     : type IDENT                   ;
block     : LBRACE stmts RBRACE          ;
stmts     : /* empty */                  | stmts stmt ;
stmt      : decl SEMI                    | assign SEMI
          | while_stmt                   | if_stmt
          | return_stmt SEMI             ;
decl      : type IDENT ASSIGN expr       ;
assign    : IDENT ASSIGN expr            ;
while_stmt: WHILE LPAREN expr RPAREN block ;
if_stmt   : IF LPAREN expr RPAREN block
          | IF LPAREN expr RPAREN block ELSE block ;
return_stmt: RETURN expr                  ;
expr      : expr PLUS  expr              | expr MINUS expr
          | expr TIMES expr              | expr DIV   expr
          | expr LT expr                 | expr GT    expr
          | expr EQ expr                 | LPAREN expr RPAREN
          | IDENT                        | NUM
          ;

%%

Tip: the canonical factorial is available as the "MiniC · factorial" sample. Load it, tweak the source, and watch the tokens and parse tree update.