The Tiger compiler
description
Transcript of The Tiger compiler
The Tiger compilerThe Tiger compiler
Ivan PribelaIvan Pribela
ContentsContents
The Tiger languageThe Tiger languageCourse structureCourse structureCourse sequenceCourse sequenceObject-oriented Tiger languageObject-oriented Tiger languageFunctional Tiger languageFunctional Tiger languageExisting course adaption to TigerExisting course adaption to Tiger
Tiger compilerTiger compiler
The Tiger languageThe Tiger language
Tiger programming languageTiger programming languageis simple, but nontrivial languageis simple, but nontrivial languagebelongs to Algol family with nested scopebelongs to Algol family with nested scopeheap-allocated records with implicit heap-allocated records with implicit pointerspointersarrays, integer and string variablesarrays, integer and string variablesfew simple structured control constructsfew simple structured control constructs
Easily modified toEasily modified toa functional programming languagea functional programming languagebe object-orientedbe object-oriented
The Tiger languageThe Tiger language
Sample Tiger programsSample Tiger programs
letlet functionfunction do_nothing1 do_nothing1((aa:: int, int, bb:: string string):): int int == ( ( do_nothing2do_nothing2((a a ++ 1 1));; 00 )) functionfunction do_nothing2 do_nothing2((dd:: int int):): string string == ( ( do_nothing1do_nothing1((dd,, “str” “str”));; “ ” “ ” ))inin do_nothing1do_nothing1((0, “str2”0, “str2”))endend
letlet varvar a a :=:= 0 0inin forfor i i :=:= 0 0 toto 100 100 dodo ( ( a a :=:= a a ++ 1; 1; ()() ))endend
Lexical issuesLexical issues
IdentifiersIdentifierssequence of letters, digits and sequence of letters, digits and underscores, starting with letterunderscores, starting with letter
CommentsCommentsstarting with /* and ending with */starting with /* and ending with */can apear betwean any two tokenscan apear betwean any two tokenscan be nestedcan be nested
DeclarationsDeclarations
decsdecs →→
{{ dec dec }}
decdec →→
tydec tydec ||
vardec vardec ||
fundecfundec
Declaration sequenceDeclaration sequencea sequence of type, value a sequence of type, value and function declarationsand function declarationsno punctation separates no punctation separates or terminates individual or terminates individual declarationsdeclarations
Data TypesData Types
tydectydec →→
typetype id id == ty ty
tyty →→
id id || { tyfld } { tyfld } ||
arrayarray ofof id id
tyfldtyfld →→
λλ ||
id id :: type-id type-id
{{ ,, id id :: type-id type-id }}
Built-in typesBuilt-in typesint and stringint and stringca be redefinedca be redefined
Type equalityType equalityby nameby name
Mutually recursiveMutually recursiveconsecutive sequenceconsecutive sequencelist = {hd: int, tl: listlist = {hd: int, tl: list}}
Field name reusabilityField name reusability
VariablesVariables
vardecvardec →→
varvar id id :=:= exp exp ||
varvar id id [[ :: type-id type-id ]]
:=:= exp exp
Variable typeVariable typein short form, type of the in short form, type of the expression is usedexpression is usedin long form, given type in long form, given type and type of expression and type of expression must matchmust matchif expression is if expression is nilnil, long , long fom must be usedfom must be used
Variable lasts until end Variable lasts until end of scopeof scope
FunctionsFunctions
ParametersParametersall parameters are all parameters are passed by valuepassed by value
Mutually recursiveMutually recursivedeclared in consecutive declared in consecutive sequencesequence
fundecfundec →→
functionfunction id id (( tyfld tyfld ))
== exp exp ||
functionfunction id id (( tyfld tyfld )) :: type-id type-id == expexp
Scope rulesScope rules
VariablesVariablesletlet ... vardec ... ... vardec ... inin exp exp endend
ParametersParametersfunctionfunction id id (( ... id1 ... id1 :: id2 ... id2 ... )) == exp exp
Nested scopesNested scopesaccess to a variable in outer scopes is access to a variable in outer scopes is permitedpermited
TypesTypesletlet ... typedec ... ... typedec ... inin exp exp endend
Scope rulesScope rules
FunctionsFunctionsletlet ... fundec ... ... fundec ... inin exp exp endend
Name spacesName spacestwo name spaces (types, varables & two name spaces (types, varables & functions)functions)
Local redeclarationsLocal redeclarationsobject can be hidden in a smaller scopeobject can be hidden in a smaller scopemutually recurcive objects must have mutually recurcive objects must have different namesdifferent names
ValuesValues
L-valuesL-valueslocation whose value location whose value may be read or assignedmay be read or assignedvariables, procedure variables, procedure parameters, fields of parameters, fields of records and elements of records and elements of the arraythe array
fundecfundec →→
functionfunction id id (( tyfld tyfld ))
== exp exp ||
functionfunction id id (( tyfld tyfld )) :: type-id type-id == expexp
ExpressionsExpressions
L-valueL-valueevaluates to the location contentsevaluates to the location contents
Valueless expressionsValueless expressionsprocedure calls, assignment, if-then, while, procedure calls, assignment, if-then, while, break, and sometimes if-then-elsebreak, and sometimes if-then-else
NilNilexpression nil denotes a value nilexpression nil denotes a value nilwhen used, it must have a type determinedwhen used, it must have a type determined
SequencingSequencingsequence of expressions (expsequence of expressions (exp11; exp; exp22; ... ; ... expexpnn))
ExpressionsExpressions
No valueNo valueempty sequenceempty sequencelet expression with empty in...endlet expression with empty in...end
Integer literalInteger literalsequence of digitssequence of digits
String literalString literalsequence of 0 or more printable characters betwean sequence of 0 or more printable characters betwean quotesquotes\\ \n \t \ddd \” \f...f\\\ \n \t \ddd \” \f...f\
NegationNegationFunction callFunction call
has value of function result, or produces no valuehas value of function result, or produces no value
OperationsOperations
Arithmetic operatorsArithmetic operators+ - * /+ - * /
ComparisonComparison= < > <= >= <>= < > <= >= <>produces: 0 for false, 1 for trueproduces: 0 for false, 1 for true
Boolean operatorsBoolean operators& |& |0 is considered false, non zero is true0 is considered false, non zero is true
Records and arraysRecords and arrays
Record creationRecord creationtype-id type-id {{ id id == exp { exp { ,, id id == exp} exp} }}
Array creationArray creationtype-id type-id [[ exp exp11 ]] ofof exp exp22
Assignment and ExtentAssignment and Extentrecords and arrays assignmen is by records and arrays assignmen is by referencereferencerecords and arrays have infinite records and arrays have infinite extentextent
StatementsStatements
If-then-elseIf-then-elseifif exp exp11 thenthen exp exp22 [ [ elseelse exp exp33 ] ]expexp22 and exp and exp33 must be the same must be the same typetype
While loopWhile loopwhilewhile exp exp11 dodo exp exp22
For loopFor loopforfor id id :=:= exp exp11 toto exp exp22 dodo exp exp33
StatementsStatements
BreakBreakterminates evaluation of nearest terminates evaluation of nearest while or forwhile or for
LetLetletlet desc desc inin expseq expseq endendevaluates descevaluates descbinds types variables and functionsbinds types variables and functionsresult (if any) is the result of last result (if any) is the result of last expressionexpression
ParenthesesParentheses
Standard libraryStandard library
functionfunction size size ((s: strings: string)): int: int
functionfunction substring substring (( s: string,s: string, first: int, n: intfirst: int, n: int)): string: string
functionfunction concat concat (( s1: string,s1: string, s2: strings2: string)): string: string
functionfunction print print ((s: strings: string))functionfunction flush flush ()()functionfunction getchar getchar ()(): string: string
functionfunction ord ord ((s: strings: string)): int: intfunctionfunction chr chr ((i: inti: int)): string: string
functionfunction not not ((i: inti: int)): int: intfunctionfunction exit exit ((i: inti: int))
Tiger compilerTiger compiler
Course structureCourse structure
LecturesLectures
LecturesLecturesStudents will see the theory behind Students will see the theory behind different components of a compilerdifferent components of a compilerprogramming techniques used to put programming techniques used to put the theory into practicethe theory into practiceand the interfaces used to and the interfaces used to modularize the compilermodularize the compilerwritten in Java programming written in Java programming languagelanguage
Practical exercisesPractical exercises
PPractical exercisesractical exercisesThe “student project compiler” is The “student project compiler” is reasonably simplereasonably simpleis organized to demonstrate some is organized to demonstrate some important techniques important techniques Use abstract syntax trees to avoid Use abstract syntax trees to avoid tangling syntax and semanticstangling syntax and semanticsseparates instruction selection from separates instruction selection from register allocationregister allocation
Paper exercisesPaper exercises
Each chapter has pencil-and-Each chapter has pencil-and-paper exercisespaper exercises
marked with a star are more marked with a star are more challengingchallengingtwo-star problems are difficult two-star problems are difficult but solvablebut solvableoccasional three-star exercises occasional three-star exercises are not known to have a solution. are not known to have a solution.
Topic dependancyTopic dependancy
One or two semester courseOne or two semester course
One-semester course could cover all of Part IOne-semester course could cover all of Part IChapters 1-12Chapters 1-12students implement the project compilerstudents implement the project compiler
working in groupsworking in groupsin addition, selected topics from Part II. in addition, selected topics from Part II.
An advanced or graduate course – cover Part An advanced or graduate course – cover Part IIII
as well as additional topics from the other literatureas well as additional topics from the other literaturemany of the Part II chapters can stand many of the Part II chapters can stand independentlyindependently
In a two-quarter sequenceIn a two-quarter sequencethe first quarter could cover Chapters 1-8the first quarter could cover Chapters 1-8and the second quarter could cover Chapters 9-12and the second quarter could cover Chapters 9-12and some chapters from Part IIand some chapters from Part II
Course materialCourse material
Chapters in Part IChapters in Part Iare acompanied by skeleton codeare acompanied by skeleton codeeasily built to a full working compiler easily built to a full working compiler modulemodulecan be used on practical exercisescan be used on practical exercises
Chapters in Part IIChapters in Part IIgive only theorethical knoledgegive only theorethical knoledgeand general instructions how to add and general instructions how to add discused feature to the Tiger compilerdiscused feature to the Tiger compilerthere is no skeleton codethere is no skeleton code
Target languageTarget language
CISCCISCfew registers (16, 8, or 6)few registers (16, 8, or 6)registers divided in to registers divided in to classesclassessome operations some operations available only on certain available only on certain registersregistersaritmetic operations on aritmetic operations on registers and memoryregisters and memorytwo-address instructions two-address instructions of form rof form r11 r r2233
various addressing various addressing modesmodesvariable length variable length instructionsinstructionsinstructions with side instructions with side effectseffects
RISCRISC32 registers32 registersonly one class of only one class of integer/pointer registersinteger/pointer registersarithmetic operations only arithmetic operations only betwean registersbetwean registerstree-address instructions tree-address instructions of form rof form r11 r r2233
load and store only with load and store only with M[reg+const] addressingM[reg+const] addressingevery instruction is 32bit every instruction is 32bit longlongone result effect per one result effect per instructioninstruction
Tiger compilerTiger compiler
Course sequenceCourse sequence
1. Introduction
6. Activation records
2. Lexical analysis
3. Parsing
4. Abstract syntax
5. Semantic analysis
7. Intermediate code
8. Blocks and traces
9. Instruction selection
10. Liveness analysis
11. Register allocation
12. Putting all together
Course sequenceCourse sequence
PhasesPhaseseach phase is described each phase is described in one sectionin one sectionsome compilers combine some compilers combine parse, semantic analysisparse, semantic analysisothers put instruction others put instruction selection much laterselection much latersimple compilers omit simple compilers omit control and dataflow control and dataflow analysisanalysis
1. Introduction
6. Activation records
1. Introduction
2. Lexical analysis
3. Parsing
4. Abstract syntax
5. Semantic analysis
7. Intermediate code
8. Blocks and traces
9. Instruction selection
10. Liveness analysis
11. Register allocation
12. Putting all together
IntroductionIntroduction
Modules and interfacesModules and interfaceslarge software is much large software is much easies to understandeasies to understandand to implementand to implement
Tools and softwareTools and softwarecontext-free grammarscontext-free grammarsreguar expressionsreguar expressions
Data structuresData structuresintermediate intermediate representationsrepresentationstables, treestables, trees
2. Lexical analysis
6. Activation records
1. Introduction
3. Parsing
4. Abstract syntax
5. Semantic analysis
7. Intermediate code
8. Blocks and traces
9. Instruction selection
10. Liveness analysis
11. Register allocation
12. Putting all together
2. Lexical analysis
Lexical analysisLexical analysis
Transforms program Transforms program texttext
reads program textreads program textoutputs sequence of outputs sequence of tokenstokens
AlgorithmAlgorithmgenerated from lexical generated from lexical specificationspecificationJLex lexer generatorJLex lexer generator
3. Parsing6. Activation records
2. Lexical analysis
4. Abstract syntax
5. Semantic analysis
7. Intermediate code
8. Blocks and traces
9. Instruction selection
10. Liveness analysis
11. Register allocation
12. Putting all together
3. Parsing
ParsingParsing1. Introduction
Checks program syntaxChecks program syntaxdetects errors in order of detects errors in order of tokenstokens
Parsing algorithmParsing algorithmLALR(1) - parsingLALR(1) - parsingCUP parser generatorCUP parser generator
4. Abstract syntax
6. Activation records
1. Introduction
2. Lexical analysis
3. Parsing
5. Semantic analysis
7. Intermediate code
8. Blocks and traces
9. Instruction selection
10. Liveness analysis
11. Register allocation
12. Putting all together
4. Abstract syntax
Abstract syntaxAbstract syntax
Improves modularutyImproves modularutysyntax analysis is syntax analysis is separated form semantic separated form semantic analysisanalysis
Semantic actionsSemantic actionsduring parsingduring parsingproduce abstract parse produce abstract parse treetree
5. Semantic analysis
6. Activation records
1. Introduction
2. Lexical analysis
3. Parsing
4. Abstract syntax7. Intermediate code
8. Blocks and traces
9. Instruction selection
10. Liveness analysis
11. Register allocation
12. Putting all together
5. Semantic analysis
Semantic analysisSemantic analysis
Checks program Checks program semanticsemantic
reports scope and type reports scope and type errorserrors
ActionsActionsbuilds symbol tablesbuilds symbol tablesperformes scope analysisperformes scope analysischecks typeschecks types
6. Activation records
1. Introduction
2. Lexical analysis
3. Parsing
4. Abstract syntax
5. Semantic analysis
7. Intermediate code
8. Blocks and traces
9. Instruction selection
10. Liveness analysis
11. Register allocation
12. Putting all together
6. Activation records
Activation recordsActivation records
Functions, local Functions, local variablesvariables
several invocations of the several invocations of the same function may same function may coexistcoexisteach invocation has its each invocation has its own instances of local own instances of local variablesvariables
Stack framesStack frameslocal variables, local variables, parametersparametersreturn address, return address, temporariestemporariesstatic and dynamic linksstatic and dynamic links
7. Intermediate code
6. Activation records
1. Introduction
2. Lexical analysis
3. Parsing
4. Abstract syntax
5. Semantic analysis
8. Blocks and traces
9. Instruction selection
10. Liveness analysis
11. Register allocation
12. Putting all together
7. Intermediate code
Intermediate codeIntermediate code
Allows portabilityAllows portabilityonly N front ends and M only N front ends and M back endsback ends
Abstract machine Abstract machine languagelanguage
can express target can express target machine operationsmachine operationsindipendent of details of indipendent of details of cource languagecource languagerepresented by simple represented by simple expression treesexpression trees
Intermediate codeIntermediate code
+
a *
b 4
if
= break :=
a b x 5
a + b * 4a + b * 4 if a = b if a = b
then breakthen break
else x:= 5else x:= 5
8. Blocks and traces
6. Activation records
1. Introduction
2. Lexical analysis
3. Parsing
4. Abstract syntax
5. Semantic analysis
9. Instruction selection
10. Liveness analysis
11. Register allocation
12. Putting all together
8. Blocks and traces
Blocks and tracesBlocks and traces
7. Intermediate code
Basic blocksBasic blocksbegins with a labelbegins with a labelends with jumpends with jumpno other labels or jumpsno other labels or jumps
TracesTracesblocks can be arranged in blocks can be arranged in any orderany orderarrange that most jumps arrange that most jumps are followed by their labelare followed by their label
9. Instruction selection
6. Activation records
1. Introduction
2. Lexical analysis
3. Parsing
4. Abstract syntax
5. Semantic analysis
8. Blocks and traces
10. Liveness analysis
11. Register allocation
12. Putting all together
Instruction selectionInstruction selection
9. Instruction selection
7. Intermediate code
Allows portabilityAllows portabilityfinding apropriate finding apropriate machine instructions to machine instructions to implement IRimplement IR
Tree patternsTree patternsone pattern represents one pattern represents one instructionone instructioninstruction selection is instruction selection is tiling of IR treetiling of IR tree
Instruction selectionInstruction selectionMOVE
MEM MEM
+
MEM *
+
FP CONST x
+ TEMP i CONST 4
FP CONST a
MOVE
MEM MEM
+
MEM *
+
FP CONST x
+ TEMP i CONST 4
FP CONST a
LOADLOAD rr11 → M [fp + a] → M [fp + a]
ADDIADDI rr22 → r → r00 + 4 + 4
MULMUL rr22 → r → rii x r x r22
ADDADD rr11 → r → r11 + r + r22
LOADLOAD rr22 → M [fp + x] → M [fp + x]
STORESTORE M [rM [r11 + 0] → r + 0] → r22
LOADLOAD rr11 → M [fp + a] → M [fp + a]
ADDIADDI rr22 → r → r00 + 4 + 4
MULMUL rr22 → r → rii x r x r22
ADDADD rr11 → r → r11 + r + r22
ADDIADDI rr22 → fp + x → fp + x
MOVEMOVE M [rM [r11] → M [r] → M [r22]]
10. Liveness analysis
6. Activation records
1. Introduction
2. Lexical analysis
3. Parsing
4. Abstract syntax
5. Semantic analysis
8. Blocks and traces
11. Register allocation
12. Putting all together
10. Liveness analysis
Leveness analysisLeveness analysis
9. Instruction selection
7. Intermediate code
Detects needed valuesDetects needed valuesdetermines which determines which variable will be needed in variable will be needed in the futurethe future
ProblemProblemIR has unbounded IR has unbounded number of temporariesnumber of temporariestarget machine has target machine has limited number of limited number of registersregisters
SolutionSolutionControl and dataflow Control and dataflow graphgraph
11. Register allocation
6. Activation records
1. Introduction
2. Lexical analysis
3. Parsing
4. Abstract syntax
5. Semantic analysis
8. Blocks and traces
10. Liveness analysis
12. Putting all together
11. Register allocation
Register allocationRegister allocation
9. Instruction selection
7. Intermediate code
Assignes registersAssignes registerslinks temporaries with links temporaries with registersregisters
Interference graphInterference graphis created from is created from examination of control examination of control and dataflow graphand dataflow graphis colored for registers to is colored for registers to be assignedbe assigned
12. Putting all together
6. Activation records
1. Introduction
2. Lexical analysis
3. Parsing
4. Abstract syntax
5. Semantic analysis
8. Blocks and traces
10. Liveness analysis
11. Register allocation
12. Putting all together
Putting it all togetherPutting it all together
7. Intermediate code
9. Instruction selection
PropertiesPropertiesnested functionsnested functionsmissing structured valuesmissing structured valuestree intermediate tree intermediate representationsrepresentationsregister allocationregister allocation
RemainsRemainslist all registerslist all registersprocedure entry / exitprocedure entry / exitimplement stringsimplement strings
17. Dataflow analysis
18. Loop optimizations
19. Static single assignment form
20. Pipelinining, scheduling
21. Memory hierarchies
12. Putting all together
6. Activation records
1. Introduction
2. Lexical analysis
3. Parsing
4. Abstract syntax
5. Semantic analysis
8. Blocks and traces
10. Liveness analysis
11. Register allocation
OptimizationsOptimizations
7. Intermediate code
9. Instruction selection
17. Dataflow analysis
18. Loop optimizations
19. Static single assignment form
20. Pipelinining, scheduling
21. Memory hierarchies13. Garbage collection
12. Putting all together
Optimizing compilerOptimizing compilertransforms programs to transforms programs to improve efficiencyimprove efficiencyuses dataflow analysisuses dataflow analysis
AlgorithmsAlgorithmsStatic single assignment Static single assignment formformuse pipelining if availableuse pipelining if availableutilize cacheutilize cache
13. Garbage collection
12. Putting all together
6. Activation records
1. Introduction
2. Lexical analysis
3. Parsing
4. Abstract syntax
5. Semantic analysis
8. Blocks and traces
10. Liveness analysis
11. Register allocation
Garbage collectionGarbage collection
7. Intermediate code
9. Instruction selection
17. Dataflow analysis
18. Loop optimizations
19. Static single assignment form
20. Pipelinining, scheduling
21. Memory hierarchies13. Garbage collection
12. Putting all together
AlgorithmsAlgorithmsmark and sweepmark and sweepreference countsreference countscopying collectioncopying collectiongenerational collectiongenerational collection
Incremental collectionIncremental collection
16. Polymorphic types
15. Functional languages
14. Object-oriented languages
6. Activation records
1. Introduction
2. Lexical analysis
3. Parsing
4. Abstract syntax
5. Semantic analysis
7. Intermediate code
8. Blocks and traces
9. Instruction selection
10. Liveness analysis
11. Register allocation
12. Putting all together
Language modificationsLanguage modifications
17. Dataflow analysis
18. Loop optimizations
19. Static single assignment form
20. Pipelinining, scheduling
21. Memory hierarchies13. Garbage collection
14. Object-oriented languages
16. Polymorphic types
15. Functional languages
Tiger compilerTiger compiler
Object-oriented Tiger Object-oriented Tiger languagelanguage
Object-oriented principlesObject-oriented principles
Information hidingInformation hidingUseful software principleUseful software principlemodule provide values of module provide values of given typegiven typeonly that module knows only that module knows its representationits representation
ExtensionExtensioninheritanceinheritance
Object-TigerObject-TigerTiger can easily Tiger can easily become object become object orientedoriented
Program exampleProgram example
classclass Truck Truck extendsextends Vehicle Vehicle {{
methodmethod move move ((int xint x)) == ifif x <= 80 x <= 80 thenthen position position :=:= position + x position + x
}}
varvar t t :=:= newnew Truck Truck varvar v v:: Vehicle Vehicle :=:= t t
inin tt..movemove((5050)) vv..movemove((100100))endend
letlet
start start :=:= 10 10
classclass Vehicle Vehicle extendsextends Object Object {{
varvar position position :=:= start start
methodmethod move move ((int xint x)) == ( ( position position :=:= position + x position + x ))
}}
Classes in Object-TigerClasses in Object-Tiger
Added class definitionsAdded class definitionsNo multiple inheritanceNo multiple inheritanceAllows method overrideAllows method override
decdec →→classdecclassdec
classdecclassdec →→classclass class-id class-id extends extends class-class-idid{{ { classfield} { classfield} }}
classfieldclassfield →→vardecvardec | | methodmethod
methodmethod →→methodmethod id id (( tyfld tyfld )) ==expexpmethodmethod id id (( tyfld tyfld )) :: type-id type-id ==expexp
Expressions in Object-TigerExpressions in Object-Tiger
expexp →→
newnew class-id class-id
lvalue lvalue .. id id (( ))
lvalue lvalue .. id id ((
exp exp {{ ,, exp exp }} ))
Added Added object object constructionconstructionAnd method invocationAnd method invocation
Tiger compilerTiger compiler
Functional Tiger languageFunctional Tiger language
Functional languagesFunctional languages
Equational reasoningEquational reasoningif f(x) = a this timeif f(x) = a this timef(x) must be a next timef(x) must be a next time
Imperative languagesImperative languagesfunctions have side functions have side effectseffectsx can be changed x can be changed betwean callsbetwean calls
Functions in Fun-TigerFunctions in Fun-Tiger
tyty →→
ty ty →→ ty ty ||
(( ty ty {{ ,, ty ty }} )) →→ ty ty ||
( )( ) →→ ty ty
expexp →→
exp exp (( exp exp {{ ,, exp exp } } )) ||
exp exp (( ))
Added function typeAdded function typefunction type is equal to function type is equal to other data typesother data typesany expression can be any expression can be calledcalled
PureFun-TigerPureFun-Tiger
ModificationsModificationsno assignment statementno assignment statementno while and forno while and forno conpound statementsno conpound statements
Tiger compilerTiger compiler
Existing course adaption to Existing course adaption to TigerTiger
First partFirst part
Every chapter in Part IEvery chapter in Part Istarts with problem definitionstarts with problem definitiondescribes few algorithmsdescribes few algorithmsdiscuses the best solution for Tigerdiscuses the best solution for Tigerspecifies actions to build the part of specifies actions to build the part of compiler from given skeletoncompiler from given skeletonrecomends further readingrecomends further readingcontains pencil-and-paper exercisescontains pencil-and-paper exercises
Second partSecond part
Every chapter in Part IIEvery chapter in Part IIstarts with problem definitionstarts with problem definitiondescribes few algorithmsdescribes few algorithmsdiscuses the best solution for Tigerdiscuses the best solution for Tigerthere is no skeleton codethere is no skeleton coderecomends further readingrecomends further readingcontains pencil-and-paper exercisescontains pencil-and-paper exercises
Tiger compilerTiger compiler
The endThe end