Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Table of contents
1.
Types of Attributes
1.1.
1. Synthesized Attributes
1.2.
2. Inherited Attributes
2.
Syntax-Directed Translation
2.1.
S-Attributed SDT
2.2.
L-Attributed SDT
3.
Attributes Flow in Compiler Design 
4.
Frequently Asked Questions
4.1.
What function does compiler design serve?
4.2.
What is SDD in compiler design?
4.3.
What are the compiler's two primary components?
5.
Conclusion
Last Updated: Jun 12, 2024
Medium

Attributes in Compiler Design

Author Shivani Singh
0 upvote
Master Python: Predicting weather forecasts
Speaker
Ashwin Goyal
Product Manager @

An attribute is a characteristic that determines the value of a grammatical symbol. Semantic functions, also referred to as attribute computation functions, are functions connected to grammar productions that compute the values of attributes. Predicate functions are functions that state a specific grammar's static semantic rules as well as portions of its syntax.

Attributes in Compiler Design

Some of the basis of attributes are the following:

Basis of Attributes
Basis of AttributesDescription               
TypeThese link data objects to the range of valid values
LocationThis represents the operating system's memory.
ValueThese are what an assignment operation produces.
NameThe name of these variables can be altered whenever a sub-program is called.
ComponentsData objects from other data items are called components. A pointer is used to represent this binding, which is then modified.

Also see, Cross Compiler

Types of Attributes

When parsing values from their domain, attributes can be applied to them and evaluated when conditions are met. The attributes can be roughly separated into two groups: 

  1. Synthesized Attributes 
  2. Inherited Attributes

depending on how they receive their values.

Two types of Attributes in compiler design

1. Synthesized Attributes

An attribute that lies on the left-hand side of a production is called a synthesized attribute. These attributes derive their values from the child nodes. Let's use the example of the language P->QR. If an attribute P depends on attribute Q or R, it will be a synthesized attribute.

Let us see some examples of the synthesized attributes in compiler design to understand it in a better way.

Example 1

G → PQRS

Here, G is referred to be a synthesized attribute if it receives values from its sibling nodes which are P, Q, R, and S.

Example 2

G → G * P + Q

In this example, the parent node G takes its values from all the child nodes, which are P and Q.

We have come to the end of synthesized attributes in compiler design. Now let us discuss the other types of attributes.

2. Inherited Attributes

An inherited attribute belongs to a nonterminal on the right side of a production. These characteristics borrow values from their siblings or parents. As long as the production at the parent has the non-terminal in its body, a semantic rule connected to the production at the parent defines them.

Inherited attributes are useful when the parse tree's structure differs from the source program's abstract syntax tree. Since they depend on both left and right siblings, they cannot be evaluated by a pre-order traversal of the parse tree.

Let us see some examples of the inherited attributes in compiler design to understand it in a better way.

Example 1

G → PQRS

Here, G, Q, R, and S can provide values for P. G, P, R, and S can all provide values for Q. G, P, Q, and S are sources of values for R. In the end, G, P, Q, and R are input sources for S. 

Example 2

E → E + S + T

In the above example, the value of S can be determined by E and T. Similarly, the value of T can be determined with the help of E and S. 

Now as we are now aware of the types of attributes. Let us know how these attributes are used in grammar production. These attributes are helpful in the generation of intermediate code directly. This is done with the help of syntax-directed translation. Let's proceed to know how.

Syntax-Directed Translation

Let us continue with our blog and discuss syntax-directed transmission in compiler design. This topic needs to be known to understand S-attributed SDT and L-attributed SDT better.

Grammar rules enhanced by Syntax Directed Translation make it easier to perform semantic analysis. SDT entails feeding the parse tree data attached to the nodes as attributes from the bottom up or the top down. 

The primary method for Syntax-Directed Translation is to build a parse tree or syntax tree, visit the tree's nodes in some sequence, and compute the values of the attributes at each node. Constructing an explicit tree is not always necessary when translating during parsing. 

Now, let us discuss S-attributed and L-attributed SDT.

S-Attributed SDT

The S-attributed definition is a type of syntax-directed attributes in compiler design that solely uses synthesized attributes. The symbol attribute values in the production's body are used to calculate the attribute values for the non-terminal at the head.

The nodes of the parse tree can be ranked from the bottom up when evaluating an S-attributed SDD's attributes. i.e., by conducting a post-order traverse of the parse tree and evaluating the characteristics at a node once the traversal finally leaves that node.

Let us see an example of S-attributed SDT.

Example

The grammar is given below:

S → E
E → E1+T
E → T
T → T1*F
T → F
F → digit

The S-attributed SDT of the above grammar can be written in the following way.

Production

Semantic Rules

→ ES.val = E.val
→ E1 + TE.val = E1.val + T.val
→ TE.val = T.val
→ T1 * FT.val = T1.val * F.val
→ FT.val = F.val
→ digitF.val = digit. lexval

L-Attributed SDT

L-attributed definitions are syntax-directed attributes in compiler design in which the edges of the dependency graph for the attributes in the production body can go from left to right and not from right to left. L-attributed definitions can inherit or synthesize their attributes.

If the traits are inherited, the calculation must come from the following:

  • A quality that the production head inherited.
  • By a production-related attribute, either inherited or synthesized, situated to the left of the attribute being computed.
  • An inherited or synthesized attribute is linked to the attribute in question in a way that prevents cycles from forming in the dependency network.

Let us see an example of L-attributed SDT.

Example

The grammar is given below:

G → TL
T → int
T → float
T → double
L → Ll, id
L → id.

The L-attributed SDT of the above grammar can be written in the following way.

Production 

Semantic Rules

→ T LL.in = T.type
→ intT.type = int
→ floatT.type = float
→ doubleT.type = double
→ L1, id

L1.in = L.in

Enter_type(id. entry, L.in)

→ idEntry_type(id. entry, L.in)
Get the tech career you deserve, faster!
Connect with our expert counsellors to understand how to hack your way to success
User rating 4.7/5
1:1 doubt support
95% placement record
Akash Pal
Senior Software Engineer
326% Hike After Job Bootcamp
Himanshu Gusain
Programmer Analyst
32 LPA After Job Bootcamp
After Job
Bootcamp

Attributes Flow in Compiler Design 

grammar is well-defined if the rules produce a distinct set for every conceivable parse tree. Grammars are declarative notations that do not require an ordering. If an attribute does not depend on itself, the grammar is noncircular.

An S-attributed grammar can be decorated in the same manner as an LR parser, enabling the interleaving of parsing and attribute evaluation in a single pass.

An L-attributed grammar can be decorated like an LL parser, enabling the interleaving of parsing and attribute evaluation in a single pass.

Also see,  cousins of compiler

Frequently Asked Questions

What function does compiler design serve?

A compiler is software that assists in the conversion of computer code from one programming language to another. In essence, it converts the source language program into machine language. Error detection and a crucial translation step are included in the compilation process.

What is SDD in compiler design?

In compiler design, a syntax-directed definition (SDD) is a CFG that includes attributes and rules. In an extended CFG (i.e., the nodes of the parse tree), the properties are connected to the grammar symbols. The guidelines are related to grammar creation.

What are the compiler's two primary components?

Compilation consists of two parts: analysis and synthesis. The source program is disassembled into its parts, and an interim representation of the source program is produced during the analysis phase. The target program is created from the intermediate representation by the synthesis component.

Conclusion

As we have reached the end of this blog, let us see what we have discussed so far. In this blog, we have discussed the basics of attributes in compiler design and their types which are synthesized and inherited. We also learned syntax-directed translation, its types, and attributes flow in compiler design.

If you like to learn more, you can check out our articles: 

You may refer to our Guided Path on Code360 to enhance your skill set on DSACompetitive ProgrammingSystem Design, etc. Check out essential interview questions, practice our available mock tests, look at the interview bundle for interview preparations, and so much more!

Happy Learning, Ninja!

Previous article
What is a Compiler?
Next article
Translator in Compiler Design
Live masterclass