Language Design, Translation Issues and Elementary Data Types
Stages in Translation, and Formal Translation Models
- Lexical analysis groups characters into tokens; syntax analysis (parsing) checks the token stream against a grammar and builds a parse/syntax tree; semantic analysis checks meaning-level rules (type compatibility, scope) that a context-free grammar cannot express; intermediate code generation produces a machine-independent form; optimisation improves it; code generation produces the target machine code. This is the same pipeline the course's Compiler Design chapters cover in depth for the syntax-through-optimisation stages — this chapter's own concern is the language-design vocabulary around it, not re-deriving those algorithms.
- A compiler translates a whole source program into target code before execution begins; an interpreter executes source (or an intermediate form) statement by statement without producing a standalone target program; a translator is the general term covering both, and an assembler is a translator specifically for assembly language into machine code.
Properties of Types and Objects; Scalar and Composite Data Types
A type is a set of values together with a set of operations on them, and it exists to catch a whole class of errors before run time (assigning a string to an integer variable) and to document intent. Scalar (primitive) types hold one value — integer, floating point, character, boolean, enumeration. Composite (structured) types are built from scalars: an array is a fixed-size homogeneous collection with random access by index; a record/struct is a fixed-size heterogeneous collection accessed by named field; a union overlays several fields at the same memory location, holding only one at a time (and so needs a discriminant elsewhere to know which is currently valid); a pointer holds the address of another value rather than the value itself.
Programming Environments and Virtual Computers
- A virtual computer is the machine a language's semantics are actually defined against — the Java Virtual Machine's bytecode instruction set, for instance — rather than any physical hardware; it is what lets the same compiled program run unmodified on different real machines.
- A programming environment is the whole toolchain supporting development — editor/IDE, compiler/interpreter, linker, debugger, version control — and its integration level (a bundled IDE versus separate command-line tools) is itself a language-design-adjacent choice that affects productivity independently of the language's own syntax.
Key takeaways
- The four major paradigms — imperative, object-oriented, functional, logic — differ in what a program IS (a sequence of state changes, communicating objects, function evaluation, or facts and rules).
- Binding time (static vs dynamic) trades earlier error-checking/speed against later flexibility.
- Translation runs lexical → syntax → semantic analysis → intermediate code → optimisation → code generation; a compiler produces standalone target code, an interpreter executes directly.
- Arrays, records, unions and pointers are the four composite type constructions built from scalar types.
- Static/dynamic typing (when checked) and strong/weak typing (whether implicit unsafe conversions are allowed) are independent axes — do not conflate them.
Practice questions (8)
Attempt each one before opening the answer. Every explanation names the tempting wrong option as well as the right one, because that is where marks are lost.
The functional programming paradigm is chiefly characterised by:
Show answer
Answer: A — Computation as evaluation of side-effect-free mathematical functions, with no mutable state
Functional languages like Haskell model computation as function application without mutable state; the other three options describe imperative, logic and (again) imperative styles respectively.A virtual method call resolved to its actual target at run time, based on the object's real (dynamic) type, is an example of:
Show answer
Answer: A — Dynamic (late) binding
The decision about which method body actually runs is deferred to run time and depends on the object's dynamic type — the defining feature of dynamic (late) binding, as opposed to a decision fixed at compile time.In the standard translation pipeline, which stage builds a parse/syntax tree from a stream of tokens?
Show answer
Answer: A — Syntax analysis (parsing)
Lexical analysis produces the token stream that syntax analysis then checks against the grammar, building the parse tree that later stages consume — this ordering is fixed because parsing needs tokens, not raw characters, to work with.A union data type differs from a record (struct) chiefly in that:
Show answer
Answer: A — All of a union's fields overlay the same memory, holding only one valid value at a time
A record allocates separate storage for every field simultaneously; a union allocates enough storage for its LARGEST field and overlays every field on that same storage, so only one field is meaningfully valid at any moment — usually tracked by a separate discriminant.Python is often described as dynamically typed but strongly typed. This means:
Show answer
Answer: A — Types are checked at run time, and the language does not silently allow meaning-changing conversions between incompatible types
Static/dynamic (WHEN checked) and strong/weak (WHETHER unsafe implicit conversions are allowed) are independent axes; Python is late (dynamic) on the first and strict (strong) on the second.The Java Virtual Machine's bytecode instruction set is an example of:
Show answer
Answer: A — A virtual computer — the machine the language's semantics are defined against
Bytecode is executed by the JVM software rather than directly by any physical CPU, which is exactly what lets the same compiled .class file run unmodified on any machine with a JVM — the definition of a virtual computer.Which of the following are examples of scalar (primitive) data types? (More than one option may be correct.)
Show answer
Answer: A — Integer; B — Boolean
Integer and boolean each hold a single value directly. An array and a record are both composite types built from scalars — an array is a homogeneous indexed collection, a record a heterogeneous named-field collection.Name the component of a programming-language implementation that executes source code (or an intermediate form) statement by statement without first producing a standalone target-code program.
Numerical answer — type the value.
Show answer
Answer: interpreter
An interpreter reads and executes each statement in turn, in contrast to a compiler, which translates the whole program into target code before any execution begins.