![]() |
VOOZH | about |
Syntax-Directed Translation (SDT) is a method used in compiler design to convert source code into another form while analyzing its structure. It integrates syntax analysis (parsing) with semantic rules to produce intermediate code, machine code, or optimized instructions. Each grammar rule is linked with semantic actions that define how translation should occur. These actions help in tasks like evaluating expressions, checking types, generating code, and handling errors.
SDT ensures a systematic and structured way of translating programs, allowing information to be processed bottom-up or top-down through the parse tree. This makes translation efficient and accurate, ensuring that every part of the input program is correctly transformed into its executable form.
Key Elements:
General Process
An attribute is any quantity associated with a programming construct in a parse tree. Help in carrying semantic information during the compilation process.
Synthesized Attributes
Inherited Attributes
Read about Differences Between Synthesized and Inherited Attributes.
Special type of grammar used in compiler design to add extra information (attributes) to syntax rules. This helps in semantic analysis, such as type checking, variable classification, and ensuring correctness in programming languages.
Example of an Attribute Grammar
| Production Rule | Semantic Rule | Explanation |
|---|---|---|
| D β T L | L.in := T.type | The type defined in T is passed to L. |
| T β int | T.type := integer | Assigns the data type integer to T. |
| T β real | T.type := real | Assigns the data type real to T. |
| L β Lβ , id | Lβ.in := L.inaddtype(id.entry, L.in) | Passes type information to Lβ and updates the symbol table with the identifier type. |
| L β id | addtype(id.entry, L.in) | Assigns the type information to the identifier id and stores it in the symbol table. |
| Production Rule | Translation Action |
|---|---|
| E β E + T | { print('+') } |
| E β E - T | { print('-') } |
| E β T | β |
| T β 0 | { print('0') } |
| T β 1 | { print('1') } |
| β¦ | β¦ |
| T β 9 | { print('9') } |
Translation rules can be evaluated using Depth-First Search (DFS) traversal of the parse tree.
When all attributes are synthesized, the attributes of child nodes are computed before the parent node, so evaluation can be done in one traversal. If other types of attributes are present, we may need to determine the proper order of traversal and possibly perform multiple passes on the parse tree. Evaluation is performed in a bottom-up and left-to-right manner to compute translation rules correctly.
E β E + T { E.val = E.val + T.val } (PR#1)
E β T { E.val = T.val } (PR#2)
T β T * F { T.val = T.val * F.val } (PR#3)
T β F { T.val = F.val } (PR#4)
F β INTLIT { F.val = INTLIT.lexval } (PR#5)
Each production rule has a semantic action in {} that defines how values are computed.
Step 1: Build the Parse Tree
The parse tree for 2 + 3 * 4 is structured like this:
Step 2: Apply Translation Rules (Bottom-Up Evaluation)
We evaluate the expression step by step in a bottom-up manner (from leaves to root)
F β 2 β F.val = 2
F β 3 β F.val = 3
F β 4 β F.val = 4
T β F (T gets F's value) β T.val = 3
T β T * F β T.val = 3 * 4 = 12
E β T (E gets T's value) β E.val = 12
E β E + T β E.val = 2 + 12 = 14
Thus, the final computed value of 2 + 3 * 4 is 14.