Subset of Modula-2 (no procedures/functions) with a Coco/R-generated
compiler featuring a symbol table, static type checking and a
Modula-2-generating backend. All work lives in Test1/, built with
../CR -m -C and GNU Modula-2 (gm2 -fiso).
Analysed Sample grammars/ (21 Coco/R .atg files across the
C / Pascal / Modula-2 / Oberon / Ada / calculator families, plus
Other Formats/ with 6 ANTLR Modula-2 grammars) as reference material.
Test1/SimpleMod2.atgModula-2 subset without procedures/functions: program module only,
CONST / TYPE / VAR, full expression hierarchy, assignment and
IF CASE WHILE REPEAT LOOP/EXIT FOR WITH statements. Removed:
procedure declarations and calls, formal parameters, RETURN,
DEFINITION / IMPLEMENTATION modules, local modules, EXPORT,
PRIORITY. LL(1)-clean (subrange rule factored for Coco/R).
Test1/CR -m -C SimpleMod2.atg
(-C = emit compiler main module, -m = FORWARD declarations
commented out), CRFRAMES pointing at Test1/ for the frame files.gm2 -fiso (FileIO SymTab CodeGen SimpleMS SimpleMP
SimpleM, linked via generated module list) → Test1/SimpleM.Test1/tests/: 30+ .mod sources with .LST listings —
valid programs (t_ok_*, ok), syntax rejects (t_bad_*, bad),
symbol-table rejects, type rejects, backend demos (t_be_demo,
t_be_full).Test1/gen/: backend output (<Module>.mod per successful parse).Test1/SymTab.def/.modScopes with levels (globals at level 0) and kinds
(CONST / TYPE / VAR / IMPORT / MODULE / PREDEF / FIELD):
duplicate declarations (200), undeclared identifiers (201),
MODULE / END name match (202).
TYPE declaration (so self-references
such as POINTER TO Person resolve; A = A is caught as cyclical),
subranges, enumerations (literals typed), arrays, records with field
lists, sets, pointers, predefined types, string literals.BOOLEAN conditions, array
indexing, pointer dereference, .field selection, FOR integer-ness,
CASE label matching, IN / set elements, ordinal index and bound
types, type-position names.WITH pushes the record's fields as an inner scope, so unqualified
field access works in its body.CHAR; unknown types
(InvalidType) suppress follow-on errors to avoid cascades.t_bad_* type tests, each producing exactly its intended code
(e.g. x := 3.14 → 210, b + 1 → 211, x AND y → 212,
x = r → 213, WHILE x → 214, x.y → 215, p.b → 216,
x[1] → 217, v[r] → 218, x^ → 219, FOR r := → 220,
v : x → 221, {1, 'a'} → 222, A = A → 223).Test1/CodeGen.def/.modSyntax-directed pretty-printer: grammar actions re-emit every token
with regenerated layout (Emit / Brk / Ind / Ded) into
gen/<Module>.mod. Output is complete, ready-to-compile Modula-2
(comments dropped). Proven end to end: BeDemo / BeFull outputs
compile (gm2 -fiso -c), link and run (exit 0); all other valid-test
outputs compile too, except two whose original sources fail
identically under gm2 (strict set typing, missing MathLib library) —
i.e. the backend is faithful to its input.
Test1/: CRFRAMES=$(pwd) ../CR -m -C SimpleMod2.atg,
then gm2 -fiso -c on FileIO SymTab CodeGen SimpleMS SimpleMP
SimpleM and link with -fgen-module-list / -fuse-list../SimpleM tests/<file>.mod (listing next to the source,
generated code in gen/, symbol table dumped on stdout).NIL literal in the language,
multi-dimensional arrays check every index but track a single element
type, backend output is only meaningful when the verdict is
Parsed correctly.