Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
34 views

What Is Syntax Directed Translation

Syntax directed translation is a technique used in compilers to construct parse trees and perform semantic analysis by associating actions with grammar rules. It is used for tasks like expression evaluation, syntax tree creation, and type checking. The document provides examples of syntax directed translation for arithmetic expressions and explains concepts like abstract syntax trees, decorated trees, and backpatching.

Uploaded by

akramshaik2004
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
34 views

What Is Syntax Directed Translation

Syntax directed translation is a technique used in compilers to construct parse trees and perform semantic analysis by associating actions with grammar rules. It is used for tasks like expression evaluation, syntax tree creation, and type checking. The document provides examples of syntax directed translation for arithmetic expressions and explains concepts like abstract syntax trees, decorated trees, and backpatching.

Uploaded by

akramshaik2004
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

What is Syntax Directed Translation?

We use it for semantic analysis, and SDT(Syntax Directed Translation) constructs the parse
tree with Grammar and Semantic action. In grammar, the need to decide who has the highest
priority will be done first, and in semantic action, the determination of what type of action is done
by grammar.
Application of Syntax Directed Translation
We use SDT(Syntax Directed Translation) for
• Executing Arithmetic Expressions
• Conversion from infix to postfix expression
• Conversion from infix to prefix expression
• For Binary to decimal conversion
• Counting the number of Reductions
• Creating a Syntax tree
• Generating intermediate code
• Storing information into the symbol table
• Type checking
Example
Here, we will cover an example of the application of SDT(Syntax Directed Translation) for a better
understanding of the SDT application uses. Let’s consider an example of an arithmetic expression,
and then you will see how we construct an SDT.
For Example: 2*(4+5)

Parse Tree of SDT construction


Semantic action is given as follows:
Production Semantic Rules

E -> E + T E1.trans = E2.trans + T.trans

E -> T E.trans = T.trans

T -> T * F T1.trans = T2.trans * F.trans


T -> F T.trans = F.trans

F -> int F.trans = int.value

F -> ( E ) F.trans = E.trans

AST(Abstract Syntax Tree) is a condensed form of an SDT tree. It has operators at internal nodes,
not at leaves. Syntactic details like parenthesis, commas, semi-commas, etc., are omitted in AST.
AST is better to structure for later compiler stages since it omits details with the source language.
It only contains information about the essential structure of the program.
For Example: 2*(4+5)

Abstract Syntax Tree Presentation

Variants of syntax trees:


A directed acyclic graph (DAG) for an expression identifies the common sub
expressions (sub expressions that occur more than once) of the expression. DAG's can be
constructed by using the same techniques that construct syntax trees.

A DAG has leaves corresponding to atomic operands and interior nodes corresponding to
operators. A node N in a DAG has more than one parent if N represents a common sub
expression, so a DAG represents expressions concisely. It gives clues to compiler about the
generating efficient code to evaluate expressions.

Example 1: Given the grammar below, for the input string id + id * id , the parse tree, syntax
tree and the DAG are as shown.

Example 2: DAG for the expression a + a * (b - c) + ( b - c ) * d is shown below.


Concrete Syntax Tree (CST):
The concrete syntax tree closely reflects the structure of the input program and retains
all the details specified by the language's concrete syntax rules. It includes elements
such as parentheses, commas, semicolons, and other punctuation. The CST is often
obtained directly from the parsing phase of the compiler.
Abstract Syntax Tree (AST):
The abstract syntax tree abstracts away the low-level details of the concrete syntax and
focuses on the essential structure of the program. It represents the program's logic and
semantics while omitting unnecessary syntactic details. The AST is typically used for
subsequent phases of the compiler, such as optimization and code generation.
Annotated Syntax Tree:
An annotated syntax tree augments the AST with additional information or annotations.
These annotations can include type information, scoping information, symbol table
references, or any other relevant data required for further analysis or transformations.
Decorated Syntax Tree:
A decorated syntax tree extends the annotated syntax tree by associating the tree
nodes with attributes or properties. These attributes can represent various aspects of
the program, such as data types, memory allocation, control flow, or other analysis
results. Decorated syntax trees are commonly used for performing static analysis and
generating intermediate representations.
Reduced Syntax Tree:
A reduced syntax tree simplifies the AST by eliminating redundancies and expressing
the program's structure in a more compact form. This reduction is achieved by applying
various transformations, such as constant folding, common subexpression elimination,
and control flow simplification. Reduced syntax trees are commonly used in
optimization phases to improve program efficiency.
These are some of the commonly encountered variants of syntax trees in compiler
design. The choice of representation depends on the specific requirements and goals
of the compiler or language analysis being performed. Each variant offers a different
level of abstraction and detail, catering to different stages and tasks in the compilation
process.
Need for Backpatching
Backpatching is mainly used for two purposes:

1. Boolean Expression:
Statements called boolean expressions have results that can either be true or
false. An expression that may only be evaluated as true or false is called a
boolean expression after the mathematician George Boole. Let’s examine some
examples in everyday language:

• My favorite color is blue. → true

• I am afraid of mathematics. → false

• 2 is greater than 5. → false

2. Flow of control statements:


During the execution of statements in a program, the flow of control statements
needs to be managed. For instance:

3. Labels and Gotos:


The most fundamental construct in programming languages for altering the flow
of control within a program is the combination of labels and goto statements.
When a compiler encounters a statement like "goto L," it needs to verify that there
is precisely one statement labeled L within the scope of the goto statement. If the
label L has already appeared, the symbol table will contain an entry with the
compiler-generated label for the first three-address instruction associated with
the source statement labeled L. During the translation process, a goto three-
address statement is generated with the compiler-generated label as its target.

When the label L is encountered for the first time in the source program, whether in a
declaration or as the destination of a forward goto, it is entered into the symbol table,
and a symbolic table for L is generated.

It is important to note that the use of labels and goto statements can make code less
readable and harder to maintain. They can lead to complex control flow and make it
difficult to understand the logical structure of a program. Therefore, it is generally
recommended to use structured control flow constructs, such as loops and conditional
statements, instead of relying heavily on goto statements and labels.

By using structured programming techniques and embracing control structures


designed for readability and maintainability, developers can enhance the clarity and
efficiency of their code while minimizing the use of labels and goto statements.

One-pass Code Generation using Backpatching


Backpatching can be used to generate a boolean expressions program and the flow of
control statements in a single pass. Label handling for Boolean statements in jumping
code is done by non-terminal B’s synthesized true list and false list attributes. If B is
true, the label to which control should go should be added to the list of a jump or
conditional jump instructions in B.truelist. The set of instructions known as B.falselist
is what ultimately receives the label to which control is sent when B is false. When the
program is generated for B, the jumps to true and false exist as well as the label field
are left empty. These early jumps are found in the lists B.truelist and B.falselist,
respectively.

In the process of code generation, a statement S possesses a synthesized attribute


called S.nextlist, which represents a list of jumps to the instruction immediately
following the code for S. These jumps are represented as indexes in an instruction
array, with labels serving as the indexes. To manipulate the list of jumps, three
functions are utilized:

• Makelist (i): This function creates a new list that contains only the index i, which
corresponds to an instruction in the array. Additionally, the function returns a
pointer to the newly generated list.

• Merge (p1, p2): The Merge function concatenates the lists pointed to by p1 and
p2, resulting in a single list that combines the jumps from both lists. The function
then returns a pointer to the concatenated list.

• Backpatch (p, i): The Backpatch function is responsible for inserting the index i
as the target label for each instruction on the list pointed to by p. This operation
ensures that the jumps in the list are redirected to the appropriate target location
represented by the index i.

Backpatching for Boolean Expressions


By employing a translation technique, code generation for Boolean expressions can be
achieved through bottom-up parsing. In grammar, a non-terminal symbol M triggers a
semantic action that retrieves the index of the subsequent instruction to be generated
at the appropriate moment.

To illustrate this, let’s consider the concept of backpatching using boolean expressions
and a production rules table. Backpatching involves updating previously generated
code with the correct target addresses or labels.

Step 1: Generation of the production table

Step 2: We have to find the TAC(Three address code) for the given expression using
backpatching:
A < B OR C < D AND P < Q
Step 3: Now we will make the parse tree for the expression:

The flow of Control Statements:


Control statements in programming languages play a crucial role in determining the
order in which statements are executed. Examples of control statements include If, If-
else, Switch-Case, and while-do statements. These statements allow programmers to
incorporate conditional logic and alter the flow of control within a program.

Boolean expressions are an integral part of control statements as they provide the
conditions that govern the flow of control. These expressions evaluate to either true or
false, and their values determine whether certain statements or blocks of code are
executed.

One of the primary purposes of boolean expressions is to modify the flow of control. By
using conditional statements such as if, the execution of specific statements or blocks
of code can be controlled based on the truth value of a boolean expression. For
example, in the statement "if (A) B," if the boolean expression A evaluates to true, the
program will execute the statement B.

Boolean expressions also serve to compute logical values within a program. During the
process of bottom-up parsing, code generation for boolean expressions can be
accomplished using translation techniques. Non-terminal markers in the grammar
trigger semantic actions that capture the index of the next instruction to be generated
at the appropriate moment.

This translation mechanism ensures that the generated code properly handles boolean
expressions and accurately reflects their logical values. By incorporating boolean
expressions and control statements, programmers can create dynamic and conditional
execution paths in their programs, leading to more versatile and efficient code.

Applications of Backpatching
• Conditional statements: Backpatching is frequently used in the code generation
of conditional statements, such as if-else and switch-case statements. During the
parsing and code generation phases, backpatching helps in setting the correct
target addresses for the conditional branches based on the evaluation of the
associated boolean expressions.

• Loop constructs: Backpatching plays a vital role in generating code for loop
constructs, such as while and for loops. It ensures that the loop control
statements, such as the loop condition and loop body, are properly connected
and that the correct target addresses are set for loop entry and exit points.

• Jump instructions: Backpatching is employed when generating code for jump


instructions, such as goto statements or function calls. It helps in updating the
target addresses of the jumps, allowing the program execution to transfer to the
desired locations.

• Error handling: Backpatching is useful in handling errors during compilation. It


allows for the insertion of appropriate error handling code or the modification of
existing code to handle exceptional situations. By backpatching error handlers
with the correct target addresses, the compiler can ensure that the program
handles errors effectively.

• Code optimization: Backpatching is sometimes used in code optimization


techniques, such as constant folding or dead code elimination. By updating the
target addresses of instructions or eliminating unnecessary jumps, backpatching
can contribute to the optimization of generated code, resulting in improved
performance.

You might also like