[HD] EECS4302 F26 - 2026-09-15 (Tuesday) - Lecture 2
Watch on YouTube →
Overview
Jackie Wang introduces compilers as automated, semantics-preserving transformations between languages, using examples such as Java-like object-oriented code mapped to relational databases. The lecture develops a feasibility test based on input-language scope and whether the target can express the source concepts, connects compiler implementations to ANTLR 4 grammars, and explains why analyzing arbitrary runtime behavior can be undecidable. It closes with software-design guidance for the course project, including modularity and information hiding.
Key takeaways
- A compiler’s correctness depends on preserving program meaning, not merely generating syntactically valid output; its transformation rules must connect the semantics of the source and target.
- Compiler feasibility requires both a clear input scope and a target language expressive enough to represent every supported source concept.
- Compiler implementation has two distinct levels: individual program instances are transformed, while grammars define which source and target instances are valid.
- A tool that must infer the runtime outcome of arbitrary programs may need to simulate execution; non-terminating inputs make complete, guaranteed analysis impossible without additional constraints.
- Good project structure balances modularity against over-fragmentation, giving each cohesive module a focused responsibility.
- Information hiding protects external users from implementation changes: keep public interfaces stable and place volatile design decisions in private code.
Chapters
- Jackie Wang notes that recordings, digests, course notes, templates, and the syllabus materials are available to students.
- An ANTLR 4 compiler-building tutorial is planned around weeks four or five and will require substantial Java programming.
- Java experience from courses 2030 and 21101 should be sufficient; advanced algorithms from 3101 are not required.
- A compiler is a software system that transforms an input program into an output program; it is not hardware.
- Source and target languages may differ, as in Java-to-C++ or C-to-SQL translation, or may be the same, as in Java-to-Java transformation.
- The lecture introduces semantic domains before discussing syntax and implementation details.
- A semantic domain captures meaning for a particular application through a defined vocabulary.
- The object-oriented domain includes classes, objects, interfaces, abstract classes, generics, and inheritance.
- Inheritance encompasses related concepts such as polymorphism and dynamic binding.
- The relational-database domain includes entities, tables, primary and foreign keys, queries, and stored procedures.
- An object-relational bridge can map object-oriented concepts such as classes into database structures such as tables.
- Mapping arbitrary methods into SQL queries or stored procedures is substantially harder than mapping classes to tables.
- The logic domain includes propositions, predicates, functions, relations, and sets.
- Propositional operations include conjunction, negation, disjunction, and implication; predicates add universal and existential quantification.
- At a high level, a compiler automates a transformation from one semantic domain to another after developers define its rules.
- A transformer maps one syntax to another, while a translator must also preserve the meaning of the source.
- Compiler rules should implement semantics-preserving steps rather than produce arbitrary target code.
- A compiler report must explain why the generated output retains the input program’s meaning.
- A Java-like compiler needs a precisely defined input syntax, potentially using a context-free grammar.
- Project teams must decide whether to support all object-oriented features or a practical subset, such as classes and integer attributes.
- Starting with a small, working compiler and documenting unsupported features helps keep a roughly six-week project feasible.
- A key feasibility question is whether every supported input concept has an equivalent representation in the output semantic domain.
- Java-to-SQL translation must determine whether database tables and statements can represent the chosen Java-like features.
- C pointer arithmetic illustrates a difficult C-to-Java mapping because Java has no direct equivalent for arbitrary address manipulation.
- At the instance level, one compiler run maps a particular source file, such as MyClass.java, to an output such as MyDatabase.sql.
- The compiler should be deterministic: the same input should produce the same output.
- At the language-definition level, separate context-free grammars describe valid source and target programs, and the compiler defines mappings between their constructs.
- For assignments and the final project, first clarify exactly which input-language features are in scope.
- Then check whether the output’s vocabulary—such as SQL tables, queries, and insert or delete statements—can express those features.
- When target expressiveness is unclear, sketching a mapping for representative constructs can expose feasibility problems early.
- The challenge asks a program to report a variable’s last dynamic type after arbitrary assignments, conditionals, loops, and cross-class imports.
- A simple search for the Java keyword new is insufficient because a variable can inherit its dynamic type through assignments from other variables.
- Even a limited output—a single line naming the type—requires reasoning about the input program’s execution.
- The proposed type-analysis tool may need to simulate loops and other execution paths to determine a variable’s final dynamic type.
- If an arbitrary input program does not halt, a simulator may not halt either, so it cannot always produce an answer.
- General runtime-behavior inference is therefore undecidable in this setting, though restrictions such as guaranteed termination can change the problem.
- Jackie Wang lists modularity, information hiding, cohesion, the single-choice principle, object-oriented design patterns, and regression testing as project principles.
- A Superman class or module does too many unrelated tasks; modularity instead separates concerns into appropriate classes or packages.
- Modules should not be fragmented excessively either: each should be cohesive and avoid unnecessary duplication.
- Information hiding separates a class’s public interface, which external users depend on, from private implementation details.
- The public interface should remain stable while implementation choices—such as using a binary search tree versus a hash table—can change privately.
- Frequently changed functionality should be considered for placement behind the private boundary to reduce impact on clients.
- The closing exercise presents a Student class with resident/non-resident kinds, premium or discount rates, and repeated kind checks in tuition and course-registration methods.
Summary, takeaways, and chapters were generated by AI from the video's transcript and may contain errors. The video belongs to its creator, Jackie Wang.