Short Notes on Two Topics in Compiler Design: SLR(1) Parser and Attribute Grammar
This section provides two concise, exam-ready short notes—(a) SLR(1) parser and (d) Attribute grammar—and also includes the key ideas, construction steps, and common pitfalls.
In compiler design, parsers determine whether an input string conforms to a grammar, while syntax-directed definitions / attribute grammars attach semantic meaning (e.g., types, values) to parse-tree nodes.
Key terms
- LR(0) items
- FOLLOW sets
- ACTION/GOTO tables
- Synthesized attributes
- Inherited attributes
Note: Because your question asks for “any two of the following” items, the course focuses on (a) SLR(1) parser and (d) Attribute grammar.
LR Parsing & LR(0)/SLR(1) Overview
(a) SLR(1) Parser — Short Note
Idea
An SLR(1) parser is an LR-family shift–reduce parser that uses:
- LR(0) items to build the LR automaton states, and
- FOLLOW sets to decide when to reduce.
It is called “Simple LR(1)” because it approximates LR(1) lookaheads using FOLLOW sets instead of exact context-sensitive lookaheads.
Core construction (what appears in the parsing tables)
- For each state :
- If an item has a dot before a terminal , then ACTION[i,a] = shift j.
- If an item corresponds to a production completed with dot at the end (e.g., ), then ACTION[i,a] = reduce for all terminals in FOLLOW(A).
- For completed start production (augmented grammar), ACTION[i,$$$] = accept.
- GOTO transitions come from nonterminal moves.
Why FOLLOW-based reduction works (intuitively)
FOLLOW(A) captures the terminals that can legally follow in some sentential form. Since SLR(1) uses that as the lookahead set, it often reduces correctly—but may introduce conflicts that would be avoided by full LR(1).
What conflicts mean
If the parsing table construction yields:
- Shift/Reduce conflict: the parser cannot decide between shifting and reducing.
- Reduce/Reduce conflict: two different reductions are possible for the same lookahead.
These conflicts indicate that the grammar is not SLR(1) (though it might still be LR(1) or LALR(1)).
Mini-example sketch (typical exam framing)
- Build LR(0) item sets (states).
- For a state containing :
- Reduce on lookaheads in FOLLOW(A).
- Put accept on $$$ when the augmented start production is complete.
Mermaid: shift/reduce in one view
SLR(1) Parsing Table Construction (Exam Steps)
- 1Step 1
Add a new start production and use $$$ as the end-marker.
- 2Step 2
Compute the canonical collection of LR(0) items (items are ).
- 3Step 3
For each state and grammar symbol , set GOTO[i,X] to the state reached after moving the dot over $X.
- 4Step 4
If state contains an item with dot before terminal (i.e., ), then ACTION[i,a] = shift to the target state.
- 5Step 5
If state contains , then for every terminal set ACTION[i,a] = reduce .
- 6Step 6
If state contains , then ACTION[i,$$$] = accept.
Pro Tip for SLR(1) exams
When you see a completed item , remember: SLR(1) uses FOLLOW(A) for reduce lookaheads—this is the core simplification over LR(1).
Common pitfall
If you accidentally use FIRST or exact LR(1) lookaheads for reductions, you won’t be describing SLR(1) correctly. In SLR(1), reductions are triggered by FOLLOW(A).
(d) Attribute Grammar — Short Note
What it is
An attribute grammar extends a context-free grammar by assigning:
- attributes to each grammar symbol occurrence in a parse tree, and
- semantic rules to compute attribute values.
These rules are evaluated during or after parsing to compute program properties such as:
- types,
- constant values,
- intermediate code generation information, etc.
Attribute types
- Synthesized attributes: typically evaluated bottom-up.
- Inherited attributes: require top-down or multi-pass evaluation.
Semantic rules and dependencies
A production like:
has semantic rules that specify how to compute attributes of and/or of ’s based on other attributes.
Evaluation must respect dependency order: if attribute depends on , then must be computed first.
Example shape (exam-friendly)
- Suppose .
- A synthesized attribute like may be computed as:
For inherited attributes, you might pass a context (e.g., expected type) from parent to child:
- (pattern depends on language specification)
Relation to syntax-directed definition (SDD)
An attribute grammar is a general framework; SDD is essentially a practical form where semantic rules are attached to grammar productions using attributes.
Attribute Grammar Evaluation Workflow
Build parse tree
1. ParseCreate the parse tree using the grammar rules."
Associate attribute occurrences
2. Attach attributesEach node (symbol occurrence) has attribute placeholders."
Compute attribute values
3. Evaluate semantic rulesUse semantic rules to compute synthesized/inherited attributes in a valid dependency order."
Drive translation/checking
4. Use resultsUse computed attributes for type checking, translation, or optimization decisions."
Visualizing Attribute Dependencies
A dependency graph helps confirm evaluation order.
- For synthesized attributes, dependencies usually point upward (children → parent).
- For inherited attributes, dependencies can point downward (parent → child).
Comparison: SLR(1) vs Attribute Grammar
Different purposes in a compiler: parsing vs semantic computation
Quick Clarifications
Knowledge Check
In an SLR(1) parsing table, when a production is in a state, reductions are added for which lookaheads?