Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions textbook/03-parsing.md
Original file line number Diff line number Diff line change
Expand Up @@ -485,3 +485,20 @@ A parse tree for a grammar G is a tree where
Every terminal string generated by a grammar has a corresponding parse tree; every valid parse tree represents a string generated by the grammar (called the yield of the parse tree).

### How do parsers work?

A parser takes a statement string passed in as an argument and divides the string into pieces, as instructions given in a parser's template dictate. The parse template gives specific instructions to the parser on how to split up input into assigned variables.

Source James eats mayonnaise and pickles

Template subject verb object

James eats mayonnaise and pickles
^ ^ ^
| | |____Next Position
| |
| |_________Current Position
|
|______________Previous Position


The parser reads the template instructions from left to right while keeping track of certain important positions within the string statement. In the example above, the template is at the position of the verb in the given source sentence. The next step would be for the object to be assigned "mayonnaise and pickles". Templates are made to accomplish various different gramatical instructions, and establish how a parser will interpret its given input data.
12 changes: 11 additions & 1 deletion textbook/06-intermediate-representation.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,20 @@ Most commonly, Null will equal zero or a pointer to zero (memory location 0x0000

###### Type Checking

Type checking determines a program's type correctness, either during compile time, a little later as the program is evaluated, or in some cases (Java) both. Type checking ensures that the type of an expression has not changed as it is passed through different instances and evaluations.

###### Static Typing

Static type checking determines the type-correctness of a program at compile time. Static typing dictates that if a variable has a certain type, and that variable is passed or assigned to a new variable, then that new variable must also be of the same type. The programming language C, and other languages that explicityly demand types use static typing to quickly establish accuracy in type checking.

###### Dynamic Typing

Dynamic type checking allows a programming language to use typing more loosely than static type checking, as variable types need to be established until runtime. This allows for a variable to take on different types throughout the execution of code, although a final type is eventually assigned.

###### Strong Typing

###### Weak Typing
A strong typed programming language has stringent limitations on the way that variables in a program may interact with variables of different types. An easy example of this would be that a string could not mathematically interact with another variable of numerical type. A lot of major high level languages require this kind of typing, but surprisingly there are some exceptions such as PHP and JavaScript which are of weak typing.

###### Weak Typing

A weakly typed language will allow multiple operations to occur without concern over the type definition of the operands in use. This eases restrictions in what the type of a variable must be, since it might not need to be definied initially. The drawback to this form of type checking is that errors are not always identifiable by the compiler and could lead to difficuly to trace bugs.
13 changes: 11 additions & 2 deletions textbook/08-code-generation.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ It produces code in the target language, which is typically a machine language (

The code generator is distinct from the [parser](#what-is-a-parser) and the [translator](#what-is-a-translator).

Code generators try to optimize the generated code by doing several different things including using faster instructions, using fewer instructions,
exploit available registers, and avoid redundant computations.
Typical input for a code generator could be a parse or abstract syntax tree, which is translated into a set of instructions to be read at the machine level.

Code generators try to optimize the generated code by doing several different things including using faster instructions, using fewer instructions, exploit available registers, and avoid redundant computations.

The first stage of code generation is known as instruction selection, in which the compiler converts its input from some type of tree into a low level machine language, such as assembly language. Once intermediate tree instructions are loaded, they will be matched up peice by piece and converted into register operations using memory as sparingly as possible.

Once instructions are established, the compiler prioritizes them to enhance performance and speed. this can be a delicate procedure, as reordering instructions could cause a stall in processing. Algorithms used to schedule instructions aim to prevent bubbles and choose the best priority for instruction order.

Now that order has been determined, the compiler must allocation memory in registers to store the code'sinstructions. All of the variables created by the previous steps will be stored into empty allocated memory spaces. Since registers can only hold so much information, variables must be carefully tracked and stored. If registers become full, RAM can be used to store any overflow although this is costly and will slow down the overall execution speed of compilation. A good compiler will make excellent use of available registers and attempt to avoid spilling over into RAM.

A debug data format is created to store information from the compiled code so that a debugging process can interpret it at the source level. A debugging proccess handles both the machine and source languages as it interprets all variables, methods, types, and other outputs generated by the compiling process.