Show description
Inside the Compiler | CSE 230
Inside the Compiler | CSE 230
⚙️ Inside the Compiler
CSE 230 - Section 2.1 Interactive Study Guide
Overview
Pipeline
Frontend
Middle
Backend
Tools
Interactive Demo
Quiz
🎯 What is a Compiler?
A compiler is a translator that converts human-readable code into machine instructions that your computer's hardware can execute directly.
Your Code (Python, C++, Java) → COMPILER → Machine Instructions (1s and 0s)
Why Do We Need Compilers?
High-level languages let programmers express complex ideas quickly and clearly.
But computers only understand machine code - sequences of numbers representing basic operations.
Machine code is nearly impossible for humans to read or write directly, so compilers bridge this gap.
🏗️ The Three Stages
Every compiler follows a similar structure, broken into three main stages:
Frontend
Syntax checking, tokenization, parsing
Middle
Analysis & optimization
Backend
Code generation
Click any stage to learn more
💡 Key Insight
Think of a compiler like a translator converting a novel from English to Japanese:
Frontend = Understanding the English (grammar, vocabulary, sentence structure)
Middle = Deciding the best way to express each idea in Japanese
Backend = Actually writing out the Japanese text
🔄 Complete Compilation Pipeline
Follow your code's journey from source to executable:
Source Codeint x = 5 + 3;
→
LexerTokenize
→
ParserBuild AST
↓
OptimizerImprove Code
↓
Code GeneratorCreate Instructions
→
ExecutableMachine Code
📊 Data Structures Along the Way
🏷️ Tokens
Smallest meaningful units of code
Created by the lexer. Examples: int, x, =, 5, +, 3, ;
Each token has a type (keyword, identifier, operator, etc.) and a value.
🌳 Abstract Syntax Tree
Hierarchical program structure
A tree showing how code elements relate.…
Inside the Compiler | CSE 230
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Inside the Compiler | CSE 230</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--bg-primary: #0d1117;
--bg-secondary: #161b22;
--bg-tertiary: #21262d;
--border-color: #30363d;
--text-primary: #e6edf3;
--text-secondary: #8b949e;
--text-muted: #6e7681;
--accent-blue: #58a6ff;
--accent-green: #3fb950;
--accent-purple: #a371f7;
--accent-orange: #d29922;
--accent-red: #f85149;
--accent-cyan: #39c5cf;
--glow-blue: rgba(88, 166, 255, 0.15);
--glow-green: rgba(63, 185, 80, 0.15);
--glow-purple: rgba(163, 113, 247, 0.15);
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
background: var(--bg-primary);
color: var(--text-primary);
line-height: 1.6;
min-height: 100vh;
}
/* Header */
header {
background: linear-gradient(135deg, var(--bg-secondary) 0%, var(--bg-primary) 100%);
border-bottom: 1px solid var(--border-color);
padding: 2rem;
text-align: center;
position: sticky;
top: 0;
z-index: 100;
}
header h1 {
font-size: 2.5rem;
background: linear-gradient(90deg, var(--accent-blue), var(--accent-purple), var(--accent-cyan));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin-bottom: 0.5rem;
}
header p {
color: var(--text-secondary);
font-size: 1.1rem;
}
/* Navigation */
nav {
display: flex;
justify-content: center;
gap: 0.5rem;
padding: 1rem;
background: var(--bg-secondary);
border-bottom: 1px solid var(--border-color);
flex-wrap: wrap;
}
nav button {
background: var(--bg-tertiary);
border: 1px solid var(--border-color);
color: var(--text-secondary);
padding: 0.6rem 1.2rem;
border-radius: 6px;
cursor: pointer;
transition: all 0.2s ease;
font-size: 0.9rem;
}
nav button:hover, nav button.active {
background: var(--accent-blue);
color: var(--bg-primary);
border-color: var(--accent-blue);
transform: translateY(-2px);
}
/* Main Content */
main {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
section {
display: none;
animation: fadeIn 0.4s ease;
}
section.active {
display: block;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
/* Cards */
.card {
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 1.5rem;
margin-bottom: 1.5rem;
transition: all 0.3s ease;
}
.card:hover {
border-color: var(--accent-blue);
box-shadow: 0 0 20px var(--glow-blue);
}
.card h2 {
color: var(--accent-blue);
margin-bottom: 1rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.card h3 {
color: var(--accent-purple);
margin: 1rem 0 0.5rem;
}
/* Pipeline Visualization */
.pipeline {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
padding: 2rem;
overflow-x: auto;
}
.stage {
flex: 1;
min-width: 200px;
background: var(--bg-tertiary);
border: 2px solid var(--border-color);
border-radius: 12px;
padding: 1.5rem;
text-align: center;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
}
.stage::after {
content: '→';
position: absolute;
right: -1.5rem;
top: 50%;
transform: translateY(-50%);
color: var(--text-muted);
font-size: 1.5rem;
}
.stage:last-child::after {
display: none;
}
.stage:hover {
transform: translateY(-5px);
}
.stage.frontend {
border-color: var(--accent-green);
}
.stage.frontend:hover {
box-shadow: 0 0 25px var(--glow-green);
background: rgba(63, 185, 80, 0.1);
}
.stage.middle {
border-color: var(--accent-orange);
}
.stage.middle:hover {
box-shadow: 0 0 25px rgba(210, 153, 34, 0.15);
background: rgba(210, 153, 34, 0.1);
}
.stage.backend {
border-color: var(--accent-purple);
}
.stage.backend:hover {
box-shadow: 0 0 25px var(--glow-purple);
background: rgba(163, 113, 247, 0.1);
}
.stage h4 {
font-size: 1.2rem;
margin-bottom: 0.5rem;
}
.stage.frontend h4 { color: var(--accent-green); }
.stage.middle h4 { color: var(--accent-orange); }
.stage.backend h4 { color: var(--accent-purple); }
.stage p {
color: var(--text-secondary);
font-size: 0.85rem;
}
/* Stage Detail Panel */
.stage-detail {
background: var(--bg-tertiary);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 2rem;
margin-top: 1rem;
display: none;
animation: slideDown 0.3s ease;
}
.stage-detail.active {
display: block;
}
@keyframes slideDown {
from { opacity: 0; max-height: 0; }
to { opacity: 1; max-height: 1000px; }
}
/* Interactive Demo */
.demo-container {
background: var(--bg-tertiary);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 1.5rem;
margin: 1.5rem 0;
}
.code-input {
width: 100%;
background: var(--bg-primary);
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 1rem;
color: var(--text-primary);
font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
font-size: 0.95rem;
resize: vertical;
min-height: 100px;
}
.code-input:focus {
outline: none;
border-color: var(--accent-blue);
}
.btn {
background: var(--accent-blue);
color: var(--bg-primary);
border: none;
padding: 0.8rem 1.5rem;
border-radius: 8px;
cursor: pointer;
font-size: 0.95rem;
font-weight: 600;
transition: all 0.2s ease;
margin-top: 1rem;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 4px 15px var(--glow-blue);
}
.output-panel {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1rem;
margin-top: 1.5rem;
}
.output-box {
background: var(--bg-primary);
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 1rem;
}
.output-box h5 {
color: var(--accent-cyan);
margin-bottom: 0.75rem;
font-size: 0.9rem;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.output-box pre {
font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
font-size: 0.85rem;
color: var(--text-secondary);
white-space: pre-wrap;
word-break: break-all;
}
.token {
display: inline-block;
padding: 0.2rem 0.5rem;
margin: 0.2rem;
border-radius: 4px;
font-family: monospace;
font-size: 0.85rem;
}
.token-keyword { background: rgba(255, 123, 114, 0.2); color: #ff7b72; }
.token-identifier { background: rgba(88, 166, 255, 0.2); color: #58a6ff; }
.token-number { background: rgba(163, 113, 247, 0.2); color: #a371f7; }
.token-operator { background: rgba(210, 153, 34, 0.2); color: #d29922; }
.token-punctuation { background: rgba(110, 118, 129, 0.2); color: #8b949e; }
.token-string { background: rgba(63, 185, 80, 0.2); color: #3fb950; }
/* Concept Cards */
.concept-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
margin-top: 1.5rem;
}
.concept-card {
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 1.5rem;
transition: all 0.3s ease;
cursor: pointer;
}
.concept-card:hover {
transform: translateY(-3px);
border-color: var(--accent-cyan);
box-shadow: 0 0 20px rgba(57, 197, 207, 0.15);
}
.concept-card h4 {
color: var(--accent-cyan);
margin-bottom: 0.75rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.concept-card p {
color: var(--text-secondary);
font-size: 0.95rem;
}
.concept-card .expand-content {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease;
}
.concept-card.expanded .expand-content {
max-height: 500px;
margin-top: 1rem;
padding-top: 1rem;
border-top: 1px solid var(--border-color);
}
/* Quiz Section */
.quiz-container {
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 2rem;
}
.question {
margin-bottom: 2rem;
padding-bottom: 1.5rem;
border-bottom: 1px solid var(--border-color);
}
.question:last-child {
border-bottom: none;
margin-bottom: 0;
}
.question h4 {
color: var(--text-primary);
margin-bottom: 1rem;
font-size: 1.1rem;
}
.question-number {
color: var(--accent-blue);
font-weight: 600;
}
.options {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.option {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.75rem 1rem;
background: var(--bg-tertiary);
border: 1px solid var(--border-color);
border-radius: 8px;
cursor: pointer;
transition: all 0.2s ease;
}
.option:hover {
border-color: var(--accent-blue);
background: rgba(88, 166, 255, 0.1);
}
.option input {
display: none;
}
.option .radio {
width: 20px;
height: 20px;
border: 2px solid var(--border-color);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s ease;
}
.option.selected .radio {
border-color: var(--accent-blue);
background: var(--accent-blue);
}
.option.correct {
border-color: var(--accent-green);
background: rgba(63, 185, 80, 0.15);
}
.option.incorrect {
border-color: var(--accent-red);
background: rgba(248, 81, 73, 0.15);
}
.feedback {
margin-top: 0.75rem;
padding: 0.75rem;
border-radius: 6px;
font-size: 0.9rem;
display: none;
}
.feedback.show {
display: block;
}
.feedback.correct {
background: rgba(63, 185, 80, 0.15);
color: var(--accent-green);
border: 1px solid var(--accent-green);
}
.feedback.incorrect {
background: rgba(248, 81, 73, 0.15);
color: var(--accent-red);
border: 1px solid var(--accent-red);
}
.score-display {
text-align: center;
padding: 2rem;
background: var(--bg-tertiary);
border-radius: 12px;
margin-top: 1.5rem;
display: none;
}
.score-display.show {
display: block;
}
.score-display h3 {
font-size: 2rem;
margin-bottom: 0.5rem;
}
/* Flow Diagram */
.flow-container {
padding: 2rem;
overflow-x: auto;
}
.flow-diagram {
display: flex;
flex-direction: column;
gap: 1rem;
min-width: 600px;
}
.flow-row {
display: flex;
align-items: center;
gap: 1rem;
}
.flow-box {
padding: 1rem 1.5rem;
border-radius: 8px;
font-weight: 500;
text-align: center;
min-width: 150px;
}
.flow-arrow {
color: var(--text-muted);
font-size: 1.5rem;
}
.flow-source { background: rgba(88, 166, 255, 0.2); border: 1px solid var(--accent-blue); color: var(--accent-blue); }
.flow-lexer { background: rgba(63, 185, 80, 0.2); border: 1px solid var(--accent-green); color: var(--accent-green); }
.flow-parser { background: rgba(63, 185, 80, 0.2); border: 1px solid var(--accent-green); color: var(--accent-green); }
.flow-optimizer { background: rgba(210, 153, 34, 0.2); border: 1px solid var(--accent-orange); color: var(--accent-orange); }
.flow-codegen { background: rgba(163, 113, 247, 0.2); border: 1px solid var(--accent-purple); color: var(--accent-purple); }
.flow-output { background: rgba(57, 197, 207, 0.2); border: 1px solid var(--accent-cyan); color: var(--accent-cyan); }
/* Symbol Table Demo */
.symbol-table {
width: 100%;
border-collapse: collapse;
margin-top: 1rem;
}
.symbol-table th,
.symbol-table td {
padding: 0.75rem 1rem;
text-align: left;
border: 1px solid var(--border-color);
}
.symbol-table th {
background: var(--bg-tertiary);
color: var(--accent-cyan);
font-weight: 600;
}
.symbol-table tr:hover {
background: rgba(88, 166, 255, 0.05);
}
/* Tooltip */
.tooltip {
position: relative;
display: inline-block;
border-bottom: 1px dashed var(--accent-blue);
cursor: help;
}
.tooltip .tooltip-text {
visibility: hidden;
width: 250px;
background: var(--bg-tertiary);
color: var(--text-primary);
text-align: left;
border-radius: 8px;
padding: 0.75rem;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
transform: translateX(-50%);
opacity: 0;
transition: opacity 0.3s;
border: 1px solid var(--border-color);
font-size: 0.85rem;
line-height: 1.4;
}
.tooltip:hover .tooltip-text {
visibility: visible;
opacity: 1;
}
/* Highlight text */
.highlight {
color: var(--accent-blue);
font-weight: 500;
}
.highlight-green { color: var(--accent-green); }
.highlight-orange { color: var(--accent-orange); }
.highlight-purple { color: var(--accent-purple); }
/* Responsive */
@media (max-width: 768px) {
header h1 {
font-size: 1.8rem;
}
.pipeline {
flex-direction: column;
}
.stage::after {
content: '↓';
right: 50%;
top: auto;
bottom: -1.5rem;
transform: translateX(50%);
}
nav {
gap: 0.25rem;
}
nav button {
padding: 0.5rem 0.8rem;
font-size: 0.8rem;
}
}
/* Animations for interactive elements */
.pulse {
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.6; }
}
/* Progress tracker */
.progress-bar {
background: var(--bg-tertiary);
border-radius: 20px;
height: 8px;
margin: 1rem 0;
overflow: hidden;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, var(--accent-green), var(--accent-blue));
border-radius: 20px;
transition: width 0.5s ease;
}
/* Mini diagrams */
.mini-diagram {
background: var(--bg-primary);
border-radius: 8px;
padding: 1rem;
margin: 1rem 0;
font-family: monospace;
font-size: 0.9rem;
line-height: 1.8;
color: var(--text-secondary);
overflow-x: auto;
}
/* AST visualization */
.ast-node {
display: inline-block;
padding: 0.3rem 0.6rem;
margin: 0.2rem;
border-radius: 4px;
font-size: 0.85rem;
font-family: monospace;
}
.ast-root { background: rgba(248, 81, 73, 0.2); color: #f85149; }
.ast-op { background: rgba(210, 153, 34, 0.2); color: #d29922; }
.ast-var { background: rgba(88, 166, 255, 0.2); color: #58a6ff; }
.ast-num { background: rgba(163, 113, 247, 0.2); color: #a371f7; }
</style>
</head>
<body>
<header>
<h1>⚙️ Inside the Compiler</h1>
<p>CSE 230 - Section 2.1 Interactive Study Guide</p>
</header>
<nav>
<button class="active" onclick="showSection('overview')">Overview</button>
<button onclick="showSection('pipeline')">Pipeline</button>
<button onclick="showSection('frontend')">Frontend</button>
<button onclick="showSection('middle')">Middle</button>
<button onclick="showSection('backend')">Backend</button>
<button onclick="showSection('tools')">Tools</button>
<button onclick="showSection('demo')">Interactive Demo</button>
<button onclick="showSection('quiz')">Quiz</button>
</nav>
<main>
<!-- Overview Section -->
<section id="overview" class="active">
<div class="card">
<h2>🎯 What is a Compiler?</h2>
<p>A compiler is a <span class="highlight">translator</span> that converts human-readable code into machine instructions that your computer's hardware can execute directly.</p>
<div class="mini-diagram">
Your Code (Python, C++, Java) → COMPILER → Machine Instructions (1s and 0s)
</div>
<h3>Why Do We Need Compilers?</h3>
<p style="margin-top: 0.5rem; color: var(--text-secondary);">
<span class="highlight-green">High-level languages</span> let programmers express complex ideas quickly and clearly.
But computers only understand <span class="highlight-purple">machine code</span> - sequences of numbers representing basic operations.
Machine code is nearly impossible for humans to read or write directly, so compilers bridge this gap.
</p>
</div>
<div class="card">
<h2>🏗️ The Three Stages</h2>
<p>Every compiler follows a similar structure, broken into three main stages:</p>
<div class="pipeline">
<div class="stage frontend" onclick="showSection('frontend')">
<h4>Frontend</h4>
<p>Syntax checking, tokenization, parsing</p>
</div>
<div class="stage middle" onclick="showSection('middle')">
<h4>Middle</h4>
<p>Analysis & optimization</p>
</div>
<div class="stage backend" onclick="showSection('backend')">
<h4>Backend</h4>
<p>Code generation</p>
</div>
</div>
<p style="text-align: center; color: var(--text-muted); font-size: 0.9rem;">Click any stage to learn more</p>
</div>
<div class="card">
<h2>💡 Key Insight</h2>
<p>Think of a compiler like a translator converting a novel from English to Japanese:</p>
<ul style="margin-top: 1rem; margin-left: 1.5rem; color: var(--text-secondary);">
<li style="margin-bottom: 0.5rem;"><span class="highlight-green">Frontend</span> = Understanding the English (grammar, vocabulary, sentence structure)</li>
<li style="margin-bottom: 0.5rem;"><span class="highlight-orange">Middle</span> = Deciding the best way to express each idea in Japanese</li>
<li><span class="highlight-purple">Backend</span> = Actually writing out the Japanese text</li>
</ul>
</div>
</section>
<!-- Pipeline Section -->
<section id="pipeline">
<div class="card">
<h2>🔄 Complete Compilation Pipeline</h2>
<p>Follow your code's journey from source to executable:</p>
<div class="flow-container">
<div class="flow-diagram">
<div class="flow-row">
<div class="flow-box flow-source">Source Code<br><small>int x = 5 + 3;</small></div>
<span class="flow-arrow">→</span>
<div class="flow-box flow-lexer">Lexer<br><small>Tokenize</small></div>
<span class="flow-arrow">→</span>
<div class="flow-box flow-parser">Parser<br><small>Build AST</small></div>
</div>
<div style="text-align: center; padding: 0.5rem;">
<span class="flow-arrow">↓</span>
</div>
<div class="flow-row" style="justify-content: center;">
<div class="flow-box flow-optimizer">Optimizer<br><small>Improve Code</small></div>
</div>
<div style="text-align: center; padding: 0.5rem;">
<span class="flow-arrow">↓</span>
</div>
<div class="flow-row">
<div class="flow-box flow-codegen">Code Generator<br><small>Create Instructions</small></div>
<span class="flow-arrow">→</span>
<div class="flow-box flow-output">Executable<br><small>Machine Code</small></div>
</div>
</div>
</div>
</div>
<div class="card">
<h2>📊 Data Structures Along the Way</h2>
<div class="concept-grid">
<div class="concept-card" onclick="toggleExpand(this)">
<h4>🏷️ Tokens</h4>
<p>Smallest meaningful units of code</p>
<div class="expand-content">
<p>Created by the lexer. Examples: <code>int</code>, <code>x</code>, <code>=</code>, <code>5</code>, <code>+</code>, <code>3</code>, <code>;</code></p>
<p style="margin-top: 0.5rem;">Each token has a type (keyword, identifier, operator, etc.) and a value.</p>
</div>
</div>
<div class="concept-card" onclick="toggleExpand(this)">
<h4>🌳 Abstract Syntax Tree</h4>
<p>Hierarchical program structure</p>
<div class="expand-content">
<p>A tree showing how code elements relate. For <code>x = 5 + 3</code>:</p>
<div class="mini-diagram">
Assignment (=)
├── Variable: x
└── Add (+)
├── Number: 5
└── Number: 3
</div>
</div>
</div>
<div class="concept-card" onclick="toggleExpand(this)">
<h4>📋 Symbol Table</h4>
<p>Registry of all identifiers</p>
<div class="expand-content">
<p>Tracks every variable, function, and class name along with their types, scopes, and memory locations.</p>
<p style="margin-top: 0.5rem;">Allows the compiler to know "what is x?" at any point in the code.</p>
</div>
</div>
<div class="concept-card" onclick="toggleExpand(this)">
<h4>🔢 Intermediate Representation</h4>
<p>Platform-independent code form</p>
<div class="expand-content">
<p>A simplified version of your code that's easier to optimize, but not yet specific to any CPU architecture.</p>
<p style="margin-top: 0.5rem;">Like a universal language between your code and machine code.</p>
</div>
</div>
</div>
</div>
</section>
<!-- Frontend Section -->
<section id="frontend">
<div class="card" style="border-left: 4px solid var(--accent-green);">
<h2 style="color: var(--accent-green);">📥 Compiler Frontend</h2>
<p>The frontend's job is to <span class="highlight-green">understand</span> your code and check it for errors.</p>
</div>
<div class="card">
<h2>🔤 Lexical Analyzer (Lexer)</h2>
<p>The lexer reads your raw source code character by character and groups them into <span class="highlight">tokens</span>.</p>
<h3>What are Tokens?</h3>
<p style="margin-top: 0.5rem; color: var(--text-secondary);">
Tokens are the smallest meaningful units in a programming language - like words in a sentence.
</p>
<div class="demo-container">
<p style="margin-bottom: 1rem; color: var(--text-secondary);">Example: How the lexer sees <code>int count = 42;</code></p>
<div>
<span class="token token-keyword">KEYWORD: int</span>
<span class="token token-identifier">IDENTIFIER: count</span>
<span class="token token-operator">OPERATOR: =</span>
<span class="token token-number">NUMBER: 42</span>
<span class="token token-punctuation">SEMICOLON: ;</span>
</div>
</div>
<h3>Token Types</h3>
<ul style="margin-top: 0.75rem; margin-left: 1.5rem; color: var(--text-secondary);">
<li><span class="highlight">Keywords</span> - Reserved words like <code>if</code>, <code>while</code>, <code>return</code></li>
<li><span class="highlight">Identifiers</span> - Names you create: variables, functions, classes</li>
<li><span class="highlight">Literals</span> - Values like numbers (<code>42</code>) or strings (<code>"hello"</code>)</li>
<li><span class="highlight">Operators</span> - Symbols like <code>+</code>, <code>-</code>, <code>=</code>, <code>==</code></li>
<li><span class="highlight">Punctuation</span> - Structural symbols like <code>;</code>, <code>{</code>, <code>}</code></li>
</ul>
</div>
<div class="card">
<h2>📐 Parser</h2>
<p>The parser takes tokens and checks if they follow the <span class="highlight">grammar rules</span> of the language.</p>
<h3>Grammar Rules Examples</h3>
<div class="mini-diagram">
Assignment Rule: IDENTIFIER = EXPRESSION ;
If Statement: if ( CONDITION ) { STATEMENTS }
Function Call: IDENTIFIER ( ARGUMENTS )
</div>
<h3>What the Parser Catches</h3>
<ul style="margin-top: 0.75rem; margin-left: 1.5rem; color: var(--text-secondary);">
<li>Missing semicolons: <code style="color: var(--accent-red);">int x = 5</code> ← where's the <code>;</code>?</li>
<li>Unbalanced brackets: <code style="color: var(--accent-red);">if (x > 5 { }</code> ← missing <code>)</code></li>
<li>Invalid assignments: <code style="color: var(--accent-red);">5 = x;</code> ← can't assign to a number!</li>
</ul>
<h3>The Output: Abstract Syntax Tree (AST)</h3>
<p style="margin-top: 0.5rem; color: var(--text-secondary);">
If the code is valid, the parser builds a tree structure that represents the program's logic.
</p>
<div class="demo-container">
<p style="margin-bottom: 0.75rem;">AST for: <code>result = (a + b) * 2;</code></p>
<div class="mini-diagram">
<span class="ast-node ast-root">Assignment</span><br>
├── <span class="ast-node ast-var">result</span><br>
└── <span class="ast-node ast-op">Multiply (*)</span><br>
├── <span class="ast-node ast-op">Add (+)</span><br>
│ ├── <span class="ast-node ast-var">a</span><br>
│ └── <span class="ast-node ast-var">b</span><br>
└── <span class="ast-node ast-num">2</span>
</div>
</div>
</div>
<div class="card">
<h2>📋 Symbol Table</h2>
<p>While parsing, the compiler builds a <span class="highlight">symbol table</span> - a database of all identifiers in your program.</p>
<div class="demo-container">
<p style="margin-bottom: 1rem; color: var(--text-secondary);">For this code:</p>
<pre style="background: var(--bg-primary); padding: 1rem; border-radius: 6px; margin-bottom: 1rem;">int globalCount = 0;
void calculateSum(int a, int b) {
int result = a + b;
globalCount++;
}</pre>
<table class="symbol-table">
<tr>
<th>Name</th>
<th>Type</th>
<th>Scope</th>
<th>Details</th>
</tr>
<tr>
<td>globalCount</td>
<td>int</td>
<td>global</td>
<td>initialized to 0</td>
</tr>
<tr>
<td>calculateSum</td>
<td>function</td>
<td>global</td>
<td>returns void, 2 params</td>
</tr>
<tr>
<td>a</td>
<td>int</td>
<td>calculateSum</td>
<td>parameter</td>
</tr>
<tr>
<td>b</td>
<td>int</td>
<td>calculateSum</td>
<td>parameter</td>
</tr>
<tr>
<td>result</td>
<td>int</td>
<td>calculateSum</td>
<td>local variable</td>
</tr>
</table>
</div>
<h3>Why Symbol Tables Matter</h3>
<ul style="margin-top: 0.75rem; margin-left: 1.5rem; color: var(--text-secondary);">
<li><span class="highlight">Type checking</span> - Is <code>x + "hello"</code> valid?</li>
<li><span class="highlight">Scope resolution</span> - Which <code>x</code> are we referring to?</li>
<li><span class="highlight">Memory allocation</span> - Where should each variable live?</li>
</ul>
</div>
</section>
<!-- Middle Section -->
<section id="middle">
<div class="card" style="border-left: 4px solid var(--accent-orange);">
<h2 style="color: var(--accent-orange);">⚡ Middle Stage (Optimizer)</h2>
<p>The middle stage makes your code <span class="highlight-orange">faster and smaller</span> without changing what it does.</p>
<p style="margin-top: 0.5rem; color: var(--text-muted);">This stage is optional but almost always used in production compilers.</p>
</div>
<div class="card">
<h2>🎯 Optimization Goals</h2>
<div class="concept-grid">
<div class="concept-card" onclick="toggleExpand(this)">
<h4>🏃 Faster Execution</h4>
<p>Reduce CPU cycles needed</p>
<div class="expand-content">
<p>Rearrange operations to take advantage of CPU features like pipelining, caching, and parallel execution units.</p>
</div>
</div>
<div class="concept-card" onclick="toggleExpand(this)">
<h4>📦 Smaller Code</h4>
<p>Reduce executable size</p>
<div class="expand-content">
<p>Remove redundant code, combine similar operations, and eliminate unused functions to shrink the final binary.</p>
</div>
</div>
<div class="concept-card" onclick="toggleExpand(this)">
<h4>💾 Less Memory</h4>
<p>Reduce RAM usage</p>
<div class="expand-content">
<p>Reuse memory locations, eliminate unnecessary temporary variables, and optimize data layout.</p>
</div>
</div>
</div>
</div>
<div class="card">
<h2>🔧 Common Optimizations</h2>
<h3>Dead Code Elimination</h3>
<p style="color: var(--text-secondary);">Remove code that never runs or variables that are never used.</p>
<div class="demo-container">
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;">
<div>
<h5 style="color: var(--accent-red); margin-bottom: 0.5rem;">Before</h5>
<pre style="font-size: 0.9rem;">int x = 5;
int y = 10; // never used!
int z = x * 2;
return z;</pre>
</div>
<div>
<h5 style="color: var(--accent-green); margin-bottom: 0.5rem;">After</h5>
<pre style="font-size: 0.9rem;">int x = 5;
int z = x * 2;
return z;</pre>
</div>
</div>
</div>
<h3 style="margin-top: 1.5rem;">Constant Folding</h3>
<p style="color: var(--text-secondary);">Calculate constant expressions at compile time instead of runtime.</p>
<div class="demo-container">
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;">
<div>
<h5 style="color: var(--accent-red); margin-bottom: 0.5rem;">Before</h5>
<pre style="font-size: 0.9rem;">int seconds = 60 * 60 * 24;
int area = 3.14159 * 10 * 10;</pre>
</div>
<div>
<h5 style="color: var(--accent-green); margin-bottom: 0.5rem;">After</h5>
<pre style="font-size: 0.9rem;">int seconds = 86400;
int area = 314.159;</pre>
</div>
</div>
</div>
<h3 style="margin-top: 1.5rem;">Loop Optimization</h3>
<p style="color: var(--text-secondary);">Move calculations outside loops when possible.</p>
<div class="demo-container">
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;">
<div>
<h5 style="color: var(--accent-red); margin-bottom: 0.5rem;">Before</h5>
<pre style="font-size: 0.9rem;">for (i = 0; i < n; i++) {
x = y * z; // same every iteration!
arr[i] = x + i;
}</pre>
</div>
<div>
<h5 style="color: var(--accent-green); margin-bottom: 0.5rem;">After</h5>
<pre style="font-size: 0.9rem;">x = y * z; // moved outside
for (i = 0; i < n; i++) {
arr[i] = x + i;
}</pre>
</div>
</div>
</div>
<h3 style="margin-top: 1.5rem;">Strength Reduction</h3>
<p style="color: var(--text-secondary);">Replace expensive operations with cheaper equivalents.</p>
<div class="demo-container">
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;">
<div>
<h5 style="color: var(--accent-red); margin-bottom: 0.5rem;">Before</h5>
<pre style="font-size: 0.9rem;">x = y * 2;
z = w / 4;
p = q * 8;</pre>
</div>
<div>
<h5 style="color: var(--accent-green); margin-bottom: 0.5rem;">After (using bit shifts)</h5>
<pre style="font-size: 0.9rem;">x = y << 1; // shift left = *2
z = w >> 2; // shift right = /4
p = q << 3; // shift left 3 = *8</pre>
</div>
</div>
</div>
</div>
</section>
<!-- Backend Section -->
<section id="backend">
<div class="card" style="border-left: 4px solid var(--accent-purple);">
<h2 style="color: var(--accent-purple);">📤 Compiler Backend</h2>
<p>The backend transforms the optimized intermediate code into <span class="highlight-purple">actual machine instructions</span> for a specific CPU.</p>
</div>
<div class="card">
<h2>🎯 Backend Responsibilities</h2>
<div class="concept-grid">
<div class="concept-card" onclick="toggleExpand(this)">
<h4>📍 Memory Layout</h4>
<p>Organize data in RAM</p>
<div class="expand-content">
<p>Decide where each variable lives - in registers (fast), on the stack (function-local), or in the heap (dynamic).</p>
<div class="mini-diagram">
Memory Layout:
┌─────────────┐ High Address
│ Stack │ ← Local variables, function calls
├─────────────┤
│ ↓ │
│ ↑ │
├─────────────┤
│ Heap │ ← Dynamic allocations (malloc/new)
├─────────────┤
│ Data │ ← Global/static variables
├─────────────┤
│ Code │ ← Your program instructions
└─────────────┘ Low Address
</div>
</div>
</div>
<div class="concept-card" onclick="toggleExpand(this)">
<h4>⚙️ Instruction Selection</h4>
<p>Choose CPU operations</p>
<div class="expand-content">
<p>Match each operation in your code to specific machine instructions available on the target CPU (x86, ARM, etc.).</p>
<p style="margin-top: 0.5rem;">Different CPUs have different instruction sets!</p>
</div>
</div>
<div class="concept-card" onclick="toggleExpand(this)">
<h4>📝 Register Allocation</h4>
<p>Assign CPU registers</p>
<div class="expand-content">
<p>Registers are the fastest storage on a CPU, but there are only a few (8-32 typically). The compiler decides which variables get registers vs. memory.</p>
</div>
</div>
</div>
</div>
<div class="card">
<h2>🔧 Code Generation Example</h2>
<p>See how high-level code becomes machine instructions:</p>
<div class="demo-container">
<h5 style="color: var(--accent-blue); margin-bottom: 0.75rem;">C Code</h5>
<pre style="background: var(--bg-primary); padding: 1rem; border-radius: 6px;">int sum = a + b;</pre>
</div>
<div class="demo-container" style="margin-top: 0;">
<h5 style="color: var(--accent-purple); margin-bottom: 0.75rem;">x86 Assembly (simplified)</h5>
<pre style="background: var(--bg-primary); padding: 1rem; border-radius: 6px; font-size: 0.9rem;">MOV EAX, [a] ; Load value of 'a' into register EAX
ADD EAX, [b] ; Add value of 'b' to EAX
MOV [sum], EAX ; Store result in memory location 'sum'</pre>
</div>
<h3 style="margin-top: 1.5rem;">Instruction Templates</h3>
<p style="color: var(--text-secondary);">The backend uses templates for common patterns:</p>
<div class="mini-diagram">
IF Statement Template:
CMP condition ; Compare
JZ else_label ; Jump if zero (false)
[if-body code]
JMP end_label
else_label:
[else-body code]
end_label:
WHILE Loop Template:
loop_start:
CMP condition
JZ loop_end ; Exit if false
[loop-body code]
JMP loop_start ; Repeat
loop_end:
</div>
</div>
</section>
<!-- Tools Section -->
<section id="tools">
<div class="card">
<h2>🛠️ Additional Compiler Tools</h2>
<p>Compilers work with other tools to create final executables.</p>
</div>
<div class="card">
<h2>🔗 Linkers</h2>
<p>Linkers <span class="highlight">combine</span> separately compiled pieces into a single executable.</p>
<h3>What Gets Linked?</h3>
<ul style="margin: 1rem 0 1rem 1.5rem; color: var(--text-secondary);">
<li><span class="highlight">Your compiled code</span> - The .o or .obj files from your source</li>
<li><span class="highlight">Standard libraries</span> - printf, malloc, math functions</li>
<li><span class="highlight">Third-party libraries</span> - Any external code you use</li>
</ul>
<div class="demo-container">
<p style="margin-bottom: 1rem;">When you write <code>printf("Hello")</code>, you don't include the actual printf code:</p>
<div class="mini-diagram">
Your Code: Standard Library:
┌──────────────┐ ┌──────────────┐
│ main.o │ │ libc.a │
│ │ │ │
│ call printf ─┼───────────┼→ printf code │
│ │ LINKER │ │
└──────────────┘ fills └──────────────┘
this
gap!
↓
Final Executable:
┌──────────────┐
│ main code │
│ printf code │ ← copied or referenced
└──────────────┘
</div>
</div>
<h3>Static vs Dynamic Linking</h3>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-top: 1rem;">
<div class="demo-container" style="margin: 0;">
<h5 style="color: var(--accent-green);">Static Linking</h5>
<p style="font-size: 0.9rem; color: var(--text-secondary);">Library code is copied INTO your executable.</p>
<p style="font-size: 0.85rem; margin-top: 0.5rem;">✅ Self-contained, ❌ Larger file</p>
</div>
<div class="demo-container" style="margin: 0;">
<h5 style="color: var(--accent-blue);">Dynamic Linking</h5>
<p style="font-size: 0.9rem; color: var(--text-secondary);">Library code is loaded at runtime (.dll, .so).</p>
<p style="font-size: 0.85rem; margin-top: 0.5rem;">✅ Smaller file, ❌ Needs library installed</p>
</div>
</div>
</div>
<div class="card">
<h2>📝 Assemblers</h2>
<p>Assemblers translate <span class="highlight">assembly language</span> into machine code.</p>
<h3>Assembly vs Machine Code</h3>
<div class="demo-container">
<div class="mini-diagram">
Assembly (Human Readable): Machine Code (CPU Reads):
MOV EAX, 5 → B8 05 00 00 00
ADD EAX, 3 → 83 C0 03
</div>
</div>
<h3>What Assemblers Do</h3>
<ul style="margin: 1rem 0 0 1.5rem; color: var(--text-secondary);">
<li><span class="highlight">Translate mnemonics</span> - MOV, ADD, JMP → numeric opcodes</li>
<li><span class="highlight">Resolve labels</span> - Convert names like <code>loop_start</code> to addresses</li>
<li><span class="highlight">Manage symbol table</span> - Track function/variable locations</li>
<li><span class="highlight">Handle directives</span> - .data, .text, memory alignment</li>
</ul>
<p style="margin-top: 1rem; padding: 1rem; background: var(--bg-tertiary); border-radius: 8px; color: var(--text-secondary);">
💡 Assembly is much simpler to translate than high-level languages because there's almost a 1:1 mapping between assembly instructions and machine code.
</p>
</div>
</section>
<!-- Interactive Demo Section -->
<section id="demo">
<div class="card">
<h2>🎮 Interactive Lexer Demo</h2>
<p>Enter some code and watch it get tokenized!</p>
<div class="demo-container">
<textarea id="codeInput" class="code-input" placeholder="Enter code here, e.g.:
int count = 42;
float pi = 3.14;
if (count > 10) {
return count * 2;
}">int count = 42;
if (count > 10) {
return count * 2;
}</textarea>
<button class="btn" onclick="tokenizeCode()">⚡ Tokenize</button>
<div class="output-panel">
<div class="output-box">
<h5>Tokens</h5>
<div id="tokenOutput"></div>
</div>
<div class="output-box">
<h5>Symbol Table</h5>
<div id="symbolOutput"></div>
</div>
</div>
</div>
</div>
<div class="card">
<h2>🌳 AST Builder</h2>
<p>Enter a simple expression to see its syntax tree:</p>
<div class="demo-container">
<input type="text" id="exprInput" class="code-input" style="min-height: auto; padding: 0.75rem;" placeholder="e.g., x = (a + b) * 2" value="result = (a + b) * 2">
<button class="btn" onclick="buildAST()">🌳 Build AST</button>
<div id="astOutput" class="output-box" style="margin-top: 1rem;">
<h5>Abstract Syntax Tree</h5>
<pre id="astTree"></pre>
</div>
</div>
</div>
</section>
<!-- Quiz Section -->
<section id="quiz">
<div class="card">
<h2>📝 Test Your Knowledge</h2>
<p>See how well you understand compiler internals!</p>
<div class="progress-bar">
<div class="progress-fill" id="quizProgress" style="width: 0%"></div>
</div>
</div>
<div class="quiz-container">
<div class="question" data-correct="2">
<h4><span class="question-number">Q1:</span> What does a lexer produce?</h4>
<div class="options">
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q1" value="0">
<span class="radio"></span>
<span>Machine code instructions</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q1" value="1">
<span class="radio"></span>
<span>An abstract syntax tree</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q1" value="2">
<span class="radio"></span>
<span>Tokens (language elements)</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q1" value="3">
<span class="radio"></span>
<span>Optimized intermediate code</span>
</label>
</div>
<div class="feedback"></div>
</div>
<div class="question" data-correct="1">
<h4><span class="question-number">Q2:</span> What does the parser check for?</h4>
<div class="options">
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q2" value="0">
<span class="radio"></span>
<span>Performance bottlenecks</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q2" value="1">
<span class="radio"></span>
<span>Syntax rules and grammar</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q2" value="2">
<span class="radio"></span>
<span>Memory allocation</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q2" value="3">
<span class="radio"></span>
<span>CPU compatibility</span>
</label>
</div>
<div class="feedback"></div>
</div>
<div class="question" data-correct="3">
<h4><span class="question-number">Q3:</span> What does a symbol table track?</h4>
<div class="options">
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q3" value="0">
<span class="radio"></span>
<span>CPU register assignments</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q3" value="1">
<span class="radio"></span>
<span>Source code line numbers</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q3" value="2">
<span class="radio"></span>
<span>Machine instruction opcodes</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q3" value="3">
<span class="radio"></span>
<span>Names, types, and scopes of identifiers</span>
</label>
</div>
<div class="feedback"></div>
</div>
<div class="question" data-correct="0">
<h4><span class="question-number">Q4:</span> Which compiler stage is optional but improves performance?</h4>
<div class="options">
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q4" value="0">
<span class="radio"></span>
<span>Middle stage (optimization)</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q4" value="1">
<span class="radio"></span>
<span>Frontend (lexing/parsing)</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q4" value="2">
<span class="radio"></span>
<span>Backend (code generation)</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q4" value="3">
<span class="radio"></span>
<span>Linking</span>
</label>
</div>
<div class="feedback"></div>
</div>
<div class="question" data-correct="2">
<h4><span class="question-number">Q5:</span> What does "constant folding" optimization do?</h4>
<div class="options">
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q5" value="0">
<span class="radio"></span>
<span>Removes unused variables</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q5" value="1">
<span class="radio"></span>
<span>Moves code outside of loops</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q5" value="2">
<span class="radio"></span>
<span>Calculates constant expressions at compile time</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q5" value="3">
<span class="radio"></span>
<span>Converts multiplication to bit shifts</span>
</label>
</div>
<div class="feedback"></div>
</div>
<div class="question" data-correct="1">
<h4><span class="question-number">Q6:</span> What does a linker do?</h4>
<div class="options">
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q6" value="0">
<span class="radio"></span>
<span>Translates high-level code to assembly</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q6" value="1">
<span class="radio"></span>
<span>Combines compiled code and libraries into an executable</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q6" value="2">
<span class="radio"></span>
<span>Checks syntax rules</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q6" value="3">
<span class="radio"></span>
<span>Optimizes loop performance</span>
</label>
</div>
<div class="feedback"></div>
</div>
<div class="question" data-correct="0">
<h4><span class="question-number">Q7:</span> Why is assembly-to-machine-code translation simpler than compilation?</h4>
<div class="options">
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q7" value="0">
<span class="radio"></span>
<span>There's nearly a 1:1 mapping between assembly and machine instructions</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q7" value="1">
<span class="radio"></span>
<span>Assembly doesn't need optimization</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q7" value="2">
<span class="radio"></span>
<span>Assembly is a high-level language</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q7" value="3">
<span class="radio"></span>
<span>Assemblers don't use symbol tables</span>
</label>
</div>
<div class="feedback"></div>
</div>
<div class="question" data-correct="2">
<h4><span class="question-number">Q8:</span> What is the output of the compiler frontend?</h4>
<div class="options">
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q8" value="0">
<span class="radio"></span>
<span>Machine code binary</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q8" value="1">
<span class="radio"></span>
<span>Optimized assembly</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q8" value="2">
<span class="radio"></span>
<span>Intermediate representation (often an AST)</span>
</label>
<label class="option" onclick="selectOption(this)">
<input type="radio" name="q8" value="3">
<span class="radio"></span>
<span>Linked executable</span>
</label>
</div>
<div class="feedback"></div>
</div>
<button class="btn" onclick="checkQuiz()" style="width: 100%; margin-top: 1rem;">Check Answers</button>
<div class="score-display" id="scoreDisplay">
<h3 id="scoreText"></h3>
<p id="scoreMessage"></p>
</div>
</div>
</section>
</main>
<script>
// Navigation
function showSection(sectionId) {
document.querySelectorAll('section').forEach(s => s.classList.remove('active'));
document.querySelectorAll('nav button').forEach(b => b.classList.remove('active'));
document.getElementById(sectionId).classList.add('active');
event.target.classList.add('active');
}
// Expand concept cards
function toggleExpand(card) {
card.classList.toggle('expanded');
}
// Tokenizer Demo
function tokenizeCode() {
const code = document.getElementById('codeInput').value;
const tokenOutput = document.getElementById('tokenOutput');
const symbolOutput = document.getElementById('symbolOutput');
const keywords = ['int', 'float', 'double', 'char', 'void', 'if', 'else', 'while', 'for', 'return', 'break', 'continue', 'switch', 'case', 'default', 'struct', 'const', 'static'];
const operators = ['+', '-', '*', '/', '=', '==', '!=', '<', '>', '<=', '>=', '&&', '||', '!', '++', '--', '+=', '-='];
const punctuation = [';', ',', '(', ')', '{', '}', '[', ']'];
// Simple tokenizer
const tokenRegex = /(\d+\.?\d*)|([a-zA-Z_]\w*)|([+\-*\/=<>!&|]+)|([;,(){}[\]])|(".*?")|('.')/g;
const tokens = [];
const symbols = new Map();
let match;
while ((match = tokenRegex.exec(code)) !== null) {
const value = match[0];
let type, className;
if (/^\d/.test(value)) {
type = 'NUMBER';
className = 'token-number';
} else if (keywords.includes(value)) {
type = 'KEYWORD';
className = 'token-keyword';
} else if (/^[a-zA-Z_]/.test(value)) {
type = 'IDENTIFIER';
className = 'token-identifier';
// Track in symbol table (simplified)
if (!symbols.has(value)) {
symbols.set(value, { type: 'unknown', scope: 'current' });
}
} else if (operators.some(op => value.includes(op))) {
type = 'OPERATOR';
className = 'token-operator';
} else if (punctuation.includes(value)) {
type = 'PUNCTUATION';
className = 'token-punctuation';
} else if (value.startsWith('"') || value.startsWith("'")) {
type = 'STRING';
className = 'token-string';
} else {
type = 'UNKNOWN';
className = 'token-punctuation';
}
tokens.push({ value, type, className });
}
// Display tokens
tokenOutput.innerHTML = tokens.map(t =>
`<span class="token ${t.className}">${t.type}: ${t.value}</span>`
).join('');
// Display symbol table
let symbolHtml = '<table class="symbol-table" style="font-size: 0.85rem;"><tr><th>Name</th><th>Type</th></tr>';
symbols.forEach((info, name) => {
symbolHtml += `<tr><td>${name}</td><td>${info.type}</td></tr>`;
});
symbolHtml += '</table>';
symbolOutput.innerHTML = symbolHtml;
}
// AST Builder (simplified)
function buildAST() {
const expr = document.getElementById('exprInput').value;
const astTree = document.getElementById('astTree');
// Very simplified AST visualization
let tree = '';
if (expr.includes('=')) {
const [left, right] = expr.split('=').map(s => s.trim());
tree += `<span class="ast-node ast-root">Assignment (=)</span>\n`;
tree += `├── <span class="ast-node ast-var">${left}</span>\n`;
// Parse right side
const rightParsed = parseExpression(right);
tree += rightParsed.split('\n').map((line, i) =>
i === 0 ? `└── ${line}` : ` ${line}`
).join('\n');
} else {
tree = parseExpression(expr);
}
astTree.innerHTML = tree;
}
function parseExpression(expr) {
expr = expr.trim();
// Handle parentheses
if (expr.startsWith('(') && expr.endsWith(')')) {
expr = expr.slice(1, -1);
}
// Find main operator (simplified - doesn't handle precedence properly)
const ops = [['+', 'Add'], ['-', 'Subtract'], ['*', 'Multiply'], ['/', 'Divide']];
for (const [op, name] of ops) {
let depth = 0;
for (let i = expr.length - 1; i >= 0; i--) {
if (expr[i] === ')') depth++;
if (expr[i] === '(') depth--;
if (depth === 0 && expr[i] === op) {
const left = expr.slice(0, i).trim();
const right = expr.slice(i + 1).trim();
let result = `<span class="ast-node ast-op">${name} (${op})</span>\n`;
const leftParsed = parseExpression(left);
result += leftParsed.split('\n').map((line, i) =>
i === 0 ? `├── ${line}` : `│ ${line}`
).join('\n') + '\n';
const rightParsed = parseExpression(right);
result += rightParsed.split('\n').map((line, i) =>
i === 0 ? `└── ${line}` : ` ${line}`
).join('\n');
return result;
}
}
}
// Leaf node
if (/^\d+$/.test(expr)) {
return `<span class="ast-node ast-num">${expr}</span>`;
}
return `<span class="ast-node ast-var">${expr}</span>`;
}
// Quiz functionality
function selectOption(option) {
const question = option.closest('.question');
question.querySelectorAll('.option').forEach(o => o.classList.remove('selected'));
option.classList.add('selected');
option.querySelector('input').checked = true;
updateProgress();
}
function updateProgress() {
const total = document.querySelectorAll('.question').length;
const answered = document.querySelectorAll('.question input:checked').length;
const progress = (answered / total) * 100;
document.getElementById('quizProgress').style.width = progress + '%';
}
function checkQuiz() {
const questions = document.querySelectorAll('.question');
let correct = 0;
const explanations = [
"The lexer breaks source code into tokens - the smallest meaningful units like keywords, identifiers, and operators.",
"The parser enforces the grammar rules of the language, checking that statements are properly formed.",
"The symbol table is a database tracking all identifiers (variables, functions, classes) with their types and scopes.",
"The optimization stage (middle) is optional but results in faster, smaller executables.",
"Constant folding evaluates constant expressions at compile time (e.g., 60*60*24 becomes 86400).",
"The linker combines your compiled code with library code to create the final executable.",
"Assembly has a nearly 1:1 correspondence with machine instructions, making translation straightforward.",
"The frontend produces an intermediate representation (typically an AST) that represents the program's structure."
];
questions.forEach((q, index) => {
const selected = q.querySelector('input:checked');
const correctAnswer = parseInt(q.dataset.correct);
const feedback = q.querySelector('.feedback');
// Reset styles
q.querySelectorAll('.option').forEach(o => {
o.classList.remove('correct', 'incorrect');
});
if (selected) {
const selectedValue = parseInt(selected.value);
const selectedOption = selected.closest('.option');
if (selectedValue === correctAnswer) {
correct++;
selectedOption.classList.add('correct');
feedback.className = 'feedback show correct';
feedback.textContent = '✓ Correct! ' + explanations[index];
} else {
selectedOption.classList.add('incorrect');
q.querySelectorAll('.option')[correctAnswer].classList.add('correct');
feedback.className = 'feedback show incorrect';
feedback.textContent = '✗ ' + explanations[index];
}
} else {
feedback.className = 'feedback show incorrect';
feedback.textContent = 'Please select an answer. ' + explanations[index];
q.querySelectorAll('.option')[correctAnswer].classList.add('correct');
}
});
// Show score
const total = questions.length;
const percentage = Math.round((correct / total) * 100);
const scoreDisplay = document.getElementById('scoreDisplay');
const scoreText = document.getElementById('scoreText');
const scoreMessage = document.getElementById('scoreMessage');
scoreText.textContent = `${correct}/${total} (${percentage}%)`;
scoreText.style.color = percentage >= 80 ? 'var(--accent-green)' :
percentage >= 60 ? 'var(--accent-orange)' : 'var(--accent-red)';
if (percentage === 100) {
scoreMessage.textContent = "🎉 Perfect! You've mastered compiler internals!";
} else if (percentage >= 80) {
scoreMessage.textContent = "Great job! You have a solid understanding of compilers.";
} else if (percentage >= 60) {
scoreMessage.textContent = "Good effort! Review the sections you missed.";
} else {
scoreMessage.textContent = "Keep studying! Re-read the material and try again.";
}
scoreDisplay.classList.add('show');
scoreDisplay.scrollIntoView({ behavior: 'smooth' });
}
// Initialize
document.addEventListener('DOMContentLoaded', () => {
tokenizeCode();
buildAST();
});
</script>
</body>
</html>