Compilation Created 2026-10-13 Updated 2026-10-31
Compilation is the translation process performed by a compiler, which may include checking and transforming an abstract syntax tree. Translation can finish before execution, or happen during execution through just-in-time compilation. Reusing the translated representation can avoid repeated parsing and repeated constant folding when only the inputs change. This does not guarantee a speedup: translation itself costs work, and the choice of representation and execution mechanism matters.
One possible compilation pipeline for
. Details. x*(2+3)-4, with execution from an abstract syntax tree, a stack machine instruction sequence, or machine code Compilation arithmetic example 2026-10-14
Consider the program expression
x*(2+3)-4 in a deliberately small programming language. Its only program identifier is x, supplied as an integer input. Its literal values are nonnegative decimal numerals, interpreted as integers. Whitespace is ignored between lexical tokens. Its context-free grammar is:expression ::= term (("+" | "-") term)*
term ::= factor ("*" factor)*
factor ::= numeral | "x" | "(" expression ")"
numeral ::= digit digit*
digit ::= "0" | "1" | "2" | "3" | "4"
| "5" | "6" | "7" | "8" | "9"Here
* outside quotation marks means zero or more repetitions. Repeated operators are grouped to the left, specifying operator associativity; term gives multiplication higher operator precedence than addition and subtraction. Parentheses override that grouping. There is no unary minus, variable assignment, function call, or side effect in this language. Evaluation obtains each left operand before its right operand and uses exact integer arithmetic, with no fixed-width overflow.Lexical analysis recognizes
x, *, (, 2, +, 3, ), -, 4. Parsing constructs the concrete abstract syntax tree Sub(Mul(Name(x), Add(Int(2), Int(3))), Int(4)). Parentheses have done their work by making Add a child of Mul; they need not survive as nodes. Constant folding changes this to Sub(Mul(Name(x), Int(5)), Int(4)). It cannot replace Name(x) by a literal value because the input is supplied at execution. The resulting function of the input is .A compiler for our stack machine emits
LOAD x; PUSH 5; MUL; PUSH 4; SUB. LOAD x pushes the current input; PUSH n pushes the integer literal value n. Each binary instruction removes the top item as its right operand, then the next item as its left operand, and pushes the result. The instruction sequence is an intermediate representation that an interpreter can execute; no machine code has been emitted. A compact binary encoding could make it bytecode, but these printed instruction names are only a readable notation.Why does this compilation preserve the result? A structural induction supplies a short proof outline. Translating a literal value or
x appends its value to any initial stack. For a binary abstract syntax tree node, first translating the left child and then the right child appends the two operand values; the matching instruction replaces them by exactly the original operation's result. Previously present stack items remain intact. Constant folding also preserves the result because in the specified integer arithmetic. Together these facts explain agreement for every integer input, rather than merely agreement for one trial. Interpreter arithmetic trace Created 2026-10-14 Updated 2026-10-31
Use the compilation arithmetic example with input . An abstract syntax tree interpreter first reads
x, obtains , forms , and finally computes . Interpreting the folded abstract syntax tree skips the addition but gives the same result. The compiled stack machine instructions instead produce the following trace; the top of the stack is written on the right:instruction stack after instruction
initial []
LOAD x [7]
PUSH 5 [7, 5]
MUL [35]
PUSH 4 [35, 4]
SUB [31]Execution of
. Details. x*(2+3)-4 at : the original abstract syntax tree and the folded stack machine instructions both give The order in
SUB is essential: reversing its two popped operands would give . The same stored instruction sequence works for input , yielding , without repeating parsing or constant folding. An abstract syntax tree interpreter can likewise reuse its already-parsed tree. Reusing a representation is therefore useful to both approaches; it does not itself distinguish compilation from interpretation.The pleasing part is that a nested rooted tree and a flat instruction sequence express the same computation. The structural induction in the compilation arithmetic example connects them by a precise stack property. This tiny language always terminates and has no side effects; richer programming language semantics require a correctness argument that also accounts for failures, externally visible actions, and possible nontermination.
Lexical analysis Created 2026-10-13 Updated 2026-10-31
Recognition of lexical tokens in program text before or during parsing.
Past exam of the logic and set theory course of the University of Oxford 2008 A 1 e v Solution 2026-10-31
A subformula beginning at the first opening parenthesis equals the whole logical formula by prefix-freeness of fully parenthesized formulas. Every other subformula is the logical formula of a proper syntax subtree, by the parsing argument in part (iii). The two children of the root are precisely and , so such a subtree lies entirely inside one of those children. In particular no logical formula substring can begin in and cross the principal logical implication symbol into .
Conversely, each subformula of either child is visibly a substring of the whole expression, as is the whole expression itself. ThusTogether these cases identify the substring definition of a subformula with its usual syntax-tree definition.

