What do you understand by L-attributed definition? Give example. Describe with diagram the working process of Lexical Analyzer. Describe LR parsing with block diagram.
L-attributes: All variables have an attribute associated with it, getting some values.
A→BCD.
A.s=f(B.s, C.s, D.s).
A is getting values from its children. Such an attribute is called Synthesized attribute because they are synthesizing the value of the attribute from the children.
A→BCD, if say C is getting the values from its parent A or its left siblings B, it is called inherited attribute. C.i=A.i; C.i=B.i.
An L-attributed SDT (Syntax Directed Translation)
Uses both inherited and synthesized attributes.
Semantic actions are placed anywhere on RHS. A→{}BC | D{}E | FG{}
Attributes are evaluated by traversing parse tree by depth first search, left to right.
Ex: A→BC {B.s=A.s}
We can see that is inherited attribute. So, it is L-attributed.
Lexical analysis reads characters from left to right and groups into tokens. A simple way to build lexical analyzer is to construct a diagram to illustrate the structure of tokens of the source program. We can also produce a lexical analyzer automatically by specifying the lexeme patterns to a lexical-analyzer generator and compiling those patterns into code that functions as a lexical analyzer. This approach makes it easier to modify a lexical analyzer, since we have only to rewrite the affected patterns, not the entire program. Three general approaches for implementing lexical analyzer are:
The speed of lexical analysis is a concern in compiler design, since only this phase reads the source program character-by character.
Since the lexical analyzer is the part of the compiler that reads the source text, it may perform certain other tasks besides identification of lexemes.
Some of the issues are: simpler design, compiler efficiency is improved and compiler portability is enhanced.
Bottom-up parsing starts from the leaf nodes of a tree and works in upward direction till it reaches the root node. Here, we start from a sentence and then apply production rules in reverse manner in order to reach the start symbol. The image given below depicts the bottom-up parsers available.
Shift-Reduce Parsing
Shift-reduce parsing use two unique steps for bottom-up parsing. These steps are known as shift-step and reduce-step.
LR Parser
The LR parser is a non-recursive, shift-reduce, bottom-up parser. It uses a wide class of context-free grammar which makes it the most efficient syntax analysis technique. LR parsers are also known as LR(k) parsers, where L stands for left-to-right scanning of the input stream; R stands for the construction of right-most derivation in reverse, and k denotes the number of lookahead symbols to make decisions. In LR(0), we write the reduce steps for all the terminals throughout the row.
There are three widely used algorithms available for constructing an LR parser:
LR Parsing Algorithm
Here we describe a skeleton algorithm of an LR parser:
token = next_token() repeat forever s = top of stack if action[s, token] = “shift si” then PUSH token PUSH si token = next_token() else if action[s, token] = “reduce A::= β“ then POP 2 * |β| symbols s = top of stack PUSH A PUSH goto[s,A] else if action[s, token] = “accept” then return else error()
Explain different stages of compiler with a suitable example. What is token, Patterns and Lexeme?
Show that no left recursive grammar can be LL(1). Show that no LL(1) grammar can be ambiguous.
Write a C program to find sum of digit of any no.
Discuss the different stages of ‘Capability Maturity Model’.
What is “Top-Down and Bottom-Up Design” approach?
Eliminate left recursion from the following grammar:
Write a C program to addition of two matrices.