CD_LAB

Download as pdf or txt
Download as pdf or txt
You are on page 1of 43

1

Experiment 1 Date
1.1 AIM: Write a lex program whose output is same as input.
DESCRIPTION:
Lex is a program that generates lexical analyzer. It is used with YACC parser generator. The
lexical analyzer is a program that transforms an input stream into a sequence of tokens. It reads
the input stream and produces the source code as output through implementing the lexical
analyzer in the C program.
A Lex program is separated into three sections by %% delimiters. The formal of Lex source is as
follows:
{ definitions }
%%
{ rules }
%%
{ user subroutines }
CODE:
%%
. ECHO;
%%
int yywrap(void) {
return 1;
}
int main(void) {
yylex();
return 0;
}
OUTPUT:

Roll No 2 1 A 9 1 A 6 1 2 0
2

1.2AIM: Write a lex program which removes white spaces from its input file.
DESCRIPTION:
Lex is a program that generates lexical analyzer. It is used with YACC parser generator. The
lexical analyzer is a program that transforms an input stream into a sequence of tokens. It reads
the input stream and produces the source code as output through implementing the lexical
analyzer in the C program.
The function of Lex is as follows:
1. Firstly lexical analyzer creates a program lex.1 in the Lex language. Then Lex compiler
runs the lex.1 program and produces a C program lex.yy.c.
2. Finally C compiler runs the lex.yy.c program and produces an object program a.out.
3. a.out is lexical analyzer that transforms an input stream into a sequence of tokens.

 Definitions include declarations of constant, variable and regular definitions.


 Rules define the statement of form p1 {action1} p2 {action2}....pn {action}.Where pi
describes the regular expression and action1 describes the actions what action the lexical
analyzer should take when pattern pi matches a lexeme.
 User subroutines are auxiliary procedures needed by the actions. The subroutine can be
loaded with the lexical analyzer and compiled separately.
CODE:
%%
[ ] {};
. ECHO;
%%

int yywrap(void) {
return 1;
}

int main(void) {
yylex();
return 0;
}
OUTPUT:

Roll No 2 1 A 9 1 A 6 1 2 0
3

Experiment 2 Date
2.1AIM: Write a lex program to identify the patterns in the input file.
DESCRIPTION:
%{ and %} sections: These sections are optional and can be used to declare variables or include
header files needed for your program.
%% delimiters: These delimit the beginning and end of the pattern rules section.
Pattern rules:
 [ \t\n]+: Matches one or more whitespace characters (spaces, tabs, and newlines). You can
choose to do nothing or print a message for these.
 [a-zA-Z][a-zA-Z0-9]*: Matches identifiers that start with a letter (uppercase or lowercase)
and can be followed by any number of letters or digits. You can print or store the
identifier.
 [0-9]+: Matches one or more digits, representing integers. You can print or store the
integer.

CODE:
%{
#include<stdio.h>
%}
%%
["int""char""for""if""while""then""return""do"] {printf("keyword : %s\n");}
[*%+\-] {printf("Operator : %s ", yytext);}
[(){};] {printf("Special Character: %s\n", yytext);}
[0-9]+ {printf("Constant : %s\n", yytext);}
[a-zA-Z_][a-zA-Z0-9_]* {printf("Valid Identifier is : %s\n", yytext);}
^[^a-zA-Z_] {printf("Invalid Indentifier \n");}
%%

int yywrap() {
return 1; // Indicate end of input
}

int main(void) {
yylex();
return 0;
}

input.txt
=======
12345

Roll No 2 1 A 9 1 A 6 1 2 0
4

Hello
world
123abc456
!@#$%
This is a test file.

OUTPUT :

Roll No 2 1 A 9 1 A 6 1 2 0
5

2.2AIM:Design a lexical analyzer for given language and the lexical analyzer should ignore
redundant spaces, tabsand new lines.
DESCRIPTION:
Tools like Lex (often used with C) or JFlex (used with Java) can simplify the development of
lexical analyzers by providing a framework for defining states, transitions, and token types.
These tools generate code that handles the low-level details of character streams and state
management.
Components:
 Character Stream: The input for the lexical analyzer is a stream of characters from the
source code file.
 Finite State Automata: The core component, FSA is a machine with a set of states and
transitions between them. The transitions are triggered by the next character in the input
stream.
 Transition Function: This function determines the next state to move to based on the
current state and the next character in the input stream.
 Tokens: The output of the lexical analyzer is a sequence of tokens. Each token represents
a specific category (type) like identifier, integer, keyword, operator, etc., along with the
actual lexeme (the matched character sequence).
CODE:
%{
#include<stdio.h>
int i=0,id=0;
%}

%%
[#].*[<].*[>]\n {}
[ \t\n]+ {}
\/\/.*\n {}
\/\*(.*\n)*.*\*\/ {}
auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|re
gister|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while
{printf("token : %d < keyword , %s >\n",++i,yytext);}
[+\-\*\/%<>] {printf("token : %d < operator , %s >\n",++i,yytext);}
[();{}] {printf("token : %d < special char , %s >\n",++i,yytext);}
[0-9]+ {printf("token : %d < constant , %s >\n",++i,yytext);}
[a-zA-Z_][a-zA-Z0-9_]* {printf("token : %d <Id%d ,%s >\n",++i,++id,yytext);}
^[^a-zA-Z_] {printf("ERROR Invaild token %s \n",yytext);}
%%

int yywrap() {
return 1; // Indicate end of input
}
int main(void) {

Roll No 2 1 A 9 1 A 6 1 2 0
6

yylex();
return 0;
}

OUTPUT :

Roll No 2 1 A 9 1 A 6 1 2 0
7

Experiment 3 Date
3.1AIM:Simulate First and Follow of a Grammar.
DESCRIPTION:
RULES FOR COMPUTATION OF FIRST FUNCTION
1) If X is a terminal, then first (x) = {x}
Ex: for any terminal symbol a,
First (a) = {a}
2) If X→E is a production, then add€ to FIRST (x)
For a production rule X→ €
FIRST (E) = {E}
3) If X is a non-teminal and X→PQR then FIRST(X) = FIRST(P)
→ If FIRST (P) Contains €, then
FIRST(X)=(FIRST(P)-{€})U FIRST(QR)
RULES FOR COMPUTATION OF FOLLOW FUNCTION
→ follow (alpha) is a set of terminal symbols thatappear immediately to the righto x.
1) for the start symbols,place $ in FOLLOW(s) if no S symbol in RHS.
Ex:
S->aBDh
B→ cC
→ Follow (s) ={$}
2)For any production rule A→ alphaB,
FOLLOW(B) = FOLLOW(A)
Ех:
S→ aBDh
B → cC
folLow (s) = {$}
.therefore,FOLLOW (C) = FOLLOW (B)
3) For any production rule-A → alphaBbeta
If € not belong FIRIT(B), then FoLLOW (B) = FIRST (Beta),
FOLLOW (B) = FOLLOW (A))
If € € fIRST(B) , then
FOLLOW(B) ={FIRST (Beta) - €}U foLLOW(A)

Roll No 2 1 A 9 1 A 6 1 2 0
8

CODE:
#include<stdio.h>
#include<string.h>
#include<ctype.h> // Include <ctype.h> for isupper and islower functions
int n, m = 0, p, i = 0, j = 0;
char a[10][10], f[10];
void follow(char c);
void first(char c);
int main() {
int i, z;
char c, ch;
printf("enter the no. of productions:");
scanf("%d", &n);
printf("enter the productions(epsilon = $):\n");
for(i = 0; i< n; i++)
scanf("%s%c", a[i], &ch);
do {
m = 0;
printf("enter the element whose FIRST & FOLLOW is to be found:");
scanf(" %c", &c); // Added a space before %c to consume newline character
first(c);
printf("FIRST(%c) = {", c);
for(i = 0; i< m; i++)
printf("%c", f[i]);
printf("}\n");
follow(c);
printf("FOLLOW(%c) = {", c);
for(; i< m; i++)
printf("%c", f[i]);
printf("}\n");
printf("do you want to continue(0/1)?");
scanf("%d%c", &z, &ch);
} while(z == 1); // Changed z = 1 to z == 1

Roll No 2 1 A 9 1 A 6 1 2 0
9

return 0;
}
void follow(char c) {
if(a[0][0] == c) // Changed = to == for comparison
f[m++] = '$';
for(i = 0; i< n; i++) {
for(j = 2; j <strlen(a[i]); j++) {
if(a[i][j] == c) { // Changed = to == for comparison
if(a[i][j+1] != '\0') first(a[i][j+1]);
if(a[i][j+1] == '\0' &&c != a[i][0]) follow(a[i][0]);
}
}
}
}
void first(char c) {
int k;
if(!(isupper(c)) && c != '$') // Added condition to check if c is not $
f[m++] = c;
for(k = 0; k < n; k++) {
if(a[k][0] == c) {
if(a[k][2] == '$') // Changed = to == for comparison
follow(a[k][0]);
else if(islower(a[k][2]))
f[m++] = a[k][2];
else
first(a[k][2]);
}
}
}

Roll No 2 1 A 9 1 A 6 1 2 0
10

OUTPUT:

Roll No 2 1 A 9 1 A 6 1 2 0
11

3.2AIM:Implement the lexical analyzer using JLex, flex or lex or other lexical analyzer
generating tools
DESCRIPTION:
 Define Patterns:
Start by identifying the different patterns you want to identify in the input file.
 Identifiers: Sequences of letters, digits, and underscores starting with a letter.
 Keywords: Reserved words with specific meanings in the language (e.g., "if", "else",
"for").
 Operators: Symbols used for mathematical or logical operations (e.g., "+", "-", "*", "/").
 Literals: Values like integers, floating-point numbers, strings, and characters.
 Comments: Lines or sections of code ignored by the compiler.
 Use Regular Expressions:
 JFlex/Flex/Lex use regular expressions to define patterns for matching characters or
sequencesin the input stream.
 Customize and Extend:
 Add more regular expressions to match other language-specific patterns.
 Modify the actions within the curly braces ({}) to perform different actions for each
token type (e.g., storing the identifier in a symbol table, converting an integer to a
numerical value).
 Handle comments (e.g., single-line or multi-line comments) using appropriate regular
expressions and discard them.
 Compile and Run:
 Save the code as a .l or .flex file depending on the tool you're using.
 Use the JFlex/Flex command-line tool to generate the lexical analyzer source code (e.g.,
jflexfilename.l or flex filename.l).
 Compile the generated code along with your main program and run it with the input file
as an argument.
CODE:
%{
#include<stdio.h>
int i=0,id=0;
%}

%%
[#].*[<].*[>]\n {}
[ \t\n]+ {}
\/\/.*\n {}
\/\*(.*\n)*.*\*\/ {}
auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|re
gister|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while
{printf("token : %d < keyword , %s >\n",++i,yytext);}
[+\-\*\/%<>] {printf("token : %d < operator , %s >\n",++i,yytext);}
[();{}] {printf("token : %d < special char , %s >\n",++i,yytext);}
[0-9]+ {printf("token : %d < constant , %s >\n",++i,yytext);}

Roll No 2 1 A 9 1 A 6 1 2 0
12

[a-zA-Z_][a-zA-Z0-9_]* {printf("token : %d <Id%d ,%s >\n",++i,++id,yytext);}


^[^a-zA-Z_] {printf("ERROR Invaild token %s \n",yytext);}
%%

int yywrap() {
return 1; // Indicate end of input
}

int main(void) {
yylex();
return 0;
}

OUTPUT:

Roll No 2 1 A 9 1 A 6 1 2 0
13

Experiment 4 Date
4.1AIM: Develop an operator precedence parser for a given language.
DESCRIPTION:
A grammar that is used to define mathematical operators is called an operator grammar or
operator precedence grammar.
Operator precedence grammar is kinds of shift reduce parsing method. It is applied to a small
class of operator grammars.A grammar is said to be operator precedence grammar if it has two
properties:
 No R.H.S. of any production has a∈.
 No two non-terminals are adjacent.
Operator precedence can only established between the terminals of the grammar. It ignores the
non-terminal.There are the three operator precedence relations:
 a ⋗ b means that terminal "a" has the higher precedence than terminal "b".
 a ⋖ b means that terminal "a" has the lower precedence than terminal "b".
 a ≐ b means that the terminal "a" and "b" both have same precedence.
CODE:
#include<stdio.h>
#include<string.h>
char stack[20];
int top = -1;
void push(char item) {
if (top >= 19) {
printf("STACK OVERFLOW\n");
return;
}
stack[++top] = item;
}
char pop() {
if (top <= -1) {
printf("STACK UNDERFLOW\n");
return '\0';
}
char c = stack[top--];
printf("Popped element: %c\n", c);
return c;

Roll No 2 1 A 9 1 A 6 1 2 0
14

}
char TOS() {
if (top <= -1) {
printf("STACK EMPTY\n");
return '\0';
}
return stack[top];
}
int convert(char item) {
switch (item) {
case 'i': return 0;
case '+': return 1;
case '*': return 2;
case '$': return 3;
default: return -1; // Invalid character
}
}
int main() {
char pt[4][4] = {
{'-', '>', '>', '>'},
{'<', '>', '<', '>'},
{'<', '>', '>', '>'},
{'<', '<', '<', '1'}
};
char input[20];
int lkh = 0;
printf("Enter input with $ at the end: ");
scanf("%s", input);
push('$');
while (lkh<= strlen(input)) {
if (TOS() == '$' && input[lkh] == '$') {
printf("SUCCESS\n");
return 1;

Roll No 2 1 A 9 1 A 6 1 2 0
15

} else if (convert(TOS()) != -1 && convert(input[lkh]) != -1 &&


pt[convert(TOS())][convert(input[lkh])] == '<') {
push(input[lkh]);
printf("Push: %c\n", input[lkh]);
lkh++;
} else {
pop();
}
}
printf("FAILURE\n");
return 0;
}
OUTPUT:

Roll No 2 1 A 9 1 A 6 1 2 0
16

4.2AIM: Construct a recursive descent parser for an expression


DESCRIPTION:
Parsing is the process to determine whether the start symbol can derive the program or not. If the
Parsing is successful then the program is a valid program otherwise the program is invalid.
There are generally two types of Parsers: Top-Down Parsers and Bottom-Up Parsers
Top-Down Parsers:
 In this Parsing technique we expand the start symbol to the whole program.
 Recursive Descent and LL parsers are the Top-Down parsers.
Recursive Descent Parser:
 The process of parsing is frequently employed in language processing and compiler
design. It is founded on the idea that a difficult problem can be broken down into simpler
problems and then solved recursively. Starting with a top-level nonterminal symbol, the
parsing process proceeds by recursively expanding non terminals until it reaches terminal
symbols.
 It is a kind of Top-Down Parser. A top-down parser builds the parse tree from the top to
down, starting with the start non-terminal. A Predictive Parser is a special case of
Recursive Descent Parser, where no Back Tracking is required.
 By carefully writing a grammar means eliminating left recursion and left factoring from
it, the resulting grammar will be a grammar that can be parsed by a recursive descent
parser.

CODE:
#include<stdio.h>
#include<ctype.h>
#include<string.h>
void Tp();
void Ep();
void E();
void T();
void check();
int count, flag;
char expr[10];
int main() {
count = 0;
flag = 0;
printf("\nEnter an Algebraic Expression:\t");
scanf("%s", expr);
E();

Roll No 2 1 A 9 1 A 6 1 2 0
17

if ((strlen(expr) == count) && (flag == 0))


printf("\nThe expression %s is valid\n", expr);
else
printf("\nThe expression %s is invalid\n", expr);
return 0;
}
void E() {
T();
Ep();
}
void T() {
check();
Tp();
}
void Tp() {
if (expr[count] == '*') {
count++;
check();
Tp();
}
}
void check() {
if (isalnum(expr[count]))
count++;
else if (expr[count] == '(') {
count++;
E();
if (expr[count] == ')')
count++;
else
flag = 1;
}
else

Roll No 2 1 A 9 1 A 6 1 2 0
18

flag = 1;
}
void Ep() {
if (expr[count] == '+') {
count++;
T();
Ep();
}
}
OUTPUT:

Roll No 2 1 A 9 1 A 6 1 2 0
19

Experiment 5 Date
AIM: Construct a LL(1) parser for an expression
DESCRIPTION:
LL(1) Parsing: Here the 1st L represents that the scanning of the Input will be done from the
Left to Right manner and the second L shows that in this parsing technique, we are going to use
the Left most Derivation Tree. And finally, the 1 represents the number of look-ahead, which
means how many symbols are you going to see when you want to make a decision.
Essential conditions to check first are as follows:
 The grammar is free from left recursion.
 The grammar should not be ambiguous.
 The grammar has to be left factored in so that the grammar is deterministic grammar.
CODE:
#include<stdio.h>
#include<string.h>
int stack[20], top = -1;

void push(int item) {


if (top >= 20) {
printf("Stack Overflow\n");
return;
}
stack[++top] = item;
}
int pop() {
if (top <= -1) {
printf("Stack Underflow\n");
return -1; // Return -1 to indicate underflow
}
return stack[top--];
}
char convert(int item) {
switch (item) {
case 0: return 'E';
case 1: return 'e';

Roll No 2 1 A 9 1 A 6 1 2 0
20

case 2: return 'T';


case 3: return 't';
case 4: return 'F';
case 5: return 'i';
case 6: return '+';
case 7: return '*';
case 8: return '(';
case 9: return ')';
case 10: return '$';
default: return '?'; // Error case
}
}
int main() {
int m[10][10], i, j, k;
char ips[20];
int ip[10], a, b, t;
// Fill in the parsing table
m[0][0] = m[0][3] = 21;
m[1][1] = 621;
m[1][4] = m[1][5] = -2;
m[2][0] = m[2][3] = 43;
m[3][1] = m[3][4] = m[3][5] = -2;
m[3][2] = 743;
m[4][0] = 5;
m[4][3] = 809;
printf("\nEnter the input string with $ at the end (e.g., i+i*i$):\n");
scanf("%s", ips);
for (i = 0; i<strlen(ips); i++) {
switch (ips[i]) {
case 'E': k = 0; break;
case 'e': k = 1; break;
case 'T': k = 2; break;
case 't': k = 3; break;

Roll No 2 1 A 9 1 A 6 1 2 0
21

case 'F': k = 4; break;


case 'i': k = 5; break;
case '+': k = 6; break;
case '*': k = 7; break;
case '(': k = 8; break;
case ')': k = 9; break;
case '$': k = 10; break;
default: printf("Invalid input\n"); return 1; // Exit if input is invalid
}
ip[i] = k;
}
ip[i] = -1;
push(10); // Push $ onto stack
push(0); // Push 0 (start symbol) onto stack
i = 0;
printf("\tStack\t\tInput\n");
while (1) {
printf("\t");
for (j = 0; j <= top; j++)
printf("%c", convert(stack[j]));
printf("\t\t");
for (k = i; ip[k] != -1; k++)
printf("%c", convert(ip[k]));
printf("\n");
if (stack[top] == ip[i]) {
if (ip[i] == 10) {
printf("\t\tSuccess\n");
return 0;
} else {
top--;
i++;
}
} else if (stack[top] <= 4 && stack[top] >= 0) {

Roll No 2 1 A 9 1 A 6 1 2 0
22

a = stack[top];
b = ip[i] - 5;
t = m[a][b];
top--;
while (t > 0) {
push(t % 10);
t = t / 10;
}
} else {
printf("Error\n");
return 1;
}
}
return 0;
}
OUTPUT:

Roll No 2 1 A 9 1 A 6 1 2 0
23

Experiment 6 Date
6.1AIM: Write a program to perform loop unrolling.
DESCRIPTION:
Loop unrolling is a loop transformation technique that aims at improving the performance of a
program at the expense of code size. When a loop is unrolled, instructions that control the loop
are eliminated (full unroll) or reduced (by unroll factor) and replaced with multiple copies of the
loop body, thereby reducing the computational overhead but increasing the size of the code.
 Increases program efficiency.
 Reduces loop overhead.
 If statements in loop are not dependent on each other, they can be executed in parallel.
CODE:
#include<stdio.h>
#define TOGETHER (8)
int main(void)
{
int i = 0;
int entries = 50;
int repeat;
int left = 0;
repeat = (entries / TOGETHER);
left = (entries % TOGETHER);
while (repeat--)
{
printf("process(%d)\n", i );
printf("process(%d)\n", i + 1);
printf("process(%d)\n", i + 2);
printf("process(%d)\n", i + 3);
printf("process(%d)\n", i + 4);
printf("process(%d)\n", i + 5);
printf("process(%d)\n", i + 6);
printf("process(%d)\n", i + 7);
i += TOGETHER;
}
switch (left)

Roll No 2 1 A 9 1 A 6 1 2 0
24

{
case 7 :printf("process(%d)\n", i + 6);
case 6 :printf("process(%d)\n", i + 5);
case 5 :printf("process(%d)\n", i + 4);
case 4 :printf("process(%d)\n", i + 3);
case 3 :printf("process(%d)\n", i + 2);
case 2 :printf("process(%d)\n", i + 1);
case 1 :printf("process(%d)\n", i);
case 0 : ;
}
}
OUTPUT:

Roll No 2 1 A 9 1 A 6 1 2 0
25

6.2 AIM: Write a program for constant propagation


DESCRIPTION:
 Constant Propagation is one of the local code optimization technique in Compiler
Design. It can be defined as the process of replacing the constant value of variables in the
expression.
 In simpler words, we can say that if some value is assigned a known constant, than we
can simply replace the that value by constant.
 Constants assigned to a variable can be propagated through the flow graph and can be
replaced when the variable is used.
 Constant propagation is executed using reaching definition analysis results in compilers,
which means that if reaching definition of all variables have same assignment which
assigns a same constant to the variable, then the variable has a constant value and can be
substituted with the constant.

CODE:
#include<stdio.h>
#include<string.h>
#include<ctype.h>
void input();
void output();
void change(int p,char *res);
void constant();
struct expr{
char op[2],op1[5],op2[5],res[5];
int flag;
}arr[10];
int n;
void main(){
input();
constant();
output();
}
void input(){
int i;
printf("\n\nEnter the maximum number of expressions : ");
scanf("%d",&n);

Roll No 2 1 A 9 1 A 6 1 2 0
26

printf("\nEnter the input : \n");


for(i=0;i<n;i++){
scanf("%s",arr[i].op);
scanf("%s",arr[i].op1);
scanf("%s",arr[i].op2);
scanf("%s",arr[i].res);
arr[i].flag=0;
}
}
void constant(){
int i;
int op1,op2,res;
char op,res1[5];
for(i=0;i<n;i++){
if(isdigit(arr[i].op1[0]) &&isdigit(arr[i].op2[0]) || strcmp(arr[i].op,"=")==0){
/*if both digits, store them in variables*/
op1=atoi(arr[i].op1);
op2=atoi(arr[i].op2);
op=arr[i].op[0];
switch(op){
case '+':
res=op1+op2;
break;
case '-':
res=op1-op2;
break;
case '*':
res=op1*op2;
break;
case '/':
res=op1/op2;
break;
case '=':

Roll No 2 1 A 9 1 A 6 1 2 0
27

res=op1;
break;
}
sprintf(res1,"%d",res);
arr[i].flag=1;
change(i,res1);
}
}
}
void output(){
int i=0;
printf("\nOptimized code is : ");
for(i=0;i<n;i++){
if(!arr[i].flag)
printf("\n%s %s %s %s",arr[i].op,arr[i].op1,arr[i].op2,arr[i].res);
}
}
void change(int p,char *res){
int i;
for(i=p+1;i<n;i++){
if(strcmp(arr[p].res,arr[i].op1)==0)
strcpy(arr[i].op1,res);
else if(strcmp(arr[p].res,arr[i].op2)==0)
strcpy(arr[i].op2,res);
}
}

Roll No 2 1 A 9 1 A 6 1 2 0
28

OUTPUT:

Roll No 2 1 A 9 1 A 6 1 2 0
29

Experiment 7 Date
AIM: Develop Class Diagram and Object diagram using Rational Rose for ATM application.
DESCRIPTION: Class diagrams are a type of UML (Unified Modeling Language) diagram
used in software engineering to visually represent the structure and relationships of classes
within a system i.e. used to construct and visualize object-oriented systems.
UML Class Notation:

 Class Name:
The name of the class is typically written in the top compartment of the class box and is
centered and bold.
 Attributes:
Attributes, also known as properties or fields, represent the data members of the class. They
are listed in the second compartment of the class box and often include the visibility (e.g.,
public, private) and the data type of each attribute.
 Methods:
Methods, also known as functions or operations, represent the behavior or functionality of
the class. They are listed in the third compartment of the class box and include the visibility
(e.g., public, private), return type, and parameters of each method.
 Visibility Notation:
Visibility notations indicate the access level of attributes and methods. Common visibility
notations include:
 + for public (visible to all classes)
 - for private (visible only within the class)
 # for protected (visible to subclasses)
 ~ for package or default visibility (visible to classes in the same package)
STEPS TO DRAW:
 Identify Classes:
Start by identifying the classes in your system. A class represents a blueprint for objects
and should encapsulate related attributes and methods.
 List Attributes and Methods:
For each class, list its attributes (properties, fields) and methods (functions, operations).
Include information such as data types and visibility (public, private, protected).
 Identify Relationships:

Roll No 2 1 A 9 1 A 6 1 2 0
30

Determine the relationships between classes. Common relationships include associations,


aggregations, compositions, inheritance, and dependencies. Understand the nature and
multiplicity of these relationships.
 Create Class Boxes:
Draw a rectangle (class box) for each class identified. Place the class name in the top
compartment of the box. Divide the box into compartments for attributes and methods.
 Add Attributes and Methods:
Inside each class box, list the attributes and methods in their respective compartments. Use
visibility notations (+ for public, – for private, # for protected, ~ for package/default).
 Draw Relationships:
Draw lines to represent relationships between classes. Use arrows to indicate the direction
of associations or dependencies. Different line types or notations may be used for various
relationships.
 Label Relationships:
Label the relationships with multiplicity and role names if needed. Multiplicity indicates
the number of instances involved in the relationship, and role names clarify the role of each
class in the relationship.
 Review and Refine:
Review your class diagram to ensure it accurately represents the system’s structure and
relationships. Refine the diagram as needed based on feedback and requirements.
 Use Tools for Digital Drawing:
While you can draw class diagrams on paper, using digital tools can provide more
flexibility and ease of modification. UML modeling tools, drawing software, or even
specialized diagramming tools can be helpful.
OUTPUT:

Roll No 2 1 A 9 1 A 6 1 2 0
31

Experiment 8 Date
AIM: Develop Use case diagrams and elaborate Use case descriptions & scenarios for ATM
application.
DESCRIPTION: A Use Case Diagram is a type of Unified Modeling Language (UML)
diagram that represents the interaction between actors (users or external systems) and a system
under consideration to accomplish specific goals. It provides a high-level view of the system’s
functionality by illustrating the various ways users can interact with it.
Use Case Diagram Notations:

 Actors:
Actors are external entities that interact with the system. These can include users, other
systems, or hardware devices. In the context of a Use Case Diagram, actors initiate use cases
and receive the outcomes.
 Use Case:
Use cases are like scenes in the play. They represent specific things your system can do. In
the online shopping system, examples of use cases could be “Place Order,” “Track
Delivery,” or “Update Product Information”. Use cases are represented by ovals.
 System Boundary:
The system boundary is a visual representation of the scope or limits of the system you are
modeling. It defines what is inside the system and what is outside. The boundary helps to
establish a clear distinction between the elements that are part of the system and those that
are external to it.
STEPS TO DRAW:
 Identify Actors:
Determine who or what interacts with the system. These are your actors. They can be users,
other systems, or external entities.
 Identify Use Cases:
Identify the main functionalities or actions the system must perform. These are your use
cases. Each use case should represent a specific piece of functionality.
 Connect Actors and Use Cases:

Roll No 2 1 A 9 1 A 6 1 2 0
32

Draw lines (associations) between actors and the use cases they are involved in. This
represents the interactions between actors and the system.
 Add System Boundary:
Draw a box around the actors and use cases to represent the system boundary. This defines
the scope of your system.
 Define Relationships:
If certain use cases are related or if one use case is an extension of another, you can indicate
these relationships with appropriate notations.
 Review and Refine:
Step back and review your diagram. Ensure that it accurately represents the interactions and
relationships in your system. Refine as needed.
 Validate:
Share your use case diagram with stakeholders and gather feedback. Ensure that it aligns
with their understanding of the system’s functionality.
OUTPUT:

Roll No 2 1 A 9 1 A 6 1 2 0
33

Experiment 9 Date
AIM: Develop Detailed Sequence Diagrams / Communication diagrams for each use case
showing interactions among all the three-layer objects for ATM application.
DESCRIPTION: A sequence diagram is the most commonly used interaction diagram. It
simply depicts the interaction between the objects in a sequential order i.e. the order in which
these interactions occur.
Sequence Diagram Notations:

 Actors:
An actor in a UML diagram represents a type of role where it interacts with the system and
its objects.
 Lifelines:
A lifeline is a named element which depicts an individual participant in a sequence
diagram. So basically, each instance in a sequence diagram is represented by a lifeline.
Lifeline elements are located at the top in a sequence diagram.
 Messages:
Communication between objects is depicted using messages. The messages appear in a
sequential order on the lifeline.
 We represent messages using arrows.
 Lifelines and messages form the core of a sequence diagram.
STEPS TO DRAW:
 Identify the Scenario:
Understand the specific scenario or use case that you want to represent in the sequence
diagram. This could be a specific interaction between objects or the flow of messages in a
particular process.
 List the Participants:
Identify the participants (objects or actors) involved in the scenario. Participants can be
users, systems, or external entities.
 Define Lifelines:
Draw a vertical dashed line for each participant, representing the lifeline of each object
over time. The lifeline represents the existence of an object during the interaction.

Roll No 2 1 A 9 1 A 6 1 2 0
34

 Arrange Lifelines:
Position the lifelines horizontally in the order of their involvement in the interaction. This
helps in visualizing the flow of messages between participants.
 Add Activation Bars:
For each message, draw an activation bar on the lifeline of the sending participant. The
activation bar represents the duration of time during which the participant is actively
processing the message.
 Draw Messages:
Use arrows to represent messages between participants. Messages flow horizontally
between lifelines, indicating the communication between objects.
 Include Return Messages:
If a participant sends a response message, draw a dashed arrow returning to the original
sender to represent the return message.
 Indicate Timing and Order:
Use numbers to indicate the order of messages in the sequence. You can also use vertical
dashed lines to represent occurrences of events or the passage of time.
 Include Conditions and Loops:
Use combined fragments to represent conditions (like if statements) and loops in the
interaction. This adds complexity to the sequence diagram and helps in detailing the control
flow.
 Consider Parallel Execution:
If there are parallel activities happening, represent them by drawing parallel vertical dashed
lines and placing the messages accordingly.
 Review and Refine:
Review the sequence diagram for clarity and correctness. Ensure that it accurately
represents the intended interaction. Refine as needed.
 Add Annotations and Comments:
Include any additional information, annotations, or comments that provide context or
clarification for elements in the diagram.
 Document Assumptions and Constraints:
If there are any assumptions or constraints related to the interaction, document them
alongside the diagram.
 Tools:
Use a UML modeling tool or diagramming software to create a neat and professional-
looking sequence diagram. These tools often provide features for easy editing,
collaboration, and documentation.

Roll No 2 1 A 9 1 A 6 1 2 0
35

OUTPUT:

Roll No 2 1 A 9 1 A 6 1 2 0
36

Experiment 10 Date
AIM: Develop sample diagrams for state chart diagrams for ATM application.
DESCRIPTION: A state diagram is used to represent the condition of the system or part of
the system at finite instances of time. It’s abehavioral diagram and it represents the behavior
using finite state transitions. State Machine diagrams are also referred to as State Machines
Diagrams and State-Chart Diagrams.
State Chart Diagram Notations:
 Initial State:
We use a black filled circle represent the initial state of a System or a Class.

 Transition:
We use a solid arrow to represent the transition or change of control
from one state to another. The arrow is labelled with the event which
causes the change in state.
 State:
We use a rounded rectangle to represent a state. A state represents the conditions or
circumstances of an object of a class at an instant of time.
 Fork:
We use a rounded solid rectangular bar to represent a Fork notation with incoming
arrow from the parent state and outgoing arrows towards the newly created states.
We use the fork notation to represent a state splitting into two or more concurrent
states.
 Join:
We use the join notation when two or more states concurrently converge into one
on the occurrence of an event or events.
 Self-transition:
There might be scenarios when the state of the object does not change upon the
occurrence of an event. We use self-transitions to represent such cases.
 Composite State:
We use a rounded rectangle to represent a composite state also. We represent a
state with internal activities using a composite state.
 Final State:
We use a filled circle within a circle notation to represent the final state in a state
machine diagram.
STEPS TO DRAW:
 Identify the System:
 Understand what your diagram is representing.

Roll No 2 1 A 9 1 A 6 1 2 0
37

 Whether it’s a machine, a process, or any object, know what different situations or
conditions it might go through.
 Identify Initial and Final States:
 Figure out where your system starts (initial state) and where it ends (final state).
 These are like the beginning and the end points of your system’s journey.
 Identify Possible States:
 Think about all the different situations your system can be in.
 These are like the various phases or conditions it experiences.
 Use boundary values to guide you in defining these states.
 Label Triggering Events:
 Understand what causes your system to move from one state to another.
 These causes or conditions are the events.
 Label each transition with what makes it happen.
 Draw the Diagram with appropriate notations:
 Now, take all this information and draw it out.
 Use rectangles for states, arrows for transitions, and circles or rounded rectangles for
initial and final states.
 Be sure to connect everything in a way that makes sense.

OUTPUT:

Roll No 2 1 A 9 1 A 6 1 2 0
38

Experiment 11 Date
AIM: Develop Detailed design using activity diagrams for ATM application.
DESCRIPTION: Activity Diagrams are used to illustrate the flow of control in a system and
refer to the steps involved in the execution of a use case. We can depict both sequential
processing and concurrent processing of activities using an activity diagram.
Activity Diagram Notations:

 Action Flow or Control flows:


Action flows or Control flows are also referred to as paths and edges. They are used to show
the transition from one activity state to another activity state.
 Decision node and Branching:
When we need to make a decision before deciding the flow of control, we use the decision
node. The outgoing arrows from the decision node can be labelled with conditions or guard
expressions. It always includes two or more output arrows.
 Guard:
A Guard refers to a statement written next to a decision node on an arrow sometimes within
square brackets.
 Merge or Merge Event:
Scenarios arise when activities which are not being executed concurrently have to be
merged. We use the merge notation for such scenarios.
 Swimlanes:
We use Swimlanes for grouping related activities in one column. Swimlanes group related
activities into one column or one row. Swimlanes can be vertical and horizontal. Swimlanes
are used to add modularity to the activity diagram.
 Time Event:
This refers to an event that stops the flow for a time; an hourglass depicts it. We can have a
scenario where an event takes some time to completed.

Roll No 2 1 A 9 1 A 6 1 2 0
39

STEPS TO DRAW:
 Identify the Initial State and Final States:
 This is like setting the starting point and ending point of a journey.
 Identify where your process begins (initial state) and where it concludes (final states).
 For example, if you are modelling a process for making a cup of tea, the initial state
could be “No tea prepared,” and the final state could be “Tea ready.”
 Identify the Intermediate Activities Needed:
 Think of the steps or actions required to go from the starting point to the ending point.
 These are the activities or tasks that need to be performed.
 Continuing with the tea-making, intermediate activities could include “Boil water,”
“Pour tea into a cup”.
 Identify the Conditions or Constraints:

 Consider the conditions or circumstances that might influence the flow of your process.
 These are the factors that determine when you move from one activity to another.
 Using the tea-making scenario, a condition could be “Water is boiled,” which triggers the
transition to the next activity.

 Draw the Diagram with Appropriate Notations:


Now, represent the identified states, activities, and conditions visually using the appropriate
symbols and notations in an activity diagram. This diagram serves as a visual map of your
process, showing the flow from one state to another.

Roll No 2 1 A 9 1 A 6 1 2 0
40

OUTPUT:

Roll No 2 1 A 9 1 A 6 1 2 0
41

Experiment 12 Date
AIM: Develop sample diagrams for other UML diagrams - component diagrams and
deployment diagrams for ATM application.
DESCRIPTION:
Component Diagram: Component Diagrams are used to show code modules of a system
in Unified Modeling Language (UML). They are generally used for modeling subsystems. It
represents how each and every component acts during execution and running of a syst em
program. The component diagram is used to explain working and behavior of various
components of a system and is static diagrams of UML.
Component Diagram Notations:

 A rectangle with the component's name


 A rectangle with the component icon
 A rectangle with the stereotype text and/or icon
 Interface:
 Provided interface symbols with a complete circle at their end represent an interface that
the component provides - this "lollipop" symbol is shorthand for a realization relationship
of an interface classifier.
 Required Interface symbols with only a
half circle at their end (a.k.a. sockets)
represent an interface that the component
requires (in both cases, the interface's name
is placed near the interface symbol itself).
Deployment Diagram: A Deployment Diagram illustrates how software architecture, designed
on a conceptual level, translates into the physical system architecture where the software will
run as nodes. It maps out the deployment of software components onto hardware nodes and
depicts their relationships through communication paths, enabling a visual representation of the
software’s execution environment across multiple nodes.
Deployment Diagram Notations:
 Component:
A component represents a modular and reusable part of a system, typically
implemented as a software module, class, or package. It encapsulates its behavior
and data and can be deployed independently.
 Artifact:
An artifact represents a physical piece of information or data that is used or
produced in the software development process. It can include source code
files, executables, documents, libraries, configuration files, or any other

Roll No 2 1 A 9 1 A 6 1 2 0
42

tangible item.
 Interface:
An interface defines a contract specifying the methods or operations that a
component must implement. It represents a point of interaction between different
components or subsystems.
 Node:
A node represents a physical or computational resource, such as a hardware device,
server, workstation, or computing resource, on which software components can be
deployed or executed.
STEPS TO DRAW:
Component Diagram:
 Decide on the purpose of the diagram.
 Add components to the diagram, grouping them within other components if appropriate.
 Add other elements to the diagram, such as classes, objects and interface.
 Add the dependencies between the elements of the diagram.
Deployment Diagram:
 Identify Components:
List all software parts and hardware devices that will be in the deployment diagram.
 Understand Relationships:
Figure out how these parts connect and work together.
 Gather Requirements:
Collect details about hardware, network setups, and any special rules for deployment.
 Draw Nodes and Components:
Start by drawing the hardware devices (nodes) and software parts (components) using
standard symbols roughly at first improvise it and draw the final one.
 Connect Nodes and Components:
Use lines or arrows to show how nodes and components are linked, indicating how they talk
to each other.
 Add Details:
Label everything clearly and include any extra info, like hardware specs or communication
protocols.
 Documentation:
Write down any important decisions or assumptions made while creating the diagram

Roll No 2 1 A 9 1 A 6 1 2 0
43

OUTPUT:
Component Diagram:

Deployment Diagram:

Roll No 2 1 A 9 1 A 6 1 2 0

You might also like