Ss&Os Lab Master Manual2020-21 - Ajiet
Ss&Os Lab Master Manual2020-21 - Ajiet
UNIVERSITY BELGAUM
AJIET
A J INSTITUTE OF ENGINEERING & TECHNOLOGY
University syllabus
SYSTEM SOFTWARE LABORATORY
(Subject Code: 18CSL66)
[As per Choice Based Credit System (CBCS) scheme, Effective from the academic year 2018-2019]
SEMESTER – VI
CREDITS – 02
Course objectives:
To make students familiar with Lexical Analysis and Syntax Analysis phases of Compiler
Design and implement programs on these phases using LEX & YACC
Tools and/or C/C++/Java
To enable students to learn different types of CPU scheduling algorithms used in Operating
system.
To make students able to implement memory management - page replacement and
Deadlock handling algorithms
Descriptions
Laboratory Experiments:
*, and /.
2. Develop, Implement and Execute a program using YACC tool to recognize all
strings ending with b preceded by n a’s using the grammar an b (note: input n value).
sentence: abba$
5. Design, develop and implement a C/Java program to generate the machine code
using Triples for the statement A = -B * (C +D) whose intermediate code in three-address form:
T1 = -B
T2 = C + D
T3 = T1 + T2
A = T3
6. a) Write a LEX program to eliminate comment lines in a C program and copy the
resulting program into a separate file.
b) Write YACC program to recognize valid identifier, operators and keywords in thegiven text (C
program) file.
Shortest remaining time and Round Robin (RR) scheduling algorithms. Experiment with different
quantum sizes for RR algorithm.
Course outcomes:
On the completion of this laboratory course, the students will be able to:
Utilize the skill of Regular expression for implementing and demonstrating a Lexical analysis
and Syntax analysis phases of compiler
Utilize the skill of CFG for implementing and demonstrating a machine code generation for the
given intermediate code.
Apply the knowledge on operating system to implement and demonstrate different process
scheduling algorithms
Apply the skill of process management to implement and demonstrate resource allocation
algorithms
Apply the skill of memory management to implement and demonstrate memory allocation (Page
replacement) algorithms
1. Engineering Knowledge
2. Problem Analysis
3. Design/Development of Solutions
4. Modern Tool Usage
1. All laboratory experiments (TEN no’s) are to be included for practical examination.
2. Students are allowed to pick one experiment from the lot.
Dept. of CSE,AJIET,Mangaluru Page 4
SS Lab 18CSL66
3. Strictly follow the instructions as printed on the cover page of answer script
4. Marks distribution: Procedure + Conduction + Viva Questions:20 + 50 +10 (80)
5. Change of experiment is allowed only once and marks allotted to the procedure part to be
made zero
Lex program
1. Open Terminal (ctrl+alt+T)
2. gedit filename.l
3. lex filename.l
4. cc lex.yy.c –ll
5. ./a.out
Yacc program
1. Open Terminal (ctrl+alt+T)
2. gedit filename.y
3. lex filename.l
4. yacc –d filename.y
5 cc lex.yy.c y.tab.c –ll
6. ./a.out
Translating the high level language program input into an equivalent machine
language program.
a) Assemblers. b) Compilers.
Assemblers are translators for the lower level assembly language of Computers. It translates program
written in assembly language to machine language.
A Compiler is a translator program that translates a program written in high level language into an
equivalent program in low level language.
The first phase of the compiler is called Lexical Analyzer or Scanner. It reads the input source and
divides the input into meaningful units. These units are called tokens. A token is a sub-string of the
source program that is to be treated as a single unit.
Example:
TOKENS:
Identifier(s): x
Dept. of CSE,AJIET,Mangaluru Page 7
SS Lab 18CSL66
Constants: 2, 3, 5.0
Operators: < , +, -
The Syntax Analyzer groups’ tokens together into syntactic structure called as expression. The
syntactic structure can be regarded as a tree called as parse trees.
For example, for the expression total = count + rate * 10 the parse tree can be generated as follows:
total +
count *
rate 10
The Semantic Analyzer determines the meaning of the source string. For example, meaning of the
Source string means matching of the parenthesis in the expression or checking the scope of operation
as shown below.
total +
count *
rate
int to float
10
Lexical analyzer is build using a tool called LEX. Input is given to LEX and lexical analyzer is
generated.
Lex is an UNIX utility. It is a program generator designed for lexical processing of character input
streams. Lex generates C code for lexical analyzer. It uses the patterns that match strings in the
input and converts the strings to tokens. Lex helps you by taking a set of descriptions of possible
tokens and producing a C routine, which we call a lexical analyzer.The token description that lex uses
are known as regular expressions.
%%
Rules section
%%
C code section
Code Section
Copied to the end of C code
%% is a delimiter to mark the beginning of the Rule section. The second %% is optional, but the first is required to mark the beginning of the
rules. The definitions and the code /subroutines are often omitted.
C code
It introduces any initial C program code we want copies into the final program. We surround the C
code with the special delimiters “%{“ and “%}”. Lex copies the material between %{ and %} directly
to the beginning of generated C file, so you may write any valid C code here. This is typically used for
defining file variables, and for prototypes of routines that are defined in the code segment.
For example
letter [a-zA-Z]
digit [0-9]
punct [,.:;!?]
Dept. of CSE,AJIET,Mangaluru Page 10
SS Lab 18CSL66
nonblank [ˆ \t]
Substitution line does not end with semicolon. This Substitution can be used in the rules section: one
could start a rule {letter} + {...
State definitions If a rule depends on context, it’s possible to introduce states and incorporate those in
the rules. A state definition looks like %s STATE, and by default a state INITIAL is already given. If
the application of a rule depends on context, there are a couple of ways of dealing with this. We
distinguish between ‘left state’ and ‘right state’, basically letting a rule depend on what comes before
or after the matched token.
Note that this section has to include the yywrap() function. Lex has a set of functions and variables
that are available to the user. One of them is yywrap. Typically, yywrap() is defined as shown in the
example below.
int main()
{
Dept. of CSE,AJIET,Mangaluru Page 11
SS Lab 18CSL66
yylex();
return 0;
}
int yywrap()
{
return 1;
}
where yylex is the parser that is built from the rules.
Lex variables
Yyin Of the type FILE*. This points to the current file being parsed by the lexer.
Yyout Of the type FILE*. This points to the location where the output of the lexer will
be written. By default, both yyin and yyout point to standard input and output.
Yytext The text of the matched pattern is stored in this variable (char*).
Yylineno Provides current line number information. (May or may not be supported by the
lexer.)
Lex functions
yylex() The function that starts the analysis. It is automatically generated by Lex.
yywrap() This function is called when end of file (or input) is encountered. If this
function returns 1, the parsing stops. So, this can be used to parse multiple
files. Code can be written in the third section, which will allow multiple
files to be parsed. The strategy is to make yyin file pointer (see the
preceding table) point to a different file until all the files are parsed. At the
end, yywrap() can return 1 to indicate end of parsing.
yyless(int n) This function can be used to push back all but first ‘n’ characters of the read
token.
yymore() This function tells the lexer to append the next token to the current token.
A-Z, 0-9, a-z Characters and numbers that form part of the pattern.
Character Meaning
Ex: {digit}
\ Used to escape meta characters. Also used to remove the special meaning
of characters as defined in this table.
^ Negation.
Regular Meaning
expression
Regular Meaning
expression
character from b to e.
[0-9] 0 or 1 or 2 or………9
-?[0-9]+ -1 or +1 or +2 …..
Variable (chars)+(number)*(chars)*(
number)*
2. 1 INTRODUCTION TO YACC
YACC provides a general tool for imposing structure on the input to a computer program. The
input specification is a collection of grammar rules. Each rule describes an allowable structure and
gives it a name. YACC prepares a specification of the input process.YACC generates a function to
control the input process. This function is called a parser.
The name is an acronym for “Yet Another Compiler Compiler”. YACC generates the code for
the parser in the C programming language. YACC was developed at AT& T for the Unix operating
system. YACC has also been rewritten for other languages, including Java, Ada.
The function parser calls the lexical analyzer to pick up the tokens from the input stream.
These tokens are organized according to the input structure rules .The input structure rule is called as
grammar. When one of the rule is recognized, then user code supplied for this rule ( user code is
action) is invoked. Actions have the ability to return values and makes use of the values of other
actions.
When we run YACC, it generates a parser in file y.tab.c and also creates an include file y.tab.h. To
obtain tokens, YACC calls yylex. Function yylex has a return type of int, and returns the token.
Values associated with the token are returned by lex in variable yylval.
Every YACC specification file consists of three sections. The declarations, Rules (of
grammars), programs. The sections are separated by double percent “%%” marks. The % is
generally used in YACC specification as an escape character.
The general format for the YACC file is very similar to that of the Lex file.
{definitions}
%%
{rules}
%%
{user subroutines}
%% is a delimiter to the mark the beginning of the Rule section
Definition Section
%union It defines the Stack type for the Parser. It is a union of various datas/structures/ Objects
%token These are the terminals returned by the yylex function to the YACC. A token can also have
type associated with it for good type checking and syntax directed translation. A type of a
token can be specified as %token <stack member>tokenName.
Ex: %token NAME NUMBER
%type The type of a non-terminal symbol in the Grammar rule can be specified with this. The
format is %type <stack member>non-terminal.
%no Specifies that there is no associatively of a terminal symbol.
assoc
%left Specifies the left associatively of a Terminal Symbol
%start Specifies the L.H.S non-terminal symbol of a production rule which should be taken as the
starting point of the grammar rules.
%prec Changes the precedence level associated with a particular rule to that of the following token
name or literal
Rules Section
The rules section simply consists of a list of grammar rules. A grammar rule has the form:
A: BODY
A represents a nonterminal name, the colon and the semicolon are YACC punctuation and BODY
represents names and literals. The names used in the body of a grammar rule may represent tokens or
nonterminal symbols. The literal consists of a character enclosed in single quotes.
Names representing tokens must be declared as follows in the declaration sections:
%token name1 name2…
Every name not defined in the declarations section is assumed to represent a nonterminal
symbol. Every non-terminal symbol must appear on the left side of at least one rule. Of all the no
terminal symbols, one, called the start symbol has a particular importance. The parser is designed to
recognize the start symbol. By default the start symbol is taken to be the left hand side of the first
grammar rule in the rules section.
With each grammar rule, the user may associate actions to be. These actions may return values,
and may obtain the values returned by the previous actions. Lexical analyzer can return values for tokens,
if desired. An action is an arbitrary C statement. Actions are enclosed in curly braces.
PROGRAM-1a
TITLE Write a LEX program to recognize valid arithmetic expression. Identifiers in the expression
could be only integers and operators could be + and *. Count the identifiers & operators present and
print them separately.
AIM To check the valid arithmetic expression and Count the identifiers & operators present.
DESCRIPTION
In this program we need to check whether inputted expression is valid or not, then we are counting the
number of identifiers and operator. Ex: (2+3) it is a valid expression with two identifiers and one
operator.
INPUT
Valid arithmetic expression
EXPECTED OUTPUT
a) Print given expression valid or invalid
b) Print the count of Identifier and Operator in the given expression.
Lex PROGRAM
%{
#include<stdio.h>
int identifiers=0,operators=0,braces=0,alpha=0,spaces=0;
%}
%%
[a-zA-Z] {alpha++;printf("\nAlphabet:");ECHO;}
[0-9]* {identifiers++;printf("\nIdentifier:");ECHO;}
[+\*] {operators++;printf("\nOperator:");ECHO;}
"(" {braces++;}
")" {braces--;}
[ ] {spaces++;}
. {;}
%%
void main()
{
printf("Enter the expression:");
Dept. of CSE,AJIET,Mangaluru Page 19
SS Lab 18CSL66
yylex();
if((braces==0) && (operators==identifiers-1) && alpha==0 && spaces==0)
{
printf("\nValid expression");
printf("\nNumber of operators:%d",operators);
printf("\nNumber of identifiers:%d\n",identifiers);
}
else
printf("\nInvalid expression");
printf("\n");
}
int yywrap()
{
return 1;
}
RESULT
Viva Questions
Define system software.
System software is computer software designed to operate the computer hardware and to provide a
platform for running application software. Eg: operating system, assembler, and loader.
Dept. of CSE,AJIET,Mangaluru Page 20
SS Lab 18CSL66
What is an Assembler?
Assembler for an assembly language, a computer program to translate between lower-level
representations of computer programs.
PROGRAM -1b
TITLE
Write YACC program to evaluate arithmetic expression involving operators: +, -,
*, and /
AIM
Evaluate arithmetic expression
DESCRIPTION
YACC cannot represent numbers as [0-9]+ nor easily obtain the corresponding value, nor can it easily
be used to ignore white space and comments. Therefore, we need to use both LEX and
YACC together; LEX for the simple parts (e.g. numbers, white space, comments) and YACC for more
complex parts (e.g. expressions).
y.tab.h gives LEX the names and type declarations etc. from YACC
yylval name used for values set in LEX e.g. yylval.a_number = atoi (yytext);
%token declare each grammar rule used by YACC that is recognised by LEX and give type of
value
INPUT
Arithmetic expression is given as input
EXPECTED OUTPUT
Evaluate result is printed
PROGRAM
Lex program
%{
#include"y.tab.h"
extern int yylval;
%}
%%
[0-9]+ {yylval=atoi(yytext);return NUM;}
[+\-\*\/] {return yytext[0];}
"(" {return yytext[0];}
")" {return yytext[0];}
"\n" {return ENTER;}
"." {return yytext[0];}
%%
int yywrap()
{
Dept. of CSE,AJIET,Mangaluru Page 22
SS Lab 18CSL66
return 1;
}
Yacc program
%{
#include<stdio.h>
#include<stdlib.h>
int yylex();
int yyerror();
%}
%token NUM ENTER
%left '+' '-'
%left '*' '/'
%%
input: expr ENTER {printf("Result is %d\n",$$);exit(0);}
expr: expr '+' expr {$$=$1+$3;}
|expr '-' expr {$$=$1-$3;}
|expr '*' expr {$$=$1*$3;}
|expr '/' expr {if($3==0) {printf("Divide by zero error");exit(0);}else $$=$1/$3;}
|'(' expr ')' {$$=$2;}
|NUM {$$=$1;}
;
%%
void main()
{
printf("Enter the expression\n");
yyparse();
}
int yyerror()
{
printf("Invalid expression\n");
return 1;
}
RESULT
Viva Questions
1. What is the Syntax of a Language?
The Rules which tells whether a string is a valid Program or not are called the Syntax.
PROGRAM-2
TITLE
Develop, Implement and Execute a program using YACC tool to recognize all strings ending with b
preceded by n a’s using the grammar an b (note: input n value).
AIM
INPUT
Input n value {n=0,1 ,2 ,3 etc b, ab, aab, aaab etc}
EXPECTED OUTPUT
Print the recognized string
PROGRAM
Lex Program
%{
#include"y.tab.h"
%}
%%
a {return A;}
b {return B;}
"\n" {return ENTER;}
. {printf("Invalid input");exit(0);}
%%
Dept. of CSE,AJIET,Mangaluru Page 25
SS Lab 18CSL66
int yywrap()
{
return 1;
}
Yacc program
%{
#include<stdio.h>
#include<stdlib.h>
int yylex();
int yyerror();
%}
%token A B ENTER
%%
input:S ENTER {printf("Correct grammar");exit(0);}
S:C B |B
C:A C|A
;
%%
void main()
{
printf("enter the string");
yyparse();
}
int yyerror()
{
printf("INVALID grammar");
return 1;
}
RESULT
Viva Questions
1.What is the Lexical Analysis?
The Function of a lexical Analyzer is to read the input stream representing the Source
program, one character at a time and to translate it into valid tokens.
PROGRAM-3
TITLE
Design, develop and implement YACC/C program to construct Predictive / LL(1) Parsing Table for
the grammar rules: A aBa , B bB | . Use this table to parse the
sentence: abba$.
AIM
To construct parsing Table and parse the given string
DESCRIPTION
The types of top-down parsing are depicted below:
Predictive Parser
Predictive parser is a recursive descent parser, which has the capability to predict which production is
to be used to replace the input string. The predictive parser does not suffer from backtracking.
To accomplish its tasks, the predictive parser uses a look-ahead pointer, which points to the next
input symbols. To make the parser back-tracking free, the predictive parser puts some constraints on
the grammar and accepts only a class of grammar known as LL(k) grammar
Predictive parsing uses a stack and a parsing table to parse the input and generate a parse tree. Both the
stack and the input contains an end symbol $ to denote that the stack is empty and the input is consumed.
The parser refers to the parsing table to take any decision on the input and stack element combination.
LL Parser
An LL Parser accepts LL grammar. LL grammar is a subset of context-free grammar but with some
restrictions to get the simplified version, in order to achieve easy implementation. LL grammar can be
implemented by means of both algorithms namely, recursive-descent or table-driven.
LL parser is denoted as LL(k). The first L in LL(k) is parsing the input from left to right, the second L
in LL(k) stands for left-most derivation and k itself represents the number of look aheads. Generally k
= 1, so LL(k) may also be written as LL(1)
INPUT
Enter the string
EXPECTED OUTPUT
Display the predictive table and Parsing of given string.
PROGRAM
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char prod[3][15]={"A->aBa","B->bB","B->@"};
i=1;
j=0;
printf("\nStack input");
printf("\n____________________________________________\n");
while(1)
{
if(stack[i]==s[j])
{//first if
i--;
j++;
if(stack[i]=='$' && s[j]=='$')
{//second if
printf("$$\nSuccess\n");
break;
}// second end if
else
if(stack[i]=='$' && s[j]!='$')
{//third if
printf("Error\n");
break;
}//end third if
display(i,j);
}//end first if
switch(stack[i])
{
case 'A':row=0;break;
case 'B':row=1;break;
}//end switch
switch(s[j])
{
case 'a':col=0;break;
case 'b':col=1;break;
case '$':col=2;break;
}// end switch
if(table[row][col][0]=='\0')
{
printf("\nError\n");
break;
}// end if
else if(table[row][col][0]=='@')
Dept. of CSE,AJIET,Mangaluru Page 31
SS Lab 18CSL66
{
i--;
display(i,j);
}//end elseif
else
{
for(k=size[row][col]-1;k>=0;k--)
{
stack[i]=table[row][col][k];
i++;
}
i--;
display(i,j);
}// end else
} //end while
}//end main
RESULT
Viva Questions
Are Lexical Analysis and Parsing two different Passes?
These two can form two different passes of a Parser. The Lexical analysis can store all the
recognized tokens in an intermediate file and give it to the Parser as an input. However it is more
convenient to have the lexical Analyzer as a co routine or a subroutine which the Parser calls
whenever it requires a token.
PROGRAM-4
TITLE
Design, develop and implement YACC/C program to demonstrate Shift Reduce Parsing technique for
the grammar rules: E E+T | T, T T*F | F, F (E) | id and parse the sentence: id + id * id.
AIM
To demonstrate Shift Reduce Parsing technique
DESCRIPTION
Bottom-up parsing starts from the leaf nodes of a tree and works in upward direction till it reaches
the root node. Here, we start from a sentence and then apply production rules in reverse manner in
order to reach the start symbol. The image given below depicts the bottom-up parsers available.
Shift-Reduce Parsing
Shift-reduce parsing uses two unique steps for bottom-up parsing. These steps are known as shift-
step and reduce-step.
Shift step: The shift step refers to the advancement of the input pointer to the next input symbol,
which is called the shifted symbol. This symbol is pushed onto the stack. The shifted symbol is
treated as a single node of the parse tree.
Reduce step : When the parser finds a complete grammar rule (RHS) and replaces it to (LHS), it is
known as reduce-step. This occurs when the top of the stack contains a handle. To reduce, a POP
function is performed on the stack which pops off the handle and replaces it with LHS non-terminal
symbol.
INPUT
Enter the string to be parsed {id+id*id}
EXPECTED OUTPUT
else
{
stk[i]=a[j];
stk[i+1]='\0';
a[j]=' ';
printf("\n$%s\t%s$\t%ssymbols",stk,a,act);
check();
}// end else
}// end for
}// end main
//--------------------------------------------------------------------------------------------
void check()
{
strcpy(ac,"REDUCE");
//first for
for(z=0;z<c;z++)
if(stk[z]=='(' && stk[z+1]=='E' && stk[z+2]==')')
{
stk[z]='F';
stk[z+1]='\0';
stk[z+2]='\0';
printf("\n$%s\t%s$\t%s",stk,a,ac);
i=i-2;
}
//2nd for
for(z=0;z<c;z++)
if(stk[z]=='i' && stk[z+1]=='d')
{
stk[z]='F';
stk[z+1]='\0';
printf("\n$%s\t%s$\t%s",stk,a,ac);
j++;
}
//3rd for
for(z=0;z<c;z++)
{
if(stk[z]=='T' && stk[z+1]=='*' && stk[z+2]=='F')
{
stk[z]='T';
stk[z+1]='\0';
Dept. of CSE,AJIET,Mangaluru Page 36
SS Lab 18CSL66
stk[z+2]='\0';
printf("\n$%s\t%s$\t%s",stk,a,ac);
i=i-2;
}
else if(stk[z]=='F')
{
stk[z]='T';
printf("\n$%s\t%s$\t%s",stk,a,ac);
}
}
//4th for
for(z=0;z<c;z++)
{
if(stk[z]=='E' && stk[z+1]=='+' && stk[z+2]=='T' && stk[z+3]=='*')break;
if(stk[z]=='E' && stk[z+1]=='+' && stk[z+2]=='T')
{
if(a[j+1]=='*')break;
else
{
stk[z]='E';
stk[z+1]='\0';
stk[z+2]='\0';
printf("\n$%s\t%s$\t%s",stk,a,ac);
i=i-2;
}//end else
}// end if
else if(stk[z]=='T')
{
stk[z]='E';
printf("\n$%s\t%s$\t%s",stk,a,ac);
}
}//for ends
}//check()
RESULT
Viva Questions
1.What is shift reduce parsing in compiler?
A shift-reduce parser is a class of efficient, table-driven bottom-up parsing methods for computer
languages and other notations formally defined by a grammar.
PROGRAM-5
TITLE
Design, develop and implement a C/Java program to generate the machine code using Triples for the
statement A = -B * (C +D) whose intermediate code in three-address form:
T1 = -B
T2 = C + D
T3 = T1 + T2
A = T3
AIM
To generate the machine code using Triples
DESCRIPTION
Three-Address Code
Intermediate code generator receives input from its predecessor phase, semantic analyzer, in the form
of an annotated syntax tree. That syntax tree then can be converted into a linear representation, e.g.,
postfix notation. Intermediate code tends to be machine independent code. Therefore, code generator
assumes to have unlimited number of memory storage (register) to generate code.
For example:
a=b+c*d; {Regular Expression}
The intermediate code generator will try to divide this expression into sub-expressions and then
generate the corresponding code.
t1=c*d;
t2=b+t1;
a=t2;
A three-address code has at most three address locations to calculate the expression. A three-address
code can be represented in two forms quadruples and triples.
Triples
Each instruction in triples presentation has three fields : op, arg1, and arg2.The results of respective
sub-expressions are denoted by the position of expression. Triples represent similarity with DAG and
syntax tree. They are equivalent to DAG while representing expressions
INPUT
A text file is inputted which contains three address code
EXPECTED OUTPUT
Print the machine code
PROGRAM
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<ctype.h>
void main()
{
char a[20];
int i,j=0;
FILE *f;
f=fopen("z.txt","r");
while(fscanf(f,"%s",a)!=EOF)
{
if(a[3]=='-')//first if
{
printf("MOV R%d,%c\n",j,a[4]);
printf("NEG R%d\n",j);
j++;
}
if(isalpha(a[3]))//second if
{
if(isdigit(a[4]))
{
if(isdigit(a[5]=='+'))
printf("ADD R%d,R%d,R%d\n",j,j-4,j-1);
Dept. of CSE,AJIET,Mangaluru Page 40
SS Lab 18CSL66
else if(a[5]=='-')
printf("SUB R%d,R%d,R%d\n",j,j-4,j-1);
else if(a[5]=='*')
printf("MUL R%d,R%d,R%d\n",j,j-4,j-1);
else if(a[5]=='/')
printf("DIV R%d,R%d,R%d\n",j,j-4,j-1);
}
else
{
if(a[4]=='+')
{
printf("MOV R%d,%c\n",j++,a[3]);
printf("MOV R%d,%c\n",j++,a[5]);
printf("ADD R%d,R%d,R%d\n",j,j-2,j-1);
}
if(a[4]=='-')
{
printf("MOV R%d,%c\n",j++,a[3]);
printf("MOV R%d,%c\n",j++,a[5]);
printf("SUB R%d,R%d,R%d\n",j,j-2,j-1);
}
else if(a[4]=='*')
{
printf("MOV R%d,%c\n",j++,a[3]);
printf("MOV R%d,%c\n",j++,a[5]);
printf("MUL R%d,R%d,R%d\n",j,j-2,j-1);
}
else if(a[4]=='/')
{
printf("MOV R%d,%c\n",j++,a[3]);
printf("MOV R%d,%c\n",j++,a[5]);
printf("DIV R%d,R%d,R%d\n",j,j-2,j-1);
}
j++;
}//end else
}//end isalpha
if(isdigit(a[3]))//third if
{
printf("MOV %c,R%d\n",a[0],j);
}//end while
Dept. of CSE,AJIET,Mangaluru Page 41
SS Lab 18CSL66
}//end main
RESULT
Viva Questions
1.What is token in compiler?
A lexeme is a sequence of characters in the source program that matches the pattern for a token and is
identified by the lexical analyzer as an instance of that token.A token is a pair consisting of
a token name and an optional attribute value.
PROGRAM-6a
TITLE
Write a LEX program to eliminate comment lines in a C program and copy the resulting program into
a separate file.
AIM
to eliminate comment lines in a C program
DESCRIPTION
The given lex program eliminates the comments and display the comment count.
INPUT
Input will be simple c program with single and multi-line comments
EXPECTED OUTPUT
Display the c program without comments and print the comment count.
Lex PROGRAM 6a
%{
#include<stdio.h>
int comment1=0,comment2=0,i=0;
%}
%%
[/][/].* {if(i==0)comment1++;}
[/][*] {if(i==0)i++;}
[*][/] {if(i==1)i--;comment2++;}
. {if(i==0)ECHO;}
%%
void main()
{
yyin=fopen("program.c","r");
yyout=fopen("output.txt","w");
yylex();
printf("Single line comments:%d\n",comment1);
printf("Multi line comments:%d\n",comment2);
printf("Total number of comments:%d\n",comment1+comment2);
}
int yywrap()
{
return 1;
}
RESULT
Viva Questions
1. Give the structure of the lex program.
definition section- any intitial ‘c’ program code
%%
Rules section- pattern and action separated by white space
%%
User subroutines section-concsit of any legal code.
2. Explain yyleng?
yyleng-contains the length of the string our lexer recognizes.
PROGRAM-6b
TITLE
Write YACC program to recognize valid identifier, operators and keywords in the given text (C
program) file.
AIM
To recognize valid identifier, operators and keywords
DESCRIPTION
y.tab.h gives LEX the names and type declarations etc. from YACC
yylval name used for values set in LEX e.g. yylval.a_number = atoi (yytext);
%token declare each grammar rule used by YACC that is recognised by LEX and give type of
value
INPUT
Input will be c program file
EXPECTED OUTPUT
1. Print the identifier, operator and keywords present in the c file inputted
2. Print the count of identifier, operator and keywords present in the c file inputted
PROGRAM 6b
Lex program
%{
#include<stdio.h>
#include "y.tab.h"
extern int yylval;
%}
%%
[+\-\*\/] {printf("Operator:%s\n",yytext);return OP;}
[0-9]+ {yylval = atoi(yytext); printf("Digit is %d\n",yylval); return DIGIT;}
"void"|"int"|"main"|"printf" {printf("Keyword:%s\n",yytext);return KEY;}
[a-zA-Z]+ {printf("Identifier:%s\n",yytext);return ID;}
.;
%%
int yywrap()
{
return 1;
}
Yacc Program
%{
#include<stdio.h>
#include<stdlib.h>
int dig=0,id=0,op=0,key=0;
extern FILE *yyin;
int yylex();
int yyerror();
%}
%token DIGIT ID KEY OP
%%
input:DIGIT input {dig++;}
|ID input {id++;}
|OP input {op++;}
|KEY input {key++;}
|DIGIT {dig++;}
|ID {id++;}
|OP {op++;}
|KEY {key++;}
;
%%
//#include<stdio.h>
void main()
{
yyin=fopen("sample.c","r");
yyparse();
printf("Key count=%d\n",key);
printf("Operator count=%d\n",op);
printf("Identifier count=%d\n",id);
printf("Digit count=%d\n",dig);
}
int yyerror()
{
printf("INVALID");
return 1;
}
RESULT
Sample.c
Viva Questions
1. What is identifier?
An Identifier can only have alphanumeric characters ( a-z , A-Z , 0-9 ) and underscore( _ ).
The first character of an identifier can only contain alphabet ( a-z , A-Z ) or underscore ( _ ).
PROGRAM-7
TITLE
Design, develop and implement a C/C++/Java program to simulate the working of Shortest remaining
time and Round Robin (RR) scheduling algorithms. Experiment with different quantum sizes for RR
algorithm.
AIM
To simulate the working of shortest remaining time and Round Robin (RR) scheduling algorithms
DESCRIPTION
Shortest remaining time scheduling algorithm:
Shortest remaining time, also known as shortest remaining time first (SRTF), is a scheduling method
that is a preemptive version of shortest job next scheduling. In this scheduling algorithm, the process
with the smallest amount of time remaining until completion is selected to execute. Since the currently
executing process is the one with the shortest amount of time remaining by definition, and since that
time should only reduce as execution progresses, processes will always run until they complete or a
new process is added that requires a smaller amount of time.
Shortest remaining time is advantageous because short processes are handled very quickly. The
system also requires very little overhead since it only makes a decision when a process completes or a
new process is added, and when a new process is added the algorithm only needs to compare the
currently executing process with the new process, ignoring all other processes currently waiting to
execute.
Like shortest job first, it has the potential for process starvation; long processes may be held off
indefinitely if short processes are continually added.
Round Robin (RR) scheduling algorithm:
Round-robin (RR) is one of the algorithms employed by process and network schedulers in
computing. As the term is generally used, time slices (also known as time quanta) are assigned to each
process in equal portions and in circular order, handling all processes without priority (also known as
cyclic executive). Round-robin scheduling is simple, easy to implement, and starvation-free. Round-
robin scheduling can also be applied to other scheduling problems, such as data packet scheduling in
computer networks. It is an operating system concept.
INPUT
1. Enter the choice
2. Enter the quantum time
3. Enter the Burst time
EXPECTED OUTPUT
Display the Average waiting and Turn-around Time
PROGRAM
#include<stdio.h>
struct proc
{
int id;
int arrival;
int burst;
int rem;
int wait;
int finish;
int turnaround;
float ratio;
}process[10]; //structure to hold the process information
struct proc temp;
int no;
int chkprocess(int);
int nextprocess();
void roundrobin(int, int, int[], int[]);
void srtf(int);
int main()
{
int n,tq,choice;
int bt[10],st[10],i,j,k;
for(; ;)
{
printf("Enter the choice \n");
printf(" 1. Round Robin\n 2. SRT\n 3. Exit \n");
scanf("%d",&choice);
switch(choice)
Dept. of CSE,AJIET,Mangaluru Page 50
SS Lab 18CSL66
{
case 1:
printf("Round Robin scheduling algorithm\n");
printf("Enter number of processes:\n");
scanf("%d",&n);
printf("Enter burst time for sequences:");
for(i=0;i<n;i++)
{
scanf("%d",&bt[i]);
st[i]=bt[i]; //service time
}
printf("Enter time quantum:");
scanf("%d",&tq);
roundrobin(n,tq,st,bt);
break;
case 2:
printf("\n \n ---SHORTEST REMAINING TIME NEXT---\n \n ");
printf("\n \n Enter the number of processes: ");
scanf("%d", &n);
srtf(n);
break;
case 3: break;
}// end of switch
}// end of for
}//end of main()
int time=0;
int tat[10],wt[10],i,count=0,swt=0,stat=0,temp1,sq=0,j,k;
float awt=0.0,atat=0.0;
while(1)
{
for(i=0,count=0;i<n;i++)
{
temp1=tq;
if(st[i]==0) // when service time of a process equals zero then
//count value is incremented
Dept. of CSE,AJIET,Mangaluru Page 51
SS Lab 18CSL66
{
count++;
continue;
}
if(st[i]>tq) // when service time of a process greater than time
//quantum then time
st[i]=st[i]-tq; //quantum value subtracted from service time
else
if(st[i]>=0)
{
temp1=st[i]; // temp1 stores the service time of a process
st[i]=0; // making service time equals 0
}
sq=sq+temp1; // utilizing temp1 value to calculate turnaround time
tat[i]=sq; // turn around time
} //end of for
if(n==count) // it indicates all processes have completed their task because the count value
break; // incremented when service time equals 0
} //end of while
for(i=0;i<n;i++) // to calculate the wait time and turnaround time of each process
{
wt[i]=tat[i]-bt[i]; // waiting time calculated from the turnaround time - burst time
swt=swt+wt[i]; // summation of wait time
stat=stat+tat[i]; // summation of turnaround time
}
awt=(float)swt/n; // average wait time
atat=(float)stat/n; // average turnaround time
printf("Process_no Burst time Wait time Turn around time\n");
for(i=0;i<n;i++)
printf("%d\t\t%d\t\t%d\t\t%d\n",i+1,bt[i],wt[i],tat[i]);
printf("Avg wait time is %f\n Avg turn around time is %f\n",awt,atat);
}// end of Round Robin
{
int i;
for(i = 1; i <= s; i++)
{
if(process[i].rem != 0)
Dept. of CSE,AJIET,Mangaluru Page 52
SS Lab 18CSL66
return 1;
}
return 0;
} // end of chkprocess
{
int min, l, i;
min = 32000; //any limit assumed
for(i = 1; i <= no; i++)
{
if( process[i].rem!=0 && process[i].rem < min)
{
min = process[i].rem;
l = i;
}
}
return l;
} // end of nextprocess
void srtf(int n)
{
int i,j,k,time=0;
float tavg,wavg;
for(i = 1; i <= n; i++)
{
process[i].id = i;
printf("\n\nEnter the arrival time for process %d: ", i);
scanf("%d", &(process[i].arrival));
printf("Enter the burst time for process %d: ", i);
scanf("%d", &(process[i].burst));
process[i].rem = process[i].burst;
}
for(i = 1; i <= n; i++)
{
for(j = i + 1; j <= n; j++)
{
Dept. of CSE,AJIET,Mangaluru Page 53
SS Lab 18CSL66
process[j].finish = time;
j=nextprocess();
time--;
k=j;
}
time++;
}//end of while
Dept. of CSE,AJIET,Mangaluru Page 54
SS Lab 18CSL66
process[k].finish = time;
printf("\n\n\t\t\t---SHORTEST REMAINING TIME FIRST---");
printf("\n\n Process Arrival Burst Waiting Finishing turnaround Tr/Tb \n");
printf("%5s %9s %7s %10s %8s %9s\n\n", "id", "time", "time", "time", "time", "time");
for(i = 1; i <= n; i++)
{
process[i].turnaround = process[i].wait + process[i].burst; // calc of turnaround
process[i].ratio = (float)process[i].turnaround / (float)process[i].burst;
printf("%5d %8d %7d %8d %10d %9d %10.1f ", process[i].id, process[i].arrival,
process[i].burst, process[i].wait, process[i].finish, process[i].turnaround,
process[i].ratio);
tavg=tavg+ process[i].turnaround; //summation of turnaround time
wavg=wavg+process[i].wait; // summation of waiting time
printf("\n\n");
}
tavg=tavg/n; // average turnaround time
wavg=wavg/n; // average wait time
printf("tavg=%f\t shortest remaining time scheduling=%f\n",tavg,wavg);
RESULT
Viva Questions
1. Explain the main purpose of an operating system?
Operating systems exist for two main purposes. One is that it is designed to make sure a computer
system performs well by managing its computational activities. Another is that it provides an
environment for the development and execution of programs.
2. What is kernel?
A kernel is the core of every operating system. It connects applications to the actual processing of
data..
4. What are necessary conditions which can lead to a deadlock situation in a system?
Deadlock situations occur when four conditions occur simultaneously in a system: Mutual
exclusion; Hold and Wait; No preemption; and Circular wait.
PROGRAM-8
TITLE
Design, develop and implement a C/C++/Java program to implement Banker’s algorithm. Assume
suitable input required to demonstrate the results..
AIM
To implement Banker’s algorithm
DESCRIPTION
Banker’s algorithm
The Banker's algorithm, sometimes referred to as the detection algorithm, is a resource allocation
and deadlock avoidance algorithm developed by Edsger Dijkstra that tests for safety by simulating the
allocation of predetermined maximum possible amounts of all resources, and then makes an "s-state"
check to test for possible deadlock conditions for all other pending activities, before deciding whether
allocation should be allowed to continue.
The algorithm was developed in the design process for the operating system and originally described
(in Dutch) in EWD108. When a new process enters a system, it must declare the maximum number of
instances of each resource type that it may ever claim; clearly, that number may not exceed the total
number of resources in the system. Also, when a process gets all its requested resources it must return
them in a finite amount of time.
INPUT
EXPECTED OUTPUT
PROGRAM
#include<stdio.h>
void main()
{
intk=0,output[10],d=0,t=0,ins[5],i,avail[5],allocated[10][5],need[10][5],MAX[10][5],pno,P[10],j,rz,
count=0;
printf("\n Enter the number of resources : ");
scanf("%d", &rz);
printf("\n enter the max instances of each resources\n");
for(i=0;i<rz;i++)
{ avail[i]=0;
printf("%c= ",(i+97));
scanf("%d",&ins[i]);
}
printf("\n Enter the number of processes : ");
scanf("%d", &pno);
printf("\n Enter the allocation matrix \n ");
for(i=0;i<rz;i++)
printf(" %c",(i+97));
printf("\n");
for(i=0;i<pno;i++)
{ P[i]=i;
printf("P[%d] ",P[i]);
for(j=0;j<rz;j++)
{
scanf("%d",&allocated[i][j]);
avail[j]+=allocated[i][j];
}
}
printf("\n");
A: d=-1;
for(i=0;i <pno;i++)
{ count=0; t=P[i];
for(j=0;j<rz;j++)
{
need[t][j] = MAX[t][j]-allocated[t][j];
if(need[t][j]<=avail[j])
count++;
}
if(count==rz)
{
output[k++]=P[i];
for(j=0;j<rz;j++)
avail[j]+=allocated[t][j];
}
else
P[++d]=P[i];
}//end for
if(d!=-1)
{ pno=d+1;
goto A;
}
printf("\t <");
for(i=0;i<k;i++)
printf(" P[%d] ",output[i]);
printf(">");
}// end main
RESULT
Viva Questions
1. Why bankers algorithm are used?
Banker's algorithm is a deadlock avoidance algorithm. It is named so because this algorithm is
used in banking systems to determine whether a loan can be granted or not.
PROGRAM-9
TITLE
Design, develop and implement a C/C++/Java program to implement page replacement algorithms
LRU and FIFO. Assume suitable input required to demonstrate the results.
AIM
To implement page replacement algorithms LRU and FIFO
DESCRIPTION
Page replacement algorithms LRU and FIFO:
In a computer operating system that uses paging for virtual memory management, page replacement
algorithms decide which memory pages to page out, sometimes called swap out, or write to disk,
when a page of memory needs to be allocated. Page replacement happens when a requested page is
not in memory (page fault) and a free page cannot be used to satisfy the allocation, either because
there are none, or because the number of free pages is lower than some threshold.
When the page that was selected for replacement and paged out is referenced again it has to be paged
in (read in from disk), and this involves waiting for I/O completion. This determines the quality of the
page replacement algorithm: the less time waiting for page-ins, the better the algorithm. A page
replacement algorithm looks at the limited information about accesses to the pages provided by
hardware, and tries to guess which pages should be replaced to minimize the total number of page
misses, while balancing this with the costs (primary storage and processor time) of the algorithm
itself. The page replacing problem is a typical online problem from the competitive analysis
perspective in the sense that the optimal deterministic algorithm is known.
INPUT
1. Enter the frame size.
2. Enter the No of Pages
3. Enter the Page no
EXPECTED OUTPUT
Display the page faults and page hit count
PROGRAM
Dept. of CSE,AJIET,Mangaluru Page 62
SS Lab 18CSL66
#include<stdio.h>
#include<stdlib.h>
void FIFO(char [ ],char [ ],int,int);
void lru(char [ ],char [ ],int,int);
int cnt;
int main()
{
int ch,YN=1,i,l,f;
char F[10],s[25];
printf("\n\n\tEnter the no of empty frames: ");
scanf("%d",&f);
printf("\n\n\tEnter the length of the string: ");
scanf("%d",&l);
printf("\n\n\tEnter the string: ");
scanf("%s",s);
for(i=0;i<f;i++)
F[i]=-1;
do
{
printf("\n\n\t*********** MENU ***********");
printf("\n\n\t1:FIFO\n\n\t2:LRU\n\n\t3:EXIT");
printf("\n\n\tEnter your choice:");
scanf("%d",&ch);
switch(ch)
{
case 1:
for(i=0;i<f;i++)
{
F[i]=-1;
}
FIFO(s,F,l,f);
break;
case 2:
for(i=0;i<f;i++)
{
F[i]=-1;
}
lru(s,F,l,f);
break;
case 3:
Dept. of CSE,AJIET,Mangaluru Page 63
SS Lab 18CSL66
exit(0);
}
printf("\nNumber of page fault is %d",cnt);
printf("\nNumber of page hit is %d",(l-cnt));
printf("\n\n\tDo u want to continue IF YES PRESS 1\n\n\tIF NO PRESS 0 :");
scanf("%d",&YN);
}
while(YN==1);
return(0);
}
//FIFO
void FIFO(char s[],char F[],int l,int f)
{
int i,j=0,k,flag=0;
cnt=0;
printf("\n\tPAGE\tFRAMES\t FAULTS");
for(i=0;i<l;i++)
{
for(k=0;k<f;k++)
{
if(F[k]==s[i])
flag=1;
}
if(flag==0)
{
printf("\n\t%c\t",s[i]);
F[j]=s[i];
j++;
for(k=0;k<f;k++)
{
printf(" %c",F[k]);
}
printf("\tPage-fault%d",cnt);
cnt++;
}
else
{
flag=0;
printf("\n\t%c\t",s[i]);
for(k=0;k<f;k++)
Dept. of CSE,AJIET,Mangaluru Page 64
SS Lab 18CSL66
{
printf(" %c",F[k]);
}
printf("\tNo page-fault");
}
if(j==f)
j=0;
}
}
//LRU
void lru(char s[],char F[],int l,int f)
{
int i,j=0,k,m,flag=0,top=0;
cnt=0;
printf("\n\tPAGE\t FRAMES\t FAULTS");
for(i=0;i<l;i++)
{
for(k=0;k<f;k++)
{
if(F[k]==s[i])
{
flag=1;
break;
}
}
printf("\n\t%c\t",s[i]);
if(j!=f && flag!=1)
{
F[top]=s[i];
j++;
if(j!=f)
top++;
}
else
{
if(flag!=1)
{
for(k=0;k<top;k++)
{
F[k]=F[k+1];
Dept. of CSE,AJIET,Mangaluru Page 65
SS Lab 18CSL66
}
F[top]=s[i];
}
if(flag==1)
{
for(m=k;m<top;m++)
{
F[m]=F[m+1];
}
F[top]=s[i];
}
}
for(k=0;k<f;k++)
{
printf(" %c",F[k]);
}
if(flag==0)
{
printf("\tPage-fault%d",cnt);
cnt++;
}
else
printf("\tNo page fault");
flag=0;
}
}
RESULT
Viva Questions
1.What is FIFO page replacement algorithm?
First-In-First-Out (FIFO) Replacement. On a page fault, the frame that has been in memory the
longest is replaced. FIFO is not a stack algorithm. In certain cases, the number of page faults can
actually increase when more frames are allocated to the process.
instructions will probably be heavily usedagain in the next few. ... This strategy is called LRU (Least
Recently Used) paging.