Sei sulla pagina 1di 80

COLLEGE OF ENGINEERING

TRIVANDRUM

COMPUTER SCIENCE AND ENGINEERING


COMPILER DESIGN LAB

CSE 431

COMPILER DESIGN LAB REPORT

CERTIFIED BONAFIDE RECORD OF WORK DONE BY


ASHARUDHEEN T
University Reg. No: TVE16CS022
Roll No. : 21
Class : S7 CSE

Staff In-charge:
REMYA KRISHNAN
Assistant Professor
Department of Computer Science & Engineering
Contents
1 LEXICAL ANALYZER 4
1.1 AIM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2 INPUT AND OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3 THEORY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4 ALGORITHM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.5 PROGRAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.6 OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.7 RESULT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2 LEXICAL ANALYZER USING LEX TOOL 7


2.1 AIM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2 THEORY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.3 ALGORITHM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.4 PROGRAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.5 INPUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.6 Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.7 RESULT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

3 YAAC SPECIFICATION 12
3.1 AIM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.2 THEORY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.3 Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.4 PROGRAMM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.4.1 a) Program to recognize a valid arithmetic expression that
uses operator +, – , * and / . . . . . . . . . . . . . . . . . . . 14
3.4.2 b) Program to recognize a valid variable which starts with a
letter followed by any number of letters or digits . . . . . . . . 15
3.4.3 c) Implementation of Calculator using LEX and YACC. . . . . 16
3.4.4 d) Convert the BNF rules into YACC form and write code
to generate abstract. . . . . . . . . . . . . . . . . . . . . . . . 17
3.5 OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.6 RESULT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

4 EPSILON CLOSURE OF ALL STATES OF ANY GIVEN NFA WITH


EPSILON TRANSITION 25
4.1 AIM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.2 Theory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.3 ALGORITHM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.4 PROGRAMM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

1
4.5 OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
4.6 RESULT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

5 Convert NFA with E transition to NFA without E transition 34


5.1 AIM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
5.2 INPUT AND OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . 34
5.3 THEORY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
5.4 ALGORITHM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
5.5 PROGRAMM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
5.6 OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
5.7 RESULT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

6 Convert NFA to DFA 38


6.1 AIM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
6.2 INPUT AND OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . 38
6.3 THEORY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
6.4 ALGORITHM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
6.5 PROGRAMM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
6.6 OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
6.7 RESULT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

7 DFA Minimization 46
7.1 AIM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
7.2 INPUT AND OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . 46
7.3 THEORY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
7.4 ALGORITHM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
7.5 PROGRAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
7.6 RESULT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

8 OPERATOR PRECEDENCE PARSOR 52


8.1 AIM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
8.2 INPUT AND OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . 52
8.3 THEORY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
8.4 ALGORITHM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
8.5 PROGRAMM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
8.6 OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
8.7 RESULT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

9 FIRST AND FOLLOW 57


9.1 AIM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
9.2 INPUT AND OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . 57

2
9.3 THEORY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
9.4 ALGORITHM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
9.5 PROGRAMM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
9.6 OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
9.7 RESULT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

10 RECURSIVE DESCENDT PARSER 60


10.1 AIM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
10.2 INPUT AND OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . 60
10.3 THEORY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
10.4 ALGORITHM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
10.5 PROGRAMM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
10.6 OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
10.7 RESULT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

11 SHIFT REDUCE PARSER 64


11.1 AIM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
11.2 INPUT AND OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . 64
11.3 THEORY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
11.4 ALGORITHM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
11.5 PROGRAMM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
11.6 OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
11.7 RESULT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

12 INTERMEDIATE CODE GENERATOR 68


12.1 AIM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
12.2 INPUT AND OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . 68
12.3 THEORY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
12.4 ALGORITHM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
12.5 PROGRAMM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
12.6 OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
12.7 RESULT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

13 CONSTANT PROPAGATION 72
13.1 AIM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
13.2 INPUT AND OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . 72
13.3 THEORY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
13.4 ALGORITHM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
13.5 PROGRAMM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
13.6 OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
13.7 RESULT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

3
14 LOOP UNROLLING 76
14.1 Aim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
14.2 THEORY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
14.3 ALGORITHM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
14.4 PROGRAMM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
14.5 OUTPUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
14.6 RESULT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

1 LEXICAL ANALYZER
1.1 AIM
Design and implement a lexical analyzer for given language using C and the
lexical analyzer should ignore redundant spaces, tabs and new line.

1.2 INPUT AND OUTPUT


Given an input C-file , generates stream of tokens as output

1.3 THEORY
Lexical analysis is the first phase of a compiler. If the lexical analyzer finds a
token invalid, it generates an error. The lexical analyzer works closely with
the syntax analyzer. It reads character streams from the source code, checks
for legal tokens, and passes the data to the syntax analyzer when it demands

1.4 ALGORITHM
In this program, we are using a custom language which is displayed below
and we are identifying each token in the program using regular expressions.

1.5 PROGRAM

1 # include < stdio .h >


2 # include < stdlib .h >
3 # include < string .h >
4 # include < ctype .h >
5
6 int isKeyword ( char buffer []) {
7 char keywords [32][10] = {" auto " ," break " ," case " ," char " ," const " ,"
continue " ," default " ,

4
8 " do " ," double " ," else " ," enum " ," extern " ," float " ," for " ," goto " ,
9 " if " ," int " ," long " ," register " ," return " ," short " ," signed " ,
10 " sizeof " ," static " ," struct " ," switch " ," typedef " ," union " ,
11 " unsigned " ," void " ," volatile " ," while "};
12 int i , flag = 0;
13 for ( i = 0; i < 32; ++ i ) {
14 if ( strcmp ( keywords [ i ] , buffer ) == 0) {
15 flag = 1;
16 break ;
17 }
18 }
19 return flag ;
20 }
21
22 int main () {
23 char ch , buffer [15] , operators [] = "+ -*/%=";
24 FILE * fp ;
25 int i , j =0;
26 fp = fopen (" p . txt " ," r ") ;
27 if ( fp == NULL ) {
28 printf (" error while opening the file \ n ") ;
29 exit (0) ;
30 }
31 while (( ch = fgetc ( fp ) ) != EOF ) {
32 for ( i = 0; i < 6; ++ i ) {
33 if ( ch == operators [ i ])
34 printf ("% c is operator \ n " , ch ) ;
35 }
36
37 if ( isalnum ( ch ) ) {
38 buffer [ j ++] = ch ;
39 }
40 else if (( ch == ’ ’ || ch == ’\n ’) && ( j != 0) ) {
41 buffer [ j ] = ’\0 ’;
42 j = 0;
43

44 if ( isKeyword ( buffer ) == 1)
45 printf ("% s is keyword \ n " , buffer ) ;
46 else
47 printf ("% s is indentifier \ n " , buffer ) ;
48 }
49

50 }
51 fclose ( fp ) ;
52 return 0;
53 }

5
1.6 OUTPUT

1.7 RESULT
The programm implemented successfullly

6
2 LEXICAL ANALYZER USING LEX TOOL
2.1 AIM
Implement a Lexical analyzer using Lex Tool

2.2 THEORY
Lex is a computer program that generates lexical analyzers (”scanners” or
”lexers”). Lex is commonly used with the yacc parser generator. Lex, originally
written by Mike Lesk and Eric Schmidt and described in 1975, is the standard
lexical analyzer generator on many Unix systems, and an equivalent tool is
specified as part of the POSIX standard.
Lex reads an input stream specifying the lexical analyzer and outputs source code
implementing the lexer in the C programming language. In addition to C, some
old versions of Lex could also generate a lexer in Ratfor.
The structure of a Lex file is intentionally similar to that of a yacc file; files are
divided into three sections, separated by lines that contain only two percent signs,
as follows
• The definition section defines macros and imports header files written in C.
It is also possible to write any C code here, which will be copied verbatim
into the generated source file.
• The rules section associates regular expression patterns with C statements.
When the lexer sees text in the input matching a given pattern, it will
execute the associated C code.
• The C code section contains C statements and functions that are copied
verbatim to the generated source file. These statements presumably contain
code called by the rules in the rules section. In large programs it is more
convenient to place this code in a separate file linked in at compile time.

2.3 ALGORITHM
1. Lex program contains three sections: definitions, rules, and user subroutines.
Each section must be separated from the others by a line containing only the
delimiter, %%. The format is as follows: definitions %% rules %%
user subroutines
2. In definition section, the variables make up the left column, and their
definitions make up the right column. Any C statements should be enclosed

7
in %{..}%. Identifier is defined such that the first letter of an identifier is
alphabet and remaining letters are alphanumeric.
3. In rules section, the left column contains the pattern to be recognized in an
input file to yylex(). The right column contains the C program fragment
executed when that pattern is recognized. The various patterns are
keywords, operators, new line character, number, string, identifier, beginning
and end of block, comment statements, preprocessor directive statements
etc.
4. Each pattern may have a corresponding action, that is, a fragment of C
source code to execute when the pattern is matched.
5. When yylex() matches a string in the input stream, it copies the matched
text to an external character array, yytext, before it executes any actions in
the rules section.
6. In user subroutine section, main routine calls yylex(). yywrap() is used to
get more input.
7. The lex command uses the rules and actions contained in file to generate a
program, lex.yy.c, which can be compiled with the cc command. That
program can then receive input, break the input into the logical pieces
defined by the rules in file, and run program fragments contained in the
actions in file.

2.4 PROGRAM
1 {
2 int COMMENT =0;
3 }
4 identifier [a - zA - Z ][ a - zA - Z0 -9]*
5 # .* { printf ("\ n \% s is a preprocessor directive " , yytext ) ;}
6 int |
7 float |
8 char |
9 double |
10 while |
11 for |
12 struct |
13 typedef |
14 do |
15 if |
16 break |
17 continue |
18 void |

8
19 switch |
20 return |
21 else |
22 goto { printf ( " \ n \ t \% s is a keyword " , yytext ) ;}
23 " /* " { COMMENT =1;}{ printf ( " \ n \ t \% s is a COMMENT " , yytext ) ;}
24 { identifier }\( { if (! COMMENT ) printf ( " \ nFUNCTION \ n \ t \% s " , yytext ) ;}
25 \{ { if (! COMMENT ) printf ( " \ n BLOCK BEGINS " ) ;}
26 \} { if (! COMMENT ) printf ( " BLOCK ENDS " ) ;}
27 { identifier }(\[[0 -9]*\]) ? { if (! COMMENT )
28 printf ( " \ n \% s IDENTIFIER " , yytext ) ;}
29 \ " .*\ " { if (! COMMENT ) printf ( " \ n \ t % s is a STRING " , yytext ) ;}
30 [0 -9]+ { if (! COMMENT ) printf ( " \ n % s is a NUMBER " , yytext ) ;}
31 \) (\:) ? { if (! COMMENT ) printf ( " \ n \ t " ) ; ECHO ; printf ( " \ n " ) ;}
32 \( ECHO ;
33 = { if (! COMMENT ) printf ( " \ n \ t \% s is an ASSIGNMENT OPERATOR " , yytext )
;}
34 \ <= |
35 \ >= |
36 \< |
37 == |
38 \ > { if (! COMMENT ) printf ( " \ n \ t \% s is a RELATIONAL OPERATOR " , yytext )
;}
39 int main ( int argc , char ** argv )
40 {
41 FILE * file ;
42 file = fopen ( " var . c " ," r " ) ;
43 if (! file )
44 {
45 printf ( " could not open the file " ) ;
46 exit (0) ;
47 }
48 yyin = file ;
49 yylex () ;
50 printf ( " \ n " ) ;
51 return (0) ;
52 }
53 int yywrap ()
54 {
55 return (1) ;
56 }

2.5 INPUT
input.txt
1 # include < stdio .h >
2 # include < conio .h >
3 void main ()
4 {
5 int a ,b , c ;

9
6 a =1;
7 b =2;
8 c=a+b;
9 printf ( " Sum :% d " ,c ) ;
10 }

2.6 Output

10
2.7 RESULT
Implemented lexical analyzer using Lex Tool and output was verified.

11
3 YAAC SPECIFICATION
3.1 AIM
Generate YACC specification for a few syntactic categories.
a) Program to recognize a valid arithmetic expression that uses operator +, – , *
and /.
b) Program to recognize a valid variable which starts with a letter followed by any
number of letters or digits.
c) Implementation of Calculator using LEX and YACC.
d) Convert the BNF rules into YACC form and write code to generate abstract.

3.2 THEORY
A parser generator is a program that takes as input a specification of a syntax,
and produces as output a procedure for recognizing that language. Historically,
they are also called compiler-compilers.
YACC (yet another compiler-compiler) is an LALR(1) (LookAhead, Left-to-right,
Rightmost derivation producer with 1 lookahead token) parser generator. YACC
was originally designed for being complemented by Lex.
A yacc specification consists of a mandatory rules section, and optional sections
for definitions and user subroutines.
The declarations section for definitions, if present, must be the first section in the
yacc program. The mandatory rules section follows the definitions; if there are no
definitions, then the rules section is first. In both cases, the rules section must
start with the delimiter %%. If there is a subroutines section, it follows the rules
section and is separated from the rules by another %% delimiter. If there is no
second %% delimiter, the rules section continues to the end of the file.
When all sections are present, a specification file has the format:
declarations %% rules %% subroutines
Definition Part:
The definition part includes information about the tokens used in the syntax
definition:
%token NUMBER
%token ID
Yacc automatically assigns numbers for tokens, but it can be overridden by
%token NUMBER 621
Yacc also recognizes single characters as tokens. Therefore, assigned token
numbers should no overlap ASCII codes.
The definition part can include C code external to the definition of the parser and
variable declarations, within %{ and %} in the first column.

12
It can also include the specification of the starting symbol in the grammar:
%start non-terminal
Rule Part:
The rules part contains grammar definition in a modified BNF form.
Actions is C code in { } and can be embedded inside (Translation schemes).
Auxiliary Routines Part:
The auxiliary routines part is only C code.
It includes function definitions for every function needed in rules part.
It can also contain the main() function definition if the parser is going to be run
as a program.
The main() function must call the function yyparse().

13
3.3 Algorithm
1. Start the program.
2. Reading an expression .
3. Checking the validating of the given expression according to the rule using
yacc.
4. Using expression rule print the result of the given values
5. Stop the program.

3.4 PROGRAMM
3.4.1a) Program to recognize a valid arithmetic expression that uses
operator +, – , * and /
LEX PART:

1 %{
2 # include " y . tab . h "
3 %}
4 %%
5 [a - zA - Z_ ][ a - zA - Z_0 -9]* return id ;
6 [0 -9]+(\.[0 -9]*) ? return num ;
7 [+/*] return op ;
8 . return yytext [0];
9 \n return 0;
10 %%
11 int yywrap ()
12 {
13 return 1;
14 }

YACC PART:

1 %{
2 # include < stdio .h >
3 int valid =1;
4 %}
5 % token num id op
6 %%
7 start : id ’= ’ s ’; ’
8 s : id x
9 | num x
10 | ’-’ num x
11 | ’( ’ s ’) ’ x

14
12 ;
13 x : op s
14 | ’-’ s
15 |
16 ;
17 %%
18 int yyerror ()
19 {
20 valid =0;
21 printf ("\ nInvalid expression !\ n ") ;
22 return 0;
23 }
24 int main ()
25 {
26 printf ("\ nEnter the expression :\ n ") ;
27 yyparse () ;
28 if ( valid )
29 {
30 printf ("\ nValid expression !\ n ") ;
31 }
32 }

3.4.2b) Program to recognize a valid variable which starts with a


letter followed by any number of letters or digits
LEX PART:

1 %{
2 # include " y . tab . h "
3 %}
4 %%
5 [a - zA - Z_ ][ a - zA - Z_0 -9]* return letter ;
6 [0 -9] return digit ;
7 . return yytext [0];
8 \n return 0;
9 %%
10 int yywrap ()
11 {
12 return 1;
13 }

YACC PART:

1 %{
2 # include < stdio .h >
3 int valid =1;
4 %}

15
5 % token digit letter
6 %%
7 start : letter s
8 s : letter s
9 | digit s
10 |
11 ;
12 %%
13 int yyerror ()
14 {
15 printf ("\ nIts not a identifier !\ n ") ;
16 valid =0;
17 return 0;
18 }
19 int main ()
20 {
21 printf ("\ nEnter a name to tested for identifier ") ;
22 yyparse () ;
23 if ( valid )
24 {
25 printf ("\ nIt is a identifier !\ n ") ;
26 }
27 }

3.4.3 c) Implementation of Calculator using LEX and YACC.


LEX PART:

1 %{
2 # include < stdio .h >
3 # include " y . tab . h "
4 extern int yylval ;
5 %}
6 %%
7 [0 -9]+ {
8 yylval = atoi ( yytext ) ;
9 return NUMBER ;
10 }
11 [\ t ] ;
12 [\ n ] return 0;
13 . return yytext [0];
14 %%
15 int yywrap ()
16 {
17 return 1;
18 }

YACC PART:

16
1 %{
2 # include < stdio .h >
3 int flag =0;
4 %}
5 % token NUMBER
6 % left ’+ ’ ’-’
7 % left ’* ’ ’/ ’ ’% ’
8 % left ’( ’ ’) ’
9 %%
10 ArithmeticExpression : E{
11 printf ("\ nResult =% d \ n " , $$ ) ;
12 return 0;
13 };
14 E :E ’+ ’ E { $$ = $1 + $3 ;}
15 |E ’ - ’ E { $$ = $1 - $3 ;}
16 |E ’* ’ E { $$ = $1 * $3 ;}
17 |E ’/ ’ E { $$ = $1 / $3 ;}
18 |E ’% ’ E { $$ = $1 % $3 ;}
19 | ’( ’E ’) ’ { $$ = $2 ;}
20 | NUMBER { $$ = $1 ;}
21 ;
22 %%
23 void main ()
24 {
25 printf ("\ nEnter Any Arithmetic Expression which can have
operations Addition , Subtraction , Multiplication , Divison ,
Modulus and Round brackets :\ n ") ;
26 yyparse () ;
27 if ( flag ==0)
28 printf ("\ nEntered arithmetic expression is Valid \ n \ n ") ;
29 }
30 void yyerror ()
31 {
32 printf ("\ nEntered arithmetic expression is Invalid \ n \ n ") ;
33 flag =1;
34 }

3.4.4d) Convert the BNF rules into YACC form and write code to
generate abstract.
LEX PART:

1 %{
2 # include " y . tab . h "
3 # include < stdio .h >
4 # include < string .h >

17
5 int LineNo =1;
6 %}
7 identifier [a - zA - Z ][ _a - zA - Z0 -9]*
8 number [0 -9]+|([0 -9]*\.[0 -9]+)
9 %%
10 main \(\) return MAIN ;
11 if return IF ;
12 else return ELSE ;
13 while return WHILE ;
14 int |
15 char |
16 float return TYPE ;
17 { identifier } { strcpy ( yylval . var , yytext ) ;
18 return VAR ;}
19 { number } { strcpy ( yylval . var , yytext ) ;
20 return NUM ;}
21 \< |
22 \> |
23 \ >= |
24 \ <= |
25 == { strcpy ( yylval . var , yytext ) ;
26 return RELOP ;}
27 [ \t] ;
28 \ n LineNo ++;
29 . return yytext [0];
30 %%
YACC PART:

1 %{
2 # include < string .h >
3 # include < stdio .h >
4 struct quad
5 {
6 char op [5];
7 char arg1 [10];
8 char arg2 [10];
9 char result [10];
10 } QUAD [30];
11 struct stack
12 {
13 int items [100];
14 int top ;
15 } stk ;
16 int Index =0 , tIndex =0 , StNo , Ind , tInd ;
17 extern int LineNo ;
18 %}
19 % union
20 {

18
21 char var [10];
22 }
23 % token <var > NUM VAR RELOP
24 % token MAIN IF ELSE WHILE TYPE
25 % type <var > EXPR ASSIGNMENT CONDITION IFST ELSEST WHILELOOP
26 % left ’-’ ’+ ’
27 % left ’* ’ ’/ ’
28 %%
29 PROGRAM : MAIN BLOCK
30 ;
31 BLOCK : ’{ ’ CODE ’} ’
32 ;
33 CODE : BLOCK
34 | STATEMENT CODE
35 | STATEMENT
36 ;
37 STATEMENT : DESCT ’; ’
38 | ASSIGNMENT ’; ’
39 | CONDST
40 | WHILEST
41 ;
42 DESCT : TYPE VARLIST
43 ;
44 VARLIST : VAR ’,’ VARLIST
45 | VAR
46 ;
47 ASSIGNMENT : VAR ’= ’ EXPR {
48 strcpy ( QUAD [ Index ]. op ,"=") ;
49 strcpy ( QUAD [ Index ]. arg1 , $3 ) ;
50 strcpy ( QUAD [ Index ]. arg2 ,"") ;
51 strcpy ( QUAD [ Index ]. result , $1 ) ;
52 strcpy ( $$ , QUAD [ Index ++]. result ) ;
53 }
54 ;
55 EXPR : EXPR ’+ ’ EXPR { AddQuadruple ("+" , $1 , $3 , $$ ) ;}
56 | EXPR ’-’ EXPR { AddQuadruple (" -" , $1 , $3 , $$ ) ;}
57 | EXPR ’* ’ EXPR { AddQuadruple ("*" , $1 , $3 , $$ ) ;}
58 | EXPR ’/ ’ EXPR { AddQuadruple ("/" , $1 , $3 , $$ ) ;}
59 | ’-’ EXPR { AddQuadruple (" UMIN " , $2 ,"" , $$ ) ;}
60 | ’( ’ EXPR ’) ’ { strcpy ( $$ , $2 ) ;}
61 | VAR
62 | NUM
63 ;
64 CONDST : IFST {
65 Ind = pop () ;
66 sprintf ( QUAD [ Ind ]. result ,"% d " , Index ) ;
67 Ind = pop () ;
68 sprintf ( QUAD [ Ind ]. result ,"% d " , Index ) ;
69 }

19
70 | IFST ELSEST
71 ;
72 IFST : IF ’( ’ CONDITION ’) ’ {
73 strcpy ( QUAD [ Index ]. op ,"==") ;
74 strcpy ( QUAD [ Index ]. arg1 , $3 ) ;
75 strcpy ( QUAD [ Index ]. arg2 ," FALSE ") ;
76 strcpy ( QUAD [ Index ]. result ," -1") ;
77 push ( Index ) ;
78 Index ++;
79 }
80 BLOCK {
81 strcpy ( QUAD [ Index ]. op ," GOTO ") ;
82 strcpy ( QUAD [ Index ]. arg1 ,"") ;
83 strcpy ( QUAD [ Index ]. arg2 ,"") ;
84 strcpy ( QUAD [ Index ]. result ," -1") ;
85 push ( Index ) ;
86 Index ++;
87 };
88 ELSEST : ELSE {
89 tInd = pop () ;
90 Ind = pop () ;
91 push ( tInd ) ;
92 sprintf ( QUAD [ Ind ]. result ,"% d " , Index ) ;
93 }
94 BLOCK {
95 Ind = pop () ;
96 sprintf ( QUAD [ Ind ]. result ,"% d " , Index ) ;
97 };
98 CONDITION : VAR RELOP VAR { AddQuadruple ( $2 , $1 , $3 , $$ ) ;
99 StNo = Index -1;
100 }
101 | VAR
102 | NUM
103 ;
104 WHILEST : WHILELOOP {
105 Ind = pop () ;
106 sprintf ( QUAD [ Ind ]. result ,"% d " , StNo ) ;
107 Ind = pop () ;
108 sprintf ( QUAD [ Ind ]. result ,"% d " , Index ) ;
109 }
110 ;
111 WHILELOOP : WHILE ’( ’ CONDITION ’) ’ {
112 strcpy ( QUAD [ Index ]. op ,"==") ;
113 strcpy ( QUAD [ Index ]. arg1 , $3 ) ;
114 strcpy ( QUAD [ Index ]. arg2 ," FALSE ") ;
115 strcpy ( QUAD [ Index ]. result ," -1") ;
116 push ( Index ) ;
117 Index ++;
118 }

20
119 BLOCK {
120 strcpy ( QUAD [ Index ]. op ," GOTO ") ;
121 strcpy ( QUAD [ Index ]. arg1 ,"") ;
122 strcpy ( QUAD [ Index ]. arg2 ,"") ;
123 strcpy ( QUAD [ Index ]. result ," -1") ;
124 push ( Index ) ;
125 Index ++;
126 }
127 ;
128 %%
129 extern FILE * yyin ;
130 int main ( int argc , char * argv [])
131 {
132 FILE * fp ;
133 int i ;
134 if ( argc >1)
135 {
136 fp = fopen ( argv [1] ," r ") ;
137 if (! fp )
138 {
139 printf ("\ n File not found ") ;
140 exit (0) ;
141 }
142 yyin = fp ;
143 }
144 yyparse () ;
145 printf ("\ n \ n \ t \ t - - - - - - - - - - - - - - - - - - - - - - - - - - - -""\ n \ t \ t Pos Operator
146 Arg1 Arg2 Result " "\ n \ t \ t
147 - - - - - - - - - - - - - - - - - - - -") ;
148 for ( i =0; i < Index ; i ++)
149 {
150 printf ("\ n \ t \ t % d \ t % s \ t % s \ t % s \ t
151 % s " ,i , QUAD [ i ]. op , QUAD [ i ]. arg1 , QUAD [ i ]. arg2 , QUAD [ i ]. result ) ;
152 }
153 printf ("\ n \ t \ t - - - - - - - - - - - - - - - - - - - - - - -") ;
154 printf ("\ n \ n ") ;
155 return 0;
156 }
157 void push ( int data )
158 {
159 stk . top ++;
160 if ( stk . top ==100)
161 {
162 printf ("\ n Stack overflow \ n ") ;
163 exit (0) ;
164 }
165 stk . items [ stk . top ]= data ;
166 }
167 int pop ()

21
168 {
169 int data ;
170 if ( stk . top == -1)
171 {
172 printf ("\ n Stack underflow \ n ") ;
173 exit (0) ;
174 }
175 data = stk . items [ stk . top - -];
176 return data ;
177 }
178 void AddQuadruple ( char op [5] , char arg1 [10] , char arg2 [10] ,
179 char result [10])
180 {
181 strcpy ( QUAD [ Index ]. op , op ) ;
182 strcpy ( QUAD [ Index ]. arg1 , arg1 ) ;
183 strcpy ( QUAD [ Index ]. arg2 , arg2 ) ;
184 sprintf ( QUAD [ Index ]. result ," t % d " , tIndex ++) ;
185 strcpy ( result , QUAD [ Index ++]. result ) ;
186 }
187 yyerror ()
188 {
189 printf ("\ n Error on line no :% d " , LineNo ) ;
190 }

Input file: test.c


1 main ()
2 {
3 int a ,b , c ;
4 if (a < b )
5 {
6 a=a+b;
7 }
8 while (a < b )
9 {
10 a=a+b;
11 }
12 if (a <= b )
13 {
14 c =a - b ;
15 }
16 else
17 {
18 c=a+b;
19 }
20 }

22
3.5 OUTPUT

Valid arithmetic expression or not?

Valid variable or not?

23
Calculator using LEX and YACC

BNF rules into YACC form

3.6 RESULT
Generated YACC specification for the given syntactic categories and the output
was verified.

24
4 EPSILON CLOSURE OF ALL STATES OF
ANY GIVEN NFA WITH EPSILON
TRANSITION
4.1 AIM
Implement program to find epsilon closure of all states of any given NFA with
epsilon transition

4.2 Theory
NFA is a finite automaton where for some cases when a single input is given to a
single state, the machine goes to more than 1 states, i.e. some of the moves cannot
be uniquely determined by the present state and the present input symbol.
If any finite automata contains epsilon (null) move or transaction, then that finite
automata is called NFA with epsilon moves
Epsilon means present state can go to other state without any input. This can
happen only if the present state have epsilon transition to other state.
Epsilon closure is finding all the states which can be reached from the present
state on one or more epsilon transitions.

4.3 ALGORITHM
• function EPSILONCLOSURE(enfa,int k)
– Initialize a list t containing only state k
– Initialize an iterator to the first element of the list t
– While iterator has not crossed the last element of the list t
∗ Append all states in the i pair in the transition table of enfa which
is not previously present in list t to t

25
∗ Set the iterator to the next element of the list t
– Return list t as the -closure for state k in epsilon NFA enfa
• end function

4.4 PROGRAMM
1 # include < stdio .h >
2 # include < stdlib .h >
3 # include < string .h >
4 # define MAX_LEN 100
5
6 char NFA_FILE [ MAX_LEN ];
7 char buffer [ MAX_LEN ];
8 int zz = 0;
9
10 struct DFA {
11 char * states ;
12 int count ;
13 } dfa ;
14
15 int last_index = 0;
16 FILE * fp ;
17 int symbols ;
18
19 void reset ( int ar [] , int size ) {
20 int i ;
21
22 for ( i = 0; i < size ; i ++) {
23 ar [ i ] = 0;
24 }
25 }
26
27 void check ( int ar [] , char S []) {
28 int i , j ;
29
30 int len = strlen ( S ) ;
31 for ( i = 0; i < len ; i ++) {
32
33 j = (( int ) ( S [ i ]) - 65) ;
34 ar [ j ]++;
35 }
36 }
37

38 void state ( int ar [] , int size , char S []) {


39 int j , k = 0;
40
41 for ( j = 0; j < size ; j ++) {

26
42 if ( ar [ j ] != 0)
43 S [ k ++] = ( char ) (65 + j ) ;
44 }
45
46 S [ k ] = ’ \0 ’;
47 }
48
49 int closure ( int ar [] , int size ) {
50 int i ;
51
52 for ( i = 0; i < size ; i ++) {
53 if ( ar [ i ] == 1)
54 return i ;
55 }
56 return (100) ;
57 }
58
59 int indexing ( struct DFA * dfa ) {
60 int i ;
61

62 for ( i = 0; i < last_index ; i ++) {


63 if ( dfa [ i ]. count == 0)
64 return 1;
65 }
66 return -1;
67 }
68
69 void Display_closure ( int states , int closure_ar [] ,
70 char * closure_table [] ,
71 char * NFA_TABLE [][ symbols + 1] ,
72 char * DFA_TABLE [][ symbols ]) {
73 int i ;
74 for ( i = 0; i < states ; i ++) {
75 reset ( closure_ar , states ) ;
76 closure_ar [ i ] = 2;
77
78 if ( strcmp (& NFA_TABLE [ i ][ symbols ] , " -" ) != 0) {
79

80 strcpy ( buffer , & NFA_TABLE [ i ][ symbols ]) ;


81 check ( closure_ar , buffer ) ;
82 int z = closure ( closure_ar , states ) ;
83
84 while ( z != 100)
85 {
86 if ( strcmp (& NFA_TABLE [ z ][ symbols ] , " -" ) != 0) {
87 strcpy ( buffer , & NFA_TABLE [ z ][ symbols ]) ;
88
89 check ( closure_ar , buffer ) ;
90 }

27
91 closure_ar [ z ]++;
92 z = closure ( closure_ar , states ) ;
93 }
94 }
95
96 printf ( " \ n e - Closure (% c ) :\ t " , ( char ) (65 + i ) ) ;
97
98 bzero (( void *) buffer , MAX_LEN ) ;
99 state ( closure_ar , states , buffer ) ;
100 strcpy (& closure_table [ i ] , buffer ) ;
101 printf ( " % s \ n " , & closure_table [ i ]) ;
102 }
103 }
104

105 int new_states ( struct DFA * dfa , char S []) {


106
107 int i ;
108
109 for ( i = 0; i < last_index ; i ++) {
110 if ( strcmp (& dfa [ i ]. states , S ) == 0)
111 return 0;
112 }
113
114 strcpy (& dfa [ last_index ++]. states , S ) ;
115
116 dfa [ last_index - 1]. count = 0;
117 return 1;
118 }
119
120 void trans ( char S [] , int M , char * clsr_t [] , int st ,
121 char * NFT [][ symbols + 1] , char TB []) {
122 int len = strlen ( S ) ;
123 int i , j , k , g ;
124 int arr [ st ];
125 int sz ;
126 reset ( arr , st ) ;
127 char temp [ MAX_LEN ] , temp2 [ MAX_LEN ];
128 char * buff ;
129
130 for ( i = 0; i < len ; i ++) {
131
132 j = (( int ) ( S [ i ] - 65) ) ;
133 strcpy ( temp , & NFT [ j ][ M ]) ;
134
135 if ( strcmp ( temp , " -" ) != 0) {
136 sz = strlen ( temp ) ;
137 g = 0;
138
139 while ( g < sz ) {

28
140 k = (( int ) ( temp [ g ] - 65) ) ;
141 strcpy ( temp2 , & clsr_t [ k ]) ;
142 check ( arr , temp2 ) ;
143 g ++;
144 }
145 }
146 }
147

148 bzero (( void *) temp , MAX_LEN ) ;


149 state ( arr , st , temp ) ;
150 if ( temp [0] != ’ \0 ’) {
151 strcpy ( TB , temp ) ;
152 } else
153 strcpy ( TB , " -" ) ;
154 }
155
156 void Display_DFA ( int last_index , struct DFA * dfa_states ,
157 char * DFA_TABLE [][ symbols ]) {
158 int i , j ;
159 printf ( " \ n \ n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
160 *****\ n \ n " ) ;
161 printf ( " \ t \ t DFA TRANSITION STATE TABLE \ t \ t \ n \ n " ) ;
162 printf ( " \ n STATES OF DFA :\ t \ t " ) ;
163
164 for ( i = 1; i < last_index ; i ++)
165 printf ( " %s , " , & dfa_states [ i ]. states ) ;
166 printf ( " \ n " ) ;
167 printf ( " \ n GIVEN SYMBOLS FOR DFA : \ t " ) ;
168
169 for ( i = 0; i < symbols ; i ++)
170 printf ( " %d , " , i ) ;
171 printf ( " \ n \ n " ) ;
172 printf ( " STATES \ t " ) ;
173
174 for ( i = 0; i < symbols ; i ++)
175 printf ( " |% d \ t " , i ) ;
176 printf ( " \ n " ) ;
177

178 printf ( " - - - - - - - -+ - - - - - - - - - - - - - - - - - - - - - - -\ n " ) ;


179 for ( i = 0; i < zz ; i ++) {
180 printf ( " % s \ t " , & dfa_states [ i + 1]. states ) ;
181 for ( j = 0; j < symbols ; j ++) {
182 printf ( " |% s \ t " , & DFA_TABLE [ i ][ j ]) ;
183 }
184 printf ( " \ n " ) ;
185 }
186 }
187
188 int main () {

29
189 int i , j , states ;
190 char T_buf [ MAX_LEN ];
191
192 struct DFA * dfa_states = malloc ( MAX_LEN * ( sizeof ( dfa ) ) ) ;
193 states = 6 , symbols = 2;
194
195 printf ( " \ n STATES OF NFA :\ t \ t " ) ;
196 for ( i = 0; i < states ; i ++)
197
198 printf ( " %c , " , ( char ) (65 + i ) ) ;
199 printf ( " \ n " ) ;
200 printf ( " \ n GIVEN SYMBOLS FOR NFA : \ t " ) ;
201
202 for ( i = 0; i < symbols ; i ++)
203
204 printf ( " %d , " , i ) ;
205 printf ( " eps " ) ;
206 printf ( " \ n \ n " ) ;
207 char * NFA_TABLE [ states ][ symbols + 1];
208

209 char * DFA_TABLE [ MAX_LEN ][ symbols ];


210 strcpy (& NFA_TABLE [0][0] , " FC " ) ;
211 strcpy (& NFA_TABLE [0][1] , " -" ) ;
212 strcpy (& NFA_TABLE [0][2] , " BF " ) ;
213 strcpy (& NFA_TABLE [1][0] , " -" ) ;
214 strcpy (& NFA_TABLE [1][1] , " C " ) ;
215 strcpy (& NFA_TABLE [1][2] , " -" ) ;
216 strcpy (& NFA_TABLE [2][0] , " -" ) ;
217 strcpy (& NFA_TABLE [2][1] , " -" ) ;
218 strcpy (& NFA_TABLE [2][2] , " D " ) ;
219 strcpy (& NFA_TABLE [3][0] , " E " ) ;
220 strcpy (& NFA_TABLE [3][1] , " A " ) ;
221 strcpy (& NFA_TABLE [3][2] , " -" ) ;
222 strcpy (& NFA_TABLE [4][0] , " A " ) ;
223 strcpy (& NFA_TABLE [4][1] , " -" ) ;
224 strcpy (& NFA_TABLE [4][2] , " BF " ) ;
225 strcpy (& NFA_TABLE [5][0] , " -" ) ;
226 strcpy (& NFA_TABLE [5][1] , " -" ) ;
227 strcpy (& NFA_TABLE [5][2] , " -" ) ;
228 printf ( " \ n NFA STATE TRANSITION TABLE \ n \ n \ n " ) ;
229 printf ( " STATES \ t " ) ;
230
231 for ( i = 0; i < symbols ; i ++)
232 printf ( " |% d \ t " , i ) ;
233 printf ( " eps \ n " ) ;
234
235 printf ( " - - - - - - - -+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\ n " ) ;
236 for ( i = 0; i < states ; i ++) {
237 printf ( " % c \ t " , ( char ) (65 + i ) ) ;

30
238
239 for ( j = 0; j <= symbols ; j ++) {
240 printf ( " |% s \ t " , & NFA_TABLE [ i ][ j ]) ;
241 }
242 printf ( " \ n " ) ;
243 }
244 int closure_ar [ states ];
245 char * closure_table [ states ];
246
247 Display_closure ( states , closure_ar , closure_table , NFA_TABLE ,
248 DFA_TABLE ) ;
249 strcpy (& dfa_states [ last_index ++]. states , " -" ) ;
250
251 dfa_states [ last_index - 1]. count = 1;
252 bzero (( void *) buffer , MAX_LEN ) ;
253
254 strcpy ( buffer , & closure_table [0]) ;
255 strcpy (& dfa_states [ last_index ++]. states , buffer ) ;
256
257 int Sm = 1 , ind = 1;
258 int start_index = 1;
259
260 while ( ind != -1) {
261 dfa_states [ start_index ]. count = 1;
262 Sm = 0;
263 for ( i = 0; i < symbols ; i ++) {
264
265 trans ( buffer , i , closure_table , states , NFA_TABLE , T_buf ) ;
266
267 strcpy (& DFA_TABLE [ zz ][ i ] , T_buf ) ;
268
269 Sm = Sm + new_states ( dfa_states , T_buf ) ;
270 }
271 ind = indexing ( dfa_states ) ;
272 if ( ind != -1)
273 strcpy ( buffer , & dfa_states [++ start_index ]. states ) ;
274 zz ++;
275 }
276 Display_DFA ( last_index , dfa_states , DFA_TABLE ) ;
277
278 return 0;
279 }

31
4.5 OUTPUT

32
4.6 RESULT
Successfully implemented the to find epsilon closure of all states of any given NFA
with transition. Epsilon closure for a state can be obtained by union operation of
the -closure of the states which can be reached from X with a single move in
recursive manner. The program was implemented using C language.

33
5 Convert NFA with E transition to NFA
without E transition
5.1 AIM
Write program to convert NFA with transition to NFA without transition

5.2 INPUT AND OUTPUT


Given the object enfa containing transition table of an N F A, convert this
enfa to an N F A without transitions.

5.3 THEORY
Non-determinestic Finite Automata (NFA) : NFA is a finite automaton
where for some cases when a single input is given to a single state, the
machine goes to more than 1 states, i.e. some of the moves cannot be
uniquely determined by the present state and the present input symbol.

5.4 ALGORITHM
1 function C ONVERT T O NFA ( enfa )
2 1. Initialize an empty object of type NFA with variable name t
3 2. Initialize t . numstates = enfa . numstates , t . numalphabets = enfa .
numalphabets and t . finalstates = enfa . finalstates
[U+FFFD]
4 I terate through each of the state i in Q
[U+FFFD]
5 I nitialize l to the closure of state i of [U+FFFD]
- N F A enfa
[U+FFFD]
6 I terate through each of the input symbol j in [U+FFFD]
*
7 *
8 Initialize an empty list of states f
9 Iterate through each state k in l
[U+FFFD]
10 Add all states of enfa . transitiontable [ k ][ j + 1] to f
11 Remove all the duplicates from f

12 * Compute the [U+FFFD]


- closure c of f
13 * Set t . transitiontable [ i ][ j ] = c
[U+FFFD]R eturn t as the NFA without
14 [U+FFFD]
- transitions corresponding to the
[U+FFFD]
- NFA enfa
15 *
16 end function

5.5 PROGRAMM

34
1 # include " bits / stdc ++. h "
2

3 using namespace std ;


4
5 set < int > epsilon_closure ( vector < vector < set < int > > > transitions ,
int start ) {
6 queue < int > answer ;
7 set < int > res ;
8 answer . push ( start ) ;
9 int t ;
10 while (! answer . empty () ) {
11 t = answer . front () ;
12 cout < <t < <" ";
13 if ( res . find ( t ) == res . end () )
14 res . insert ( t ) ;
15 for ( auto i = transitions [ t ][0]. begin () ; i !=
transitions [ t ][0]. end () ; i ++)
16 answer . push (* i ) ;
17 answer . pop () ;
18 }
19 cout < < endl ;
20 return res ;
21 }
22
23 int main () {
24

25 vector < vector < set < int > > > transitions ;
26 vector < vector < set < int > > > nfa_transitions ;
27 int states , symbols ;
28 vector < string > sym ;
29 string s ;
30 cout < <" Enter number of states \ n ";
31 cin > > states ;
32 cout < <" Enter number of symbols \ n ";
33 cin > > symbols ;
34 cout < <" Enter symbols " < < endl ;
35 sym . push_back[U+FFFD]
(" ") ;
36 for ( int i = 1; i < symbols ; i ++) {
37 cin > > s ;
38 sym . push_back ( s ) ;
39 }
40 transitions . resize ( states ) ;
41 nfa_transitions . resize ( states ) ;
42 for ( int i = 0; i < states ; i ++) {
43 transitions [ i ]. resize ( symbols ) ;
44 nfa_transitions [ i ]. resize ( symbols ) ;
45 }
46 int t ;
47 int val ;

35
48 for ( int i = 0; i < states ; i ++) {
49 for ( int j = 0; j < symbols ; j ++) {
50 cout < <" Enter number of transitions for state
" < <i < <" and symbol " < < sym [ j ] < < endl ;
51 cin > > t ;
52 cout < <" Enter transition states \ n ";
53 while (t - -) {
54 cin > > val ;
55 transitions [ i ][ j ]. insert ( val ) ;
56 }
57 }
58 }
59 vector < set < int > > eClos ;
60 eClos . resize ( states ) ;
61 for ( int i = 0; i < states ; i ++) {
62 cout < <i < <" : ";
63 eClos [ i ] = epsilon_closure ( transitions , i ) ;
64 }
65 for ( int i = 0; i < states ; i ++) {
66 for ( int j = 1; j < symbols ; j ++) {
67 for ( auto itr = eClos [ i ]. begin () ; itr != eClos [ i
]. end () ; itr ++) {
68 for ( auto jtr = transitions [* itr ][ j ]. begin ()
; jtr != transitions [* itr ][ j ]. end () ; jtr ++) {
69 if ( nfa_transitions [ i ][ j ]. find (* jtr ) ==
nfa_transitions [ i ][ j ]. end () )
70 nfa_transitions [ i ][ j ]. insert (* jtr ) ;
71 }
72 }
73 }
74 }
75 cout < < endl ;
76 for ( int i = 0; i < states ; i ++) {
77 for ( int j = 1; j < symbols ; j ++) {
78 for ( auto itr = nfa_transitions [ i ][ j ]. begin () ; itr
!= nfa_transitions [ i ][ j ]. end () ; itr ++) {
79 for ( auto jtr = eClos [* itr ]. begin () ; jtr !=
eClos [* itr ]. end () ; jtr ++) {
80 if ( nfa_transitions [ i ][ j ]. find (* jtr ) ==
nfa_transitions [ i ][ j ]. end () )
81 nfa_transitions [ i ][ j ]. insert (* jtr ) ;
82 }
83 }
84 }
85 }
86 for ( int i = 0; i < states ; i ++) {
87 for ( int j = 1; j < symbols ; j ++) {
88 cout < <i < <" -> " < < sym [ j ] < <" : ";

36
89 for ( auto itr = nfa_transitions [ i ][ j ]. begin () ; itr
!= nfa_transitions [ i ][ j ]. end () ; itr ++)
90 cout < <* itr < <" ";
91 cout < < endl ;
92 }
93 cout < < endl ;
94 }
95 return 0;
96 }

5.6 OUTPUT

5.7 RESULT
The programm implemented successfullly

37
6 Convert NFA to DFA
6.1 AIM
Write program to convert NFA to DFA.

6.2 INPUT AND OUTPUT


Given the object nfa containing transition table of an NFA, convert this nfa
to a DFA using lazy construction.

6.3 THEORY
In NFA, when a specific input is given to the current state, the machine goes
to multiple states. It can have zero, one or more than one move on a given
input symbol. On the other hand, in DFA, when a specific input is given to
the current state, the machine goes to only one
Pstate. DFA has only one
move on a given input symbol. Let, M = (Q, , , q0, F) is an NFA which
acceptsPthe language L(M). There should be equivalent DFA denoted by M’
= (Q’, ’, q0’, ’, F’) such that L(M) = L(M’).

6.4 ALGORITHM
1 1. Initialize an empty object of type DFA with variable name dfa
2 2. Initialize dfa . num_alphabets = nfa . num _alphabets , i = 0
3 3. Intialize a set lazySet which stores subsets of Q and store {0}
in it .
4 4. Create a new row of size dfa . num_alphabets and insert into dfa .

table and
5 initialize all
6 values to -1.
7 5. While i < lazySet . size ()
[U+FFFD]
8 I terate through each of the input symbol j in [U+FFFD]
9 * Initialize an empty set of states reachable and a variable next =

-1
10 Iterate i through each element in lazySet [ i ] and push into
reachable the set
11 nfa . table [ i ][ j ]
12 Check if reachable is already in lazySet . If yes , the get the value
of next from
13 lazySet . If not , then
[U+FFFD]
14 Insert into lazySet , the set reachable and set next = lazySet .
size ()
[U+FFFD]
15 Insert next into dfa . finalStates if any element in reachable is
a final state

38
16 of the original nfa
[U+FFFD]
17 Create a new row of size dfa . num_alphabets and insert into
18 dfa . table and initialize all values to -1.
[U+FFFD]
19 dfa . table [ i ][ j ] = next[U+FFFD] Increment i
[U+FFFD]R eturn dfa as the DFA .
20
21 end function

6.5 PROGRAMM
1 # include < stdio .h >
2 # include < string .h >
3 # define STATES 50
4 struct Dstate
5 {
6 char name ;
7 char StateString [ STATES +1];
8 char trans [10];
9 int is_final ;
10 } Dstates [50];
11 struct tran
12 {
13 char sym ;
14 int tostates [50];
15 int notran ;
16 };
17 struct state
18 {
19 int no ;
20 struct tran tranlist [50];
21 };
22 int stackA [100] , stackB [100] , C [100] , Cptr = -1 , Aptr = -1 , Bptr = -1;
23 struct state States [ STATES ];
24 char temp [ STATES +1] , inp [10];
25 int nos , noi , nof ,j ,k , nods = -1;
26 void pushA ( int z )
27 {
28 stackA [++ Aptr ]= z ;
29 }
30 void pushB ( int z )
31 {
32 stackB [++ Bptr ]= z ;
33 }
34 int popA ()
35 {
36 return stackA [ Aptr - -];
37 }
38 void copy ( int i )

39
39 {
40 char temp [ STATES +1]=" ";
41 int k =0;
42 Bptr = -1;
43 strcpy ( temp , Dstates [ i ]. StateString ) ;
44 while ( temp [ k ]!= ’\0 ’)
45 {
46 pushB ( temp [ k ] - ’0 ’) ;
47 k ++;
48 }
49 }
50 int popB ()
51 {
52 return stackB [ Bptr - -];
53 }
54 int peekB ()
55 {
56 return stackA [ Bptr ];
57 }
58 int peekA ()
59 {
60 return stackA [ Aptr ];
61 }
62 int seek ( int arr [] , int ptr , int s )
63 {
64 int i ;
65 for ( i =0; i <= ptr ; i ++)
66 {
67 if ( s == arr [ i ])
68 return 1;
69 }
70 return 0;
71 }
72 void sort ()
73 {
74 int i ,j , temp ;
75 for ( i =0; i < Bptr ; i ++)
76 {
77 for ( j =0; j <( Bptr - i ) ; j ++)
78 {
79 if ( stackB [ j ] > stackB [ j +1])
80 {
81 temp = stackB [ j ];
82 stackB [ j ]= stackB [ j +1];
83 stackB [ j +1]= temp ;
84 }
85 }
86 }
87 }

40
88 void tostring ()
89 {
90 int i =0;
91 sort () ;
92 for ( i =0; i <= Bptr ; i ++)
93 {
94 temp [ i ]= stackB [ i ]+ ’0 ’;
95 }
96 temp [ i ]= ’\0 ’;
97 }
98 void display_DTran ()
99 {
100 int i , j ;
101 printf ("\ n \ t \ t DFA Transition Table ") ;
102 printf ("\ n \ t \ t - - - - - - - - - - - - - - - - - - - - ") ;
103 printf ("\ nStates \ tInputs \ n ") ;
104 for ( i =0; i < noi ; i ++)
105 {
106 printf ("\ t % c " , inp [ i ]) ;
107 }
108 printf ("\ n \t - - - - - - - - - -") ;
109 for ( i =0; i < nods ; i ++)
110 {
111
112 if ( Dstates [ i ]. is_final ==0)
113 printf ("\ n % c " , Dstates [ i ]. name ) ;
114 else
115 printf ("\ n *% c " , Dstates [ i ]. name ) ;
116
117 printf ("\ t % s " , Dstates [ i ]. StateString ) ;
118 for ( j =0; j < noi ; j ++)
119 {
120 printf ("\ t % c " , Dstates [ i ]. trans [ j ]) ;
121 }
122 }
123 printf ("\ n ") ;
124 }
125 void move ( int st , int j )
126 {
127 int ctr =0;
128 while ( ctr < States [ st ]. tranlist [ j ]. notran )
129 {
130 pushA ( States [ st ]. tranlist [ j ]. tostates [ ctr ++]) ;
131 }
132 }
133 void lambda_closure ( int st )
134 {
135 int ctr =0 , in_state = st , curst = st , chk ;
136 while ( Aptr != -1)

41
137 {
138 curst = popA () ;
139 ctr =0;
140 in_state = curst ;
141 while ( ctr <= States [ curst ]. tranlist [ noi ]. notran )
142 {
143 chk = seek ( stackB , Bptr , in_state ) ;
144 if ( chk ==0)
145 pushB ( in_state ) ;
146 in_state = States [ curst ]. tranlist [ noi ]. tostates [ ctr ++];
147 chk = seek ( stackA , Aptr , in_state ) ;
148 if ( chk ==0 && ctr <= States [ curst ]. tranlist [ noi ]. notran )
149 pushA ( in_state ) ;
150 }
151 }
152 }
153 main ()
154 {
155 int final [20] , start , fin =0 , i ;
156 char c , ans , st [20];
157 printf ("\ nEnter no . of states in NFA : ") ;
158 scanf ("% d " ,& nos ) ;
159 for ( i =0; i < nos ; i ++)
160 {
161 States [ i ]. no = i ;
162 }
163 printf ("\ nEnter the start state : ") ;
164 scanf ("% d " ,& start ) ;
165 printf (" Enter the no . of final states : ") ;
166 scanf ("% d " ,& nof ) ;
167 printf ("\ nEnter the final states : \ n ") ;
168 for ( i =0; i < nof ; i ++)
169 scanf ("% d " ,& final [ i ]) ;
170 printf ("\ nEnter the no . of input symbols : ") ;
171 scanf ("% d " ,& noi ) ;
172 c = getchar () ;
173 printf ("\ nEnter the input symbols : \ n ") ;
174 for ( i =0; i < noi ; i ++)
175 {
176 scanf ("% c " ,& inp [ i ]) ;
177 c = getchar () ;
178 }
179 inp [ i ]= ’e ’;
180 printf ("\ nEnter the transitions : ( -1 to stop ) \ n ") ;
181 for ( i =0; i < nos ; i ++)
182 {
183 for ( j =0; j <= noi ; j ++)
184 {
185 States [ i ]. tranlist [ j ]. sym = inp [ j ];

42
186 k =0;
187 ans = ’y ’;
188 while ( ans == ’y ’)
189 {
190 printf (" move (% d ,% c ) : " ,i , inp [ j ]) ;
191 scanf ("% d " ,& States [ i ]. tranlist [ j ]. tostates [ k ++]) ;
192 if ( States [ i ]. tranlist [ j ]. tostates [k -1]== -1)
193 {
194 k - -; ans = ’n ’;
195 break ;
196 }
197 }
198 States [ i ]. tranlist [ j ]. notran = k ;
199 }
200 }
201 // Conversion
202 i =0; nods =0; fin =0;
203 pushA ( start ) ;
204 lambda_closure ( peekA () ) ;
205 tostring () ;
206 Dstates [ nods ]. name = ’A ’;
207 nods ++;
208 strcpy ( Dstates [0]. StateString , temp ) ;
209 while (i < nods )
210 {
211 for ( j =0; j < noi ; j ++)
212 {
213 fin =0;
214 copy ( i ) ;
215 while ( Bptr != -1)
216 {
217 move ( popB () ,j ) ;
218 }
219 while ( Aptr != -1)
220 lambda_closure ( peekA () ) ;
221 tostring () ;
222 for ( k =0; k < nods ; k ++)
223 {
224 if (( strcmp ( temp , Dstates [ k ]. StateString ) ==0) )
225 {
226 Dstates [ i ]. trans [ j ]= Dstates [ k ]. name ;
227 break ;
228 }
229 }
230 if ( k == nods )
231 {
232 nods ++;
233 for ( k =0; k < nof ; k ++)
234 {

43
235 fin = seek ( stackB , Bptr , final [ k ]) ;
236 if ( fin ==1)
237 {
238 Dstates [ nods -1]. is_final =1;
239 break ;
240 } }
241 strcpy ( Dstates [ nods -1]. StateString , temp ) ;
242 Dstates [ nods -1]. name = ’A ’+ nods -1;
243 Dstates [ i ]. trans [ j ]= Dstates [ nods -1]. name ;
244 }
245 }
246 i ++;
247 }
248 display_DTran () ;
249 }

6.6 OUTPUT

44
6.7 RESULT
The programm implemented successfullly

45
7 DFA Minimization
7.1 AIM
Write a program to minimize any given DFA.

7.2 INPUT AND OUTPUT


Given the object dfa containing transition table of a DFA, convert this dfa
to minimized DFA.

7.3 THEORY
DFA minimization stands for converting a given DFA to its equivalent DFA
with minimum number of states. ... One set will contain all final states and
other set will contain non-final states. This partition is called P0.

7.4 ALGORITHM
1
2 function MINIMIZEDFA ( dfa )
3 1. Initialize an empty object of type dfa with variable name minDfa
4 2. Initialize minDfa . num_alphabets = dfa . num_alphabets

5 3. Initialize a matrix m of size a . num_states x a . num_states and set


every cell in the
6 matrix to 0
7 4. Initialize a flag variable f to 1
8 5. For all state pairs (x , y ) , set m [ x ][ y ] = 1 if x is a final state
and y is a non - final state
9 or vice - versa ( Choose either upper or lower triangle of the matrix )
.
10 6. While f ! = 0
[U+FFFD]S et f to 0
11
[U+FFFD]F or all states i from 0 to dfa . num_states
12
13 * For all states j from i + 1 to dfa . num_states

[U+FFFD]
14 If for any symbol u in [U+FFFD]
, m [ i ][ j ] = 0 and
15 m [ dfa . transitiontable [ i ][ u ]][ dfa . transitiontable [ j ][ u ]] = 1 ,
16 Th
17 en
18
19 Set m [ i ][ j ] = 1 and f = 1
20
21 7. Represent those pair of states (a , b ) which has m [ a ][ b ] = 0 by a
single state a in the
22 minimized DFA minDfa .

46
23
24 8. Return minDfa as the minimised DFA .
25 end function

7.5 PROGRAM

1
2 int main () {
3 int states , sym ;
4 map < pair < int , int > , int > transition_table ;
5 vector < char > symbols ;
6 char c ;
7 cout < <" Enter number of states \ n ";
8 cin > > states ;
9 cout < <" Enter number of symbols \ n ";
10 cin > > sym ;
11 cout < <" Enter symbols " < < endl ;
12 for ( int i = 0; i < sym ; i ++) {
13 cin > > c ;
14 symbols . push_back ( c ) ;
15 }
16 int t ;
17 for ( int i = 0; i < states ; i ++) {
18 for ( int j = 0; j < sym ; j ++) {
19 cout < <" Enter the transitions for state " < <i < <" and
symbol " < < symbols [ j ] < < endl ;
20 cin > > t ;
21 transition_table [{ i , j }] = t ;
22 }
23 }
24 set < int > final ;
25 map < pair < int , int > , int > min_table ;
26 int final_size ;
27 cout < <" Enter the number of final states \ n ";
28 cin > > final_size ;
29 for ( int i = 0; i < final_size ; i ++) {
30 cin > > t ;
31 final . insert ( t ) ;
32 }
33 for ( int i = 0; i < states ; i ++)
34 for ( int j = i +1; j < states ; j ++) {
35 // cout < <i < <" " < <j < < endl ;
36 if (( final . find ( i ) != final . end () && final . find ( j )
!= final . end () ) || ( final . find ( i ) == final . end () && final . find ( j
) == final . end () ) )
37 min_table [{ i , j }] = 0;

47
38 else
39 min_table [{ i , j }] = 1;
40 }
41 bool update = false ;
42 // cout < < endl ;
43 int a ,b , count = 0;
44 do {
45 update = false ;
46 for ( int i = 0; i < states ; i ++)
47 for ( int j = i +1; j < states ; j ++) {
48 if ( min_table [{ i , j }] == 1)
49 continue ;
50 for ( int k = 0; k < sym ; k ++) {
51 a = transition_table [{ i , k }];
52 b = transition_table [{ j , k }];
53 if ( a > b ) {
54 int t = a ;
55 a = b;
56 b = a;
57 }
58 else if ( a == b )
59 continue ;
60 if ( min_table [{ a , b }] == 1) {
61 update = true ;
62 // cout < <i < <" " < <j < < endl ;
63 min_table [{ i , j }] = 1;
64 break ;
65 }
66
67 }
68 }
69 count ++;
70 } while ( update ) ;
71 cout < < count < < endl ;
72 /* for ( auto it = min_table . begin () ; it != min_table . end () ; it
++) {
73 cout < <"( " < < it - > first . first < <" ," < < it - > first . second < <" ) :
" < < it - > second < < endl ;
74 } */
75 set < int > unmerged_states ;
76 vector < set < int > > merged_states ;
77 for ( int i = 0; i < states ; i ++)
78 unmerged_states . insert ( i ) ;
79 bool found ;
80 for ( auto it = min_table . begin () ; it != min_table . end () ; it ++) {
81 if ( it - > first . first == it - > first . second )
82 continue ;
83 if ( it - > second == 1)
84 continue ;

48
85 int a = it - > first . first ;
86 int b = it - > first . second ;
87 found = false ;
88 if ( unmerged_states . find ( a ) != unmerged_states . end () )
89 unmerged_states . erase ( a ) ;
90 if ( unmerged_states . find ( b ) != unmerged_states . end () )
91 unmerged_states . erase ( b ) ;
92 for ( auto jt = merged_states . begin () ; jt != merged_states .
end () ; jt ++) {
93 if ( jt - > find ( b ) != jt - > end () ) {
94 jt - > insert ( a ) ;
95 found = true ;
96 break ;
97 }
98 if ( jt - > find ( a ) != jt - > end () ) {
99 jt - > insert ( b ) ;
100 found = true ;
101 break ;
102 }
103 }
104 if (! found )
105 merged_states . push_back ({ a , b }) ;
106 }
107 cout < <" The final minimised states are \ n ";
108 for ( auto it = unmerged_states . begin () ; it != unmerged_states .
end () ; it ++)
109 cout < <* it < <" ";
110 cout < < endl ;
111 for ( auto it = merged_states . begin () ; it != merged_states . end () ;
it ++) {
112 for ( auto jt = it - > begin () ; jt != it - > end () ; jt ++)
113 cout < <* jt < <" ";
114 cout < < endl ;
115 }
116 cout < <" Minimised Transition table \ n ";
117 for ( auto it = unmerged_states . begin () ; it != unmerged_states .
end () ; it ++) {
118 for ( int j = 0; j < sym ; j ++) {
119 int end = transition_table [{* it , j }];
120 if ( unmerged_states . find ( end ) != unmerged_states . end () ) {
121 cout < <"[ " < <* it < <" ] - - -" < < symbols [ j ] < <" - - - - > [ " < <
end < <" ]" < < endl ;
122 }
123 else
124 {
125 for ( auto kt = merged_states . begin () ; kt !=
merged_states . end () ; kt ++) {
126 if ( kt - > find ( end ) != kt - > end () ) {

49
127 cout < <"[ " < <* it < <" ] - - - -" < < symbols [ j
] < <" - - - >[ ";
128 printSet (* kt ) ;
129 cout < <"]" < < endl ;
130 }
131 }
132 }
133

134 }
135 }
136 for ( auto it = merged_states . begin () ; it != merged_states . end () ;
it ++) {
137 for ( int j = 0; j < sym ; j ++) {
138 int start = *( it - > begin () ) ;
139 int end = transition_table [{ start , j }];
140 if ( unmerged_states . find ( end ) != unmerged_states . end () ) {
141 cout < <"[ ";
142 printSet (* it ) ;
143 cout < <" ] - - -" < < symbols [ j ] < <" - - - - > [ " < < end < <" ]" < <
endl ;
144 }
145 else
146 {
147 for ( auto kt = merged_states . begin () ; kt !=
merged_states . end () ; kt ++) {
148 if ( kt - > find ( end ) != kt - > end () ) {
149 cout < <"[ ";
150 printSet (* it ) ;
151 cout < <" ] - - - -" < < symbols [ j ] < <" - - - >[ ";
152 printSet (* kt ) ;
153 cout < <"]" < < endl ;
154 }
155 }
156 }
157 }
158 }
159 }

1 \ subsection { OUTPUT }
2 \ begin { frame }{} Enter number of states :
3 6
4 Enter number of symbols :
5 2
6 Enter symbols :
7 0 1
8 Enter the transitions for state 0 and symbol 0: 3
9 Enter the transitions for state 0 and symbol 1: 1
10 Enter the transitions for state 1 and symbol 0: 2

50
11 Enter the transitions for state 1 and symbol 1: 5
12 Enter the transitions for state 2 and symbol 0: 2
13 Enter the transitions for state 2 and symbol 1: 5
14 Enter the transitions for state 3 and symbol 0: 0
15 Enter the transitions for state 3 and symbol 1: 4
16 Enter the transitions for state 4 and symbol 0: 2
17 Enter the transitions for state 4 and symbol 1: 5
18 Enter the transitions for state 5 and symbol 0: 5
19 Enter the transitions for state 5 and symbol 1: 5
20 Enter the number of final states :
21 3
22 1 2 4
23 2
24 The final minimised states are
25 5
26 0 3
27 1 2 4
28 Minimised Transition table
29 [ 5 ] - - -0 - - - - > [ 5 ]
30 [ 5 ] - - -1 - - - - > [ 5 ]
31 [ 0 3 ] - - - -0 - - - >[ 0 3 ]
32 [ 0 3 ] - - - -1 - - - >[ 1 2 4 ]
33 [ 1 2 4 ] - - - -0 - - - >[ 1 2 4 ]
34 [ 1 2 4 ] - - -1 - - - - > [ 5 ]
35
36 \ end { frame }

7.6 RESULT
The programm implemented successfullly

51
8 OPERATOR PRECEDENCE PARSOR
8.1 AIM
Write program to find Operator Precedence Parser

8.2 INPUT AND OUTPUT


Given the precedence table

8.3 THEORY
A grammar that is generated to define the mathematical operators is called
operator grammar with some restrictions on grammar. An operator
precedence grammar is a context-free grammar that has the property that
no production has either an empty right-hand side (null productions) or two
adjacent non-terminals in its right-hand side. An operator precedence parser
is a one of the bottom-up parser that interprets an operator- precedence
grammar. This parser is only used for operator grammars. Ambiguous
grammars are not allowed in case of any parser except operator precedence
parser. There are two methods for determining what precedence relations
should hold between a pair of terminals:

8.4 ALGORITHM
1 1. Use the conventional associativity and precedence of operator .
2 2. The second method of selecting operator - precedence relations is
first to construct an
3 unambiguous grammar for the language , a grammar that reflects the

correct
4 associativity and precedence in its parse trees .
5 3. This parser relies on the following three precedence relations :
[U+FFFD]
6 a[U+FFFD]b This means a yields precedence to b .
[U+FFFD]
7 a[U+FFFD]b This means a takes precedence over b .
[U+FFFD]
8 a[U+FFFD]b This means a has precedence as b .

8.5 PROGRAMM
1
2 include < stdio .h >
3 # include < string .h >
4
5 char * input ;

52
6 int i =0;
7 char lasthandle [6] , stack [50] , handles [][5]={") E (" ," E * E " ," E + E " ," i " ," E
^ E "};
8 //( E ) becomes ) E ( when pushed to stack
9
10 int top =0 , l ;
11 char prec [9][9]={
12

13 /* input */
14
15 /* stack + - * / ^ i ( ) $ */
16
17 /* + */ ’>’, ’ > ’ , ’ < ’ , ’ < ’ , ’ < ’ , ’ < ’ , ’ < ’ , ’ > ’ , ’ > ’ ,
18

19 /* - */ ’>’, ’ > ’ , ’ < ’ , ’ < ’ , ’ < ’ , ’ < ’ , ’ < ’ , ’ > ’ , ’ > ’ ,


20
21 /* * */ ’>’, ’ > ’ , ’ > ’ , ’ > ’ , ’ < ’ , ’ < ’ , ’ < ’ , ’ > ’ , ’ > ’ ,
22
23 /* / */ ’>’, ’ > ’ , ’ > ’ , ’ > ’ , ’ < ’ , ’ < ’ , ’ < ’ , ’ > ’ , ’ > ’ ,
24

25 /* ^ */ ’>’, ’ > ’ , ’ > ’ , ’ > ’ , ’ < ’ , ’ < ’ , ’ < ’ , ’ > ’ , ’ > ’ ,


26
27 /* i */ ’>’, ’ > ’ , ’ > ’ , ’ > ’ , ’ > ’ , ’e ’ , ’e ’ , ’ > ’ , ’ > ’ ,
28
29 /* ( */ ’<’, ’ < ’ , ’ < ’ , ’ < ’ , ’ < ’ , ’ < ’ , ’ < ’ , ’ > ’ , ’e ’ ,
30

31 /* ) */ ’>’, ’ > ’ , ’ > ’ , ’ > ’ , ’ > ’ , ’e ’ , ’e ’ , ’ > ’ , ’ > ’ ,


32
33 /* $ */ ’<’, ’ < ’ , ’ < ’ , ’ < ’ , ’ < ’ , ’ < ’ , ’ < ’ , ’ < ’ , ’ > ’ ,
34
35 };
36

37 int getindex ( char c )


38 {
39 switch ( c )
40 {
41 case ’+ ’: return 0;
42 case ’ - ’: return 1;
43 case ’* ’: return 2;
44 case ’/ ’: return 3;
45 case ’^ ’: return 4;
46 case ’i ’: return 5;
47 case ’( ’: return 6;
48 case ’) ’: return 7;
49 case ’$ ’: return 8;
50 }
51 }
52
53

53
54 int shift ()
55 {
56 stack [++ top ]=*( input + i ++) ;
57 stack [ top +1]= ’\0 ’;
58 }
59
60
61 int reduce ()
62 {
63 int i , len , found , t ;
64 for ( i =0; i <5; i ++) // selecting handles
65 {
66 len = strlen ( handles [ i ]) ;
67 if ( stack [ top ]== handles [ i ][0]&& top +1 >= len )
68 {
69 found =1;
70 for ( t =0; t < len ; t ++)
71 {
72 if ( stack [ top - t ]!= handles [ i ][ t ])
73 {
74 found =0;
75 break ;
76 }
77 }
78 if ( found ==1)
79 {
80 stack [ top - t +1]= ’ E ’;
81 top = top - t +1;
82 strcpy ( lasthandle , handles [ i ]) ;
83 stack [ top +1]= ’\0 ’;
84 return 1;// successful reduction
85 }
86 }
87 }
88 return 0;
89 }
90
91

92
93 void dispstack ()
94 {
95 int j ;
96 for ( j =0; j <= top ; j ++)
97 printf ("% c " , stack [ j ]) ;
98 }
99
100
101
102 void dispinput ()

54
103 {
104 int j ;
105 for ( j = i ;j < l ; j ++)
106 printf ("% c " ,*( input + j ) ) ;
107 }
108
109
110

111 void main ()


112 {
113 int j ;
114
115 input =( char *) malloc (50* sizeof ( char ) ) ;
116 printf ("\ nEnter the string \ n ") ;
117 scanf ("% s " , input ) ;
118 input = strcat ( input ," $ ") ;
119 l = strlen ( input ) ;
120 strcpy ( stack ," $ ") ;
121 printf ("\ nSTACK \ tINPUT \ tACTION ") ;
122 while (i <= l )
123 {
124 shift () ;
125 printf ("\ n ") ;
126 dispstack () ;
127 printf ("\ t ") ;
128 dispinput () ;
129 printf ("\ tShift ") ;
130 if ( prec [ getindex ( stack [ top ]) ][ getindex ( input [ i ]) ]== ’ > ’)
131 {
132 while ( reduce () )
133 {
134 printf ("\ n ") ;
135 dispstack () ;
136 printf ("\ t ") ;
137 dispinput () ;
138 printf ("\ tReduced : E - >% s " , lasthandle ) ;
139 }
140 }
141 }
142
143 if ( strcmp ( stack ," $E$ ") ==0)
144 printf ("\ nAccepted ;") ;
145 else
146 printf ("\ nNot Accepted ;") ;
147 }

8.6 OUTPUT

55
1
2

3 Enter the string


4 i*i+i
5
6 STACK INPUT ACTION
7 $i * i + i$ Shift
8 $E * i + i$ Reduced : E - > i
9 $E * i + i$ Shift
10 $E * i + i$ Shift
11 $E * E + i$ Reduced : E - > i
12 $E + i$ Reduced : E - > E * E
13 $E + i$ Shift
14 $E + i $ Shift
15 $E + E $ Reduced : E - > i
16 $E $ Reduced : E - > E + E
17 $E$ Shift
18 $E$ Shift

8.7 RESULT
The programm implemented successfullly

56
9 FIRST AND FOLLOW
9.1 AIM
Write program to find First and Follow

9.2 INPUT AND OUTPUT


Given the precedence table

9.3 THEORY
Each time a predictive parser makes a decision, it needs to determine which
production rule to apply to the leftmost non-terminal in an intermediate form,
based on the next terminal (i.e. the lookahead symbol).This is the significance of
the FIRST sets: they tell you when a nonterminal can produce the lookahead
symbol as the beginning of a statement, so that it can be matched away and
reduce the input. FOLLOW covers the possibility that the leftmost non-terminal
can disappear, so that the lookahead symbol is not actually a part of what we’re
presently expand-ing, but rather the beginning of the next construct. This is the
significance of the FOLLOW sets: they tell you when a non-terminal can hand
you the lookahead symbol at the beginning of a statement by disappearing.
Choosing productions that give epsilon doesn’t reduce the input string, but you
still have to make a rule for when the parser needs to take them, and the
appropriate conditions are found from the FOLLOW set of the troublesome
non-terminal.

9.4 ALGORITHM
1 1. FOLLOW ( S ) = { $ }
2 2. If A -> pBq is a production , where p , B and q are any grammar
symbols , then everything in FIRST ( q ) except [U+FFFD]
is in FOLLOW ( B ) .
3 3. If A - > pB is a production , then everything in FOLLOW ( A ) is in
FOLLOW ( B ) .
4 4. If A - > pBq is a production and FIRST ( q ) contains [U+FFFD]
,
5 then FOLLOW ( B ) contains { FIRST ( q )[U+FFFD]
[U+FFFD]
} U FOLLOW ( A )

9.5 PROGRAMM
1
2 # include < stdio .h >
3 # include < math .h >
4 # include < string .h >

57
5 # include < ctype .h >
6 # include < stdlib .h >
7 int n , m =0 ,p , i =0 , j =0;
8 char a [10][10] , f [10];
9 void follow ( char c ) ;
10 void first ( char c ) ;
11 int main () {
12

13
14 int i , z ;
15 char c , ch ;
16 // clrscr () ;
17 printf (" Enter the no of prooductions :\ n ") ;
18 scanf ("% d " ,& n ) ;
19 printf (" Enter the productions :\ n ") ;
20 for ( i =0; i < n ; i ++)
21 scanf ("% s % c " , a [ i ] ,& ch ) ;
22 do {
23 m =0;
24 printf (" Enter the elemets whose fisrt & follow is to be found :") ;
25 scanf ("% c " ,& c ) ;
26 first ( c ) ;
27 printf (" First (% c ) ={" , c ) ;
28 for ( i =0; i < m ; i ++)
29 printf ("% c " , f [ i ]) ;
30 printf ("}\ n ") ;
31 strcpy (f ," ") ;
32 // flushall () ;
33 m =0;
34 follow ( c ) ;
35 printf (" Follow (% c ) ={" , c ) ;
36 for ( i =0; i < m ; i ++)
37 printf ("% c " , f [ i ]) ;
38 printf ("}\ n ") ;
39 printf (" Continue (0/1) ?") ;
40 scanf ("% d % c " ,&z ,& ch ) ;
41 } while ( z ==1) ;
42 return (0) ;
43 }
44 void first ( char c )
45 {
46 int k ;
47 if (! isupper ( c ) )
48 f [ m ++]= c ;
49 for ( k =0; k < n ; k ++)
50 {
51 if ( a [ k ][0]== c )
52 {
53 if ( a [ k ][2]== ’ $ ’)

58
54 follow ( a [ k ][0]) ;
55 else if ( islower ( a [ k ][2]) )
56 f [ m ++]= a [ k ][2];
57 else first ( a [ k ][2]) ;
58 }
59 }
60 }
61 void follow ( char c )
62 {
63 if ( a [0][0]== c )
64 f [ m ++]= ’ $ ’;
65 for ( i =0; i < n ; i ++)
66 {
67 for ( j =2; j < strlen ( a [ i ]) ; j ++)
68 {
69 if ( a [ i ][ j ]== c )
70 {
71 if ( a [ i ][ j +1]!= ’\0 ’)
72 first ( a [ i ][ j +1]) ;
73 if ( a [ i ][ j +1]== ’\0 ’ && c != a [ i ][0])
74 follow ( a [ i ][0]) ;
75 }
76 }
77 }
78 }

9.6 OUTPUT
1 Enter the no of prooductions :
2 2
3 Enter the productions :
4 i*i
5 i+i
6 Enter the elemets whose fisrt & follow is to be found :1
7 First (1) ={1}
8 Follow (1) ={}
9 Continue (0/1) ?1
10 Enter the elemets whose fisrt & follow is to be found :1
11 First (1) ={1}

9.7 RESULT
The programm implemented successfullly

59
10 RECURSIVE DESCENDT PARSER
10.1 AIM
Construct Recursive Descent Parser for a given language

10.2 INPUT AND OUTPUT


E-¿E*E E-¿(E) E-¿(id)

10.3 THEORY
Recursive descent is a top-down parsing technique that constructs the parse
tree from the top and the input is read from left to right. It uses procedures
for every terminal and non-terminal entity. This parsing technique
recursively parses the input to make a parse tree, which may or may not
require back-tracking. But the grammar associated with it (if not left
factored)cannot avoid back-tracking. A form of recursive-descent parsing
that does not require any back-tracking is known as predictive parsing. This
parsing technique is regarded recursive as it uses context-free grammar
which is recursive in nature. Recursive descent with backtracking is a
technique that determines which production to use by trying each
production in turn. Recursive descent with backtracking is not limited to
LL(k) grammars, but is not guaranteed to terminate unless the grammar is
LL(k). Even when they terminate, parsers that use recursive descent with
backtracking may require exponential time.

10.4 ALGORITHM
1 1 One parse method per non - terminal symbol
2 2 A non - terminal symbol on the right - hand side of a rewrite
rule
3 leads to a call to the parse method for that non - terminal
4 3 A terminal symbol on the right - hand side of a rewrite rule
leads to
5 " consuming " that token from the input token string
6 4 | in the CFG leads to " if - else " in the parser

10.5 PROGRAMM
1

2 # include < stdio .h >

60
3 # include < ctype .h >
4 # include < string .h >
5
6 void Tprime () ;
7 void Eprime () ;
8 void E () ;
9 void check () ;
10 void T () ;
11
12
13 char expression [10];
14 int count , flag ;
15
16 int main ()
17 {
18 count = 0;
19 flag = 0;
20 printf ("\ nEnter an Algebraic Expression :\ t ") ;
21 scanf ("% s " , expression ) ;
22 E () ;
23 if (( strlen ( expression ) == count ) && ( flag == 0) )
24 {
25 printf ("\ nThe Expression % s is Valid \ n " , expression ) ;
26 }
27 else
28 {
29 printf ("\ nThe Expression % s is Invalid \ n " , expression ) ;
30 }
31 }
32
33 void E ()
34 {
35 T () ;
36 Eprime () ;
37 }
38
39 void T ()
40 {
41 check () ;
42 Tprime () ;
43 }
44
45 void Tprime ()
46 {
47 if ( expression [ count ] == ’* ’)
48 {
49 count ++;
50 check () ;
51 Tprime () ;

61
52 }
53 }
54
55 void check ()
56 {
57 if ( isalnum ( expression [ count ]) )
58 {
59 count ++;
60 }
61 else if ( expression [ count ] == ’( ’)
62 {
63 count ++;
64 E () ;
65 if ( expression [ count ] == ’) ’)
66 {
67 count ++;
68 }
69 else
70 {
71 flag = 1;
72 }
73 }
74 else
75 {
76 flag = 1;
77 }
78 }
79
80 void Eprime ()
81 {
82 if ( expression [ count ] == ’+ ’)
83 {
84 count ++;
85 T () ;
86 Eprime () ;
87 }
88 }

10.6 OUTPUT

62
10.7 RESULT
The programm is implemented successfullly

63
11 SHIFT REDUCE PARSER
11.1 AIM
Construct a shift reduce parser for a given language

11.2 INPUT AND OUTPUT


E-¿E*E E-¿(E) E-¿(id)

11.3 THEORY
Shift-reduce parsing attempts to construct a parse tree for an input string
beginning at the leaves and working up towards the root. In other words, it
is a process of reducing (opposite of deriving a symbol using a production
rule) a string w to the start symbol of a grammar. At every (reduction)
step, a particular substring matching the RHS of a production rule is
replaced by the symbol on the LHS of the production. A general form of
shift-reduce parsing is LR (scanning from Left to right and using Right most
derivation in reverse) parsing, which is used in a number of automatic parser
generators like Yacc, Bison, etc. A handle of a string is a substring that
matches the RHS of a production and whose reduction to the non-terminal
(on the LHS of the production) represents one step along the reverse of a
rightmost derivation toward reducing to the start symbol. The set of prefixes
of right sentential forms that can appear on the stack of a shift-reduce parser
are called viable prefixes. It is always possible to add terminal symbols to
the end of a viable prefix to obtain a right-sentential form.

11.4 ALGORITHM
1 loop forever :
2 2 for top - of - stack symbol , s , and next input symbol , a case
3 action of T [ s , a ]
4 3 shift x : ( x is a STATE number )
5 4 push a , then x on the top of the stack and
6 5 advance ip to point to the next input symbol .
7 6 reduce y : ( y is a PRODUCTION number )
8 7 Assume that the production is of the form
9 8 A == > beta
10 9 pop 2 * | beta | symbols of the stack . At this
11 10 point the top of the stack should be a state number ,
12 11 says
[U+FFFD]
, push A , then goto of T[U+FFFD]
s[ , A ] ( a state number )
13 12 on the top of the stack . Output the production

64
14 13 A == > beta .
15 14 accept :
16 15 return --- a successful parse .
17 16 default :
18 17 error --- the input string is not in the language .

11.5 PROGRAMM
1
2 # include < stdio .h >
3 # include < stdlib .h >
4 # include < string .h >
5 int z = 0 , i = 0 , j = 0 , c = 0;
6 char a [16] , ac [20] , stk [15] , act [10];
7 void check ()
8 {
9 strcpy ( ac ," REDUCE TO E -> ") ;
10 for ( z = 0; z < c ; z ++)
11 {
12 if ( stk [ z ] == ’4 ’)
13 {
14 printf ("% s4 " , ac ) ;
15 stk [ z ] = ’E ’;
16 stk [ z + 1] = ’\0 ’;
17
18 printf ("\ n$ % s \ t % s$ \ t " , stk , a ) ;
19 }
20 }
21 for ( z = 0; z < c - 2; z ++)
22 {
23 if ( stk [ z ] == ’2 ’ && stk [ z + 1] == ’E ’ &&
24 stk [ z + 2] == ’2 ’)
25 {
26 printf ("% s2E2 " , ac ) ;
27 stk [ z ] = ’E ’;
28 stk [ z + 1] = ’\0 ’;
29 stk [ z + 2] = ’\0 ’;
30 printf ("\ n$ % s \ t % s$ \ t " , stk , a ) ;
31 i = i - 2;
32 }
33 }
34 for ( z =0; z <c -2; z ++)
35 {
36 if ( stk [ z ] == ’3 ’ && stk [ z + 1] == ’E ’ &&
37 stk [ z + 2] == ’3 ’)
38 {
39 printf ("% s3E3 " , ac ) ;

65
40 stk [ z ]= ’E ’;
41 stk [ z + 1]= ’\0 ’;
42 stk [ z + 1]= ’\0 ’;
43 printf ("\ n$ % s \ t % s$ \ t " , stk , a ) ;
44 i = i - 2;
45 }
46 }
47 return ;
48 }
49 int main ()
50 {
51 printf (" GRAMMAR is -\ nE - >2 E2 \ nE - >3 E3 \ nE - >4\ n ") ;
52 strcpy (a ,"32423") ;
53 c = strlen ( a ) ;
54 strcpy ( act ," SHIFT ") ;
55 printf ("\ nstack \ t input \ t action ") ;
56 printf ("\ n$ \ t % s$ \ t " , a ) ;
57 for ( i = 0; j < c ; i ++ , j ++)
58 {
59 printf ("% s " , act ) ;
60 stk [ i ] = a [ j ];
61 stk [ i + 1] = ’\0 ’;
62 a [ j ]= ’ ’;
63 printf ("\ n$ % s \ t % s$ \ t " , stk , a ) ;
64 check () ;
65 }
66 check () ;
67 if ( stk [0] == ’E ’ && stk [1] == ’\0 ’)
68 printf (" Accept \ n ") ;
69 else
70 printf (" Reject \ n ") ;
71 }

66
11.6 OUTPUT

11.7 RESULT
The programm is implemented successfullly

67
12 INTERMEDIATE CODE GENERATOR
12.1 AIM
Implement Intermediate code generation for simple expressions

12.2 INPUT AND OUTPUT


a+b*c

12.3 THEORY
Postfix Notation – The ordinary (infix) way of writing the sum of a and b is
with operator in the middle : a + b The postfix notation for the same
expression places the operator at the right end as ab +. In general, if e1 and
e2 are any postfix expressions, and + is any binary operator, the result of
applying + to the values denoted by e1 and e2 is postfix notation by e1e2 +.
No parentheses are needed in postfix notation because the position and arity
(number of arguments) of the operators permit only one way to decode a
postfix expression. In postfix notation the operator follows the operand.
Example – The postfix representation of the expression (a – b) * (c + d) +
(a – b) is : ab – cd + *ab -+. Read more: Infix to Postfix Three-Address
Code – A statement involving no more than three references(two for
operands and one for result) is known as three address statement. A
sequence of three address statements is known as three address code. Three
address statement is of the form x = y op z , here x, y, z will have address
(memory location). Sometimes a statement might contain less than three
references but it is still called three address statement. Example – The three
address code for the expression a + b * c + d : T 1 = b * c T 2 = a + T 1
T 3 = T 2 + d T 1 , T 2 , T 3 are temporary variables. Syntax Tree –
Syntax tree is nothing more than condensed form of a parse tree. The
operator and keyword nodes of the parse tree are moved to their parents and
a chain of single productions is replaced by single link in syntax tree the
internal nodes are operators and child nodes are operands. To form syntax
tree put parentheses in the expression, this way it’s easy to recognize which
operand should come first. Example – x = (a + b * c) / (a – b * c)

12.4 ALGORITHM
1 Tasks of lexical analyzer :
2 step 1:

68
3 Reads string of characters as input
4 Identify lexemes
5 Send the tokens to Syntax analyzer to convert into syntax trees .
6 step 2:
7 Remove white spaces .
8 step 3:
9 Swap x with successor
10 Remembers all the line numbers to report the line number in case of
error

12.5 PROGRAMM
1
2 # include < stdio .h >
3 # include < ctype .h >
4 # include < string .h >
5

6 void Tprime () ;
7 void Eprime () ;
8 void E () ;
9 void check () ;
10 void T () ;
11

12
13 char expression [10];
14 int count , flag ;
15
16 int main ()
17 {
18 count = 0;
19 flag = 0;
20 printf ("\ nEnter an Algebraic Expression :\ t ") ;
21 scanf ("% s " , expression ) ;
22 E () ;
23 if (( strlen ( expression ) == count ) && ( flag == 0) )
24 {
25 printf ("\ nThe Expression % s is Valid \ n " , expression ) ;
26 }
27 else
28 {
29 printf ("\ nThe Expression % s is Invalid \ n " , expression ) ;
30 }
31 }
32
33 void E ()
34 {
35 T () ;

69
36 Eprime () ;
37 }
38
39 void T ()
40 {
41 check () ;
42 Tprime () ;
43 }
44
45 void Tprime ()
46 {
47 if ( expression [ count ] == ’* ’)
48 {
49 count ++;
50 check () ;
51 Tprime () ;
52 }
53 }
54
55 void check ()
56 {
57 if ( isalnum ( expression [ count ]) )
58 {
59 count ++;
60 }
61 else if ( expression [ count ] == ’( ’)
62 {
63 count ++;
64 E () ;
65 if ( expression [ count ] == ’) ’)
66 {
67 count ++;
68 }
69 else
70 {
71 flag = 1;
72 }
73 }
74 else
75 {
76 flag = 1;
77 }
78 }
79
80 void Eprime ()
81 {
82 if ( expression [ count ] == ’+ ’)
83 {
84 count ++;

70
85 T () ;
86 Eprime () ;
87 }
88 }

12.6 OUTPUT

12.7 RESULT
The programm is implemented successfullly

71
13 CONSTANT PROPAGATION
13.1 AIM
Implement a program to perform constant propagation.

13.2 INPUT AND OUTPUT


= 3 -a +a b t1 +a c t2 +t1 t2 t3

13.3 THEORY
Some compilers perform constant propagation within basic blocks; some
compilers perform constant propagation in more complex control flow. Some
compilers perform constant propagation for integer constants, but not
floating-point constants. Few compilers perform constant propagation
through bitfield assignments. Few compilers perform constant propagation
for address constants through pointer assignments.

13.4 ALGORITHM
1 1. Initialization : assign initial values to the program[U+FFFD]s
variables [x7[U+FFFD]0, y7[U+FFFD]0, z7[U+FFFD]0]
2 2. z = 3 , change the value of z [x7[U+FFFD]0, y7[U+FFFD]0, z7[U+FFFD]3]
3 3. x = 1 , change the value of x [x7[U+FFFD]1, y7[U+FFFD]0, z7[U+FFFD]3]
4 4. while ( x >0) , at this point we havex7[U+FFFD]1so we have no choice but
tenter the loop .
5 5. if ( x = 1) , indeed this is the case , so the algorithm only
follows thethenbranch
6 6. y = 7 , change the value of x [x7[U+FFFD]1, y7[U+FFFD]7, z7[U+FFFD]3]
7 7. x = 3 , change the value of x [x7[U+FFFD]3, y7[U+FFFD]7, z7[U+FFFD]3]
8 8. print y , at this point we currently have [x7[U+FFFD]3, y7[U+FFFD]7, z7[U+FFFD]3] .
We havenow completed our first iteration of the loop and we
return to th ewhile statem ent .
9 9. while ( x >0) , from our initial iteration we have at this program
point [x7[U+FFFD]1, y7[U+FFFD]0, z7[U+FFFD]3] , but now we have [x7[U+FFFD]3, y7[U+FFFD]7,
z7[U+FFFD]3] . The stateat this point should have been [x 7U+FFFD] {1 ,3} ,
[U+FFFD] {0 ,7} , z7[U+FFFD]3] . Since werepresent states in a conservative
7
y
way we get [x 7U+FFFD]> , y[U+FFFD]> , z7[U+FFFD]3] Again we enter the loop , but
7
now sincexis non - constant we will executeboth branches of the if
statement .
10 10. First , we follow thethenbranch . We note that on that pathxis 1 ,
we get [x7[U+FFFD]1, y7[U+FFFD]7, z7[U+FFFD]3]
11 11. Continuing down that pathx = 3 and by the time we reach the print
state - ment we get [x7[U+FFFD]3, y7[U+FFFD]7, z7[U+FFFD]3]

72
12 12. We go back to theelsebranch were we have [x 7U+FFFD]> , y7[U+FFFD]7, z7[U+FFFD]3]
13 13. Following that path as well , by the time we reach the print
statement wehave [x7[U+FFFD]3, y7[U+FFFD]7, z7[U+FFFD]3]
14 14. Termination , since both paths lead to the same environment in
the printstatement , and since this environment is the same as
the one calculated onour previous journey through that point in
the program the algorithm termi - nates .

13.5 PROGRAMM
1 # include < stdio .h >
2 # include < string .h >
3 # include < ctype .h >
4
5 void input () ;
6 void output () ;
7 void change ( int p , char * res ) ;
8 void constant () ;
9 struct expr
10 {
11 char op [2] , op1 [5] , op2 [5] , res [5];
12 int flag ;
13 } arr [10];
14 int n ;
15 void main ()
16 {
17
18 input () ;
19 constant () ;
20 output () ;
21
22 }
23 void input ()
24 {
25 int i ;
26 printf ("\ n \ nEnter the maximum number of expressions : ") ;
27 scanf ("% d " ,& n ) ;
28 printf ("\ nEnter the input : \ n ") ;
29 for ( i =0; i < n ; i ++)
30 {
31 scanf ("% s " , arr [ i ]. op ) ;
32 scanf ("% s " , arr [ i ]. op1 ) ;
33 scanf ("% s " , arr [ i ]. op2 ) ;
34 scanf ("% s " , arr [ i ]. res ) ;
35 arr [ i ]. flag =0;
36 }
37 }

73
38 void constant ()
39 {
40 int i ;
41 int op1 , op2 , res ;
42 char op , res1 [5];
43 for ( i =0; i < n ; i ++)
44 {
45 if ( isdigit ( arr [ i ]. op1 [0]) && isdigit ( arr [ i ]. op2 [0]) ||
46
47 strcmp ( arr [ i ]. op ,"=") ==0)
48 {
49 op1 = atoi ( arr [ i ]. op1 ) ;
50 op2 = atoi ( arr [ i ]. op2 ) ;
51 op = arr [ i ]. op [0];
52 switch ( op )
53 {
54 case ’+ ’:
55 res = op1 + op2 ;
56 break ;
57 case ’ - ’:
58 res = op1 - op2 ;
59 break ;
60 case ’* ’:
61 res = op1 * op2 ;
62 break ;
63 case ’/ ’:
64 res = op1 / op2 ;
65 break ;
66 case ’= ’:
67 res = op1 ;
68 break ;
69 }
70 sprintf ( res1 ,"% d " , res ) ;
71 arr [ i ]. flag =1;
72 change (i , res1 ) ;
73 }
74 }
75 }
76 void output ()
77 {
78 int i =0;
79 printf ("\ nOptimized code is : ") ;
80 for ( i =0; i < n ; i ++)
81 {
82 if (! arr [ i ]. flag )
83 {
84 printf ("\ n % s % s % s % s " , arr [ i ]. op , arr [ i ]. op1 , arr [ i ]. op2 , arr [ i ]. res ) ;
85 }
86 }

74
87 }
88 void change ( int p , char * res )
89 {
90 int i ;
91 for ( i = p +1; i < n ; i ++)
92 {
93 if ( strcmp ( arr [ p ]. res , arr [ i ]. op1 ) ==0)
94 strcpy ( arr [ i ]. op1 , res ) ;
95 else if ( strcmp ( arr [ p ]. res , arr [ i ]. op2 ) ==0)
96 strcpy ( arr [ i ]. op2 , res ) ;
97 }
98 }

13.6 OUTPUT

13.7 RESULT
The programm is implemented successfullly

75
[12pt]article [utf8]inputenc graphics
listings natbib graphicx [a4paper, total=6in, 8in]geometry xcolor

14 LOOP UNROLLING
14.1 Aim
Write a program to implement loop unrolling.

14.2 THEORY
Loop unrolling is a loop transformation technique that helps to optimize the
execution time of a program. We basically remove or reduce iterations. Loop
unrolling increases the program’s speed by eliminating loop control instruction
and loop test instructions.
Advantages:
1. Increases program efficiency.
2. Reduces loop overhead.
3. If statements in loop are not dependent on each other, they can be executed
in parallel.
Disadvantages:
1. Increased program code size, which can be undesirable.
2. Possible increased usage of register in a single iteration to store temporary
variables which may reduce performance.
3. Apart from very small and simple codes, unrolled loops that contain
branches are even slower than recursions

14.3 ALGORITHM
1. Input program file.
2. Read from file l.
3. If l is a looping statement, goto 5.
4. Print l into output file, goto 2.
5. Set i = initial value, f = final value.

76
6. Read line from l.
7. If l is end of loop, go to 10.
8. Print l to buffer b.
9. Goto step 6.
10. While(i=f), repeat step 11.
11. Output buffer b to output file.
12. goto step 2.

14.4 PROGRAMM
1
2 # include < bits / stdc ++. h >
3 # include < stdio .h >
4 using namespace std ;
5
6 void func ( string buffer , int count )
7 {
8 for ( int i =0; i < count ; i ++)
9 {
10 cout < < buffer < < endl ;
11 }
12 }
13 int main ()
14 {
15 fstream file ;
16 ofstream f2 ;
17 string word , t , q , filename ;
18 filename = " file . txt " ;
19
20 file . open ( filename . c_str () ) ;
21 while ( file >> word )
22 {
23 if ( word [0]== ’# ’)
24 {
25 cout << word << endl ;
26 }
27 else
28 {
29 if ( word == " for " )
30 {
31 file >> word ;
32 file >> word ;
33 file >> word ;

77
34 file >> word ;
35 file >> word ;
36
37 int a ;
38 stringstream g ( word ) ;
39 g >> a ;
40 file >> word ;
41 file >> word ;
42 file >> word ;
43 string comp = word ;
44
45
46 file >> word ;
47 int limit ;
48 stringstream e ( word ) ;
49 e >> limit ;
50 file >> word ;
51 file >> word ;
52 file >> word ;
53 file >> word ;
54 file >> word ;
55 string buffer ( " " ) ;
56
57 while ( word != " } " )
58 {
59 buffer . append ( " " ) ;
60 buffer . append ( word ) ;
61 file >> word ;
62 }
63 if ( comp == " <" )
64 func ( buffer , limit - a ) ;
65 else if ( comp == " <= " )
66 func ( buffer , limit - a +1) ;
67 else if ( comp == " >= " )
68 func ( buffer , a - limit +1) ;
69 else if ( comp == " >" )
70 func ( buffer , a - limit ) ;
71 }
72 else
73 {
74 cout << word < < endl ;
75 }
76 }
77 }
78 return 0;
79 }

78
14.5 OUTPUT

14.6 RESULT
The program for loop unrolling was implemented using cpp and output was
verified.

79

Potrebbero piacerti anche