0% found this document useful (0 votes)
36 views

Introduction To Compilers

The document discusses the structure and tasks of a compiler. It explains that a compiler has a front end that analyzes and parses source code, and a back end that generates target code. It provides examples of lexical analysis, parsing, code generation and optimization phases in a compiler.

Uploaded by

shvdo
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views

Introduction To Compilers

The document discusses the structure and tasks of a compiler. It explains that a compiler has a front end that analyzes and parses source code, and a back end that generates target code. It provides examples of lexical analysis, parsing, code generation and optimization phases in a compiler.

Uploaded by

shvdo
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 14

Main Goal

• Reading: Chapter 1
• How do we execute something like this?
int nPos = 0;
int k = 0; while (k < length) {
if (a[k] > 0) {
nPos++;
}
}
• Or, more concretely, how do we program a computer to understand and
carry out a computation written as text in a file? The computer only
knows 1’s & 0’s: encodings of instructions and data
Structure of a Compiler
At a high level, a compiler has two pieces:
– Front end: analysis
• Read source program and discover its structure and meaning
– Back end: synthesis
• Generate equivalent target language program
Compiler Tasks

• Recognize legal programs (& complain about illegal


ones)
• Generate correct code
– Compiler can attempt to improve (“optimize”)
code, but must not change behavior (meaning)
• Manage runtime storage of all variables/data
• Agree with OS & linker on target format
Front End

• Usually split into two parts


– Scanner: Responsible for converting character stream to token stream:
keywords, operators, variables, constants, …
• Also: strips out white space, comments
– Parser: Reads token stream; generates IR (Intermediate representation)
• Either here or shortly after, perform semantics analysis to check for things like type errors, etc.

• Both of these can be generated automatically


– Use a formal grammar to specify the source language
– Tools read the grammar and generate scanner & parser (lex/yacc or
flex/bison for C/C++, JFlex/CUP for Java)
Scanner Example
• Input text
// this statement does very little
if (x >= y) y = 42;
• Token Stream

• Notes:
• tokens are atomic items, not character strings; comments & whitespace are
not tokens (in most languages – counterexamples: Python indenting, Ruby
and JavaScript newlines)
• Token objects sometimes carry associated data (e.g., numeric value, variable
name)
Parser Output (IR)
• Given token stream from scanner, the parser must produce output
that captures the meaning of the program
• Most common parser output is an abstract syntax tree (AST)
– Essential meaning of program without syntactic noise
– Nodes are operations, children are operands
• Many different forms
– Tradeoffs change over time
– Tradeoffs (and IRs) can also vary between different phases of a single compiler
Scanner/Parser Example
Static Semantic Analysis
• During or (usually) after parsing, check that the program is legal and
collect info for the back end
– Type checking
– Verify language requirements like proper declarations, etc.
– Preliminary resource allocation
– Collect other information needed by back end analysis and code generation
• Key data structure: Symbol Table(s)
– Maps names -> meaning/types/details
Back End
• Responsibilities
– Translate IR into target code
– Should produce “good” code
• “good” = fast, compact, low power (pick
some)
– Should use machine resources effectively
• Registers
• Instructions
• Memory hierarchy
Back End Structure
• Typically two major parts
– “Optimization” – code improvement – change correct code into
semantically equivalent “better” code
• Examples: common subexpression elimination, constant folding, code motion
(move invariant computations outside of loops), function inlining (replace call with
body of function)
• Optimization phases often interleaved with analysis
– Target Code Generation (machine specific)
• Instruction selection & scheduling, register allocation
• Usually walk the AST and generate lower-level intermediate code before
optimization
Example
Example
Why Study Compilers?
• Become a better programmer
– Insight into interaction between languages, compilers, and hardware
– Better intuition about what your code does
– Understanding how compilers optimize code helps you write code that is easier to optimize
• Compiler techniques are everywhere
– Parsing (“little” languages, program input, scripts,…)
– Software tools (verifiers, checkers, …)
– Database engines, query languages
– Text processing
• Tex/LaTex -> dvi -> Postscript -> pdf
• Interesting challenges
– Ordering of optimization phases
– register allocation is NP-Hard
• You might even write a compiler some day
Compilers Draws ideas from many CS Areas
• AI: Greedy algorithms, heuristic search
• Algorithms: graphs, dynamic programming, approximation
• Theory: Grammars, DFAs and PDAs, pattern matching, fixed-point algorithms
• Systems: Allocation & naming, synchronization, locality
• Architecture: pipelines, instruction set use, memory hierarchy management,
locality

You might also like