Lex and Yacc (Parser Generators)

Context: FIT2014_MOC Β· the Unix/Linux toolchain that turns the theory into a running parser β€” Lex builds the lexer from regexes, Yacc builds the LR parser from a CFG Β· Assignment 2 Problem it solves: you have a token spec and a grammar; you want an executable that recognises (and evaluates) the language without hand-coding a DPDA.

Quick Revision

  • 🎯 Trigger: regexes per token βž” Lex; production rules βž” Yacc; compile both, link, get a parser.
  • ⚠️ Key Constraint: Yacc silently resolves conflicts β€” shift-reduce βž” shift, reduce-reduce βž” rule listed first. A grammar that β€œworks” may still be ambiguous.

πŸ”§ The two-file pipeline

ToolFull nameInputOutput fileEntry function
LexLexical Analysera regular expression per tokenlex.yy.cyylex()
YaccYet Another Compiler-Compilera context-free grammary.tab.cyyparse()
  • How they couple βž” yyparse() repeatedly calls yylex() to pull the next token; Lex handles the regular layer, Yacc the context-free layer.
  • Build βž” compile y.tab.c and lex.yy.c with a C compiler (cc) βž” a single executable parser, which can evaluate as it parses β€” the code attached to each rule runs as that rule fires.

🧩 File anatomy (both use the same three-section shape, split by %%)

filename.l                        filename.y
    definitions ...                   declarations (incl. token names) ...
%%                                %%
    regexps + code, per token         grammar: production rules ...
%%                                %%
    C code ...                        C code ...
  • Section 1 βž” definitions / declarations. Yacc’s is where token names are declared, so Lex and Yacc agree on the vocabulary.
  • Section 2 βž” the rules: Lex pairs each regex with an action; Yacc pairs each production with an action.
  • Section 3 βž” plain C (e.g. main, helper functions).

⚠️ Common Mistakes

  • πŸ’‘ Chomsky vs Conjunctive Normal Form βž” Yacc grammars need no normal form at all; Chomsky Normal Form is a proof/algorithm device (CYK Algorithm), not an input format.
  • πŸ’‘ Treating a silent build as a correct grammar βž” Yacc resolves conflicts by default rather than failing; check the conflict report, then stratify the grammar (Plus-Times-B style) rather than relying on the default.
  • πŸ’‘ Token spec split across the two files βž” a token named in the Yacc declarations but never returned by a Lex rule (or vice versa) links cleanly and then never matches.

🧠 Active Recall