Sslab
Sslab
Sslab
LABORATORY
17CSL67
8 Viva Questions 50
SYSTEM SOFTWARE AND OPERATING SYSTEM LABORATORY
[As per Choice Based Credit System (CBCS) scheme]
(Effective from the academic year 2017 - 2018)
SEMESTER – VI
1. INTRODUCTION TO LEX
Lex and YACC helps you write programs that transforms structured input. Lex
generates C code for lexical analyzer whereas YACC generates Code for Syntax analyzer.
Lexical analyzer is build using a tool called LEX. Input is given to LEX and lexical analyzer
is generated.
Lex is a 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 descriptions that Lex uses are known as regular expressions.
1st Step: Using gedit create a file with extension l. For example: prg1.l
2nd Step: lex prg1.l
3rd Step: cc lex.yy.c–ll
4th Step: ./a.out
{definitions}
%%
{rules}
%%
{user subroutines/code section}
%% is a delimiter to the 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.
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*).
yyleng Gives the length of the matched pattern.
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.
It is used to describe the pattern. It is widely used to in lex. It uses meta language. The
character used in this meta language are part of the standard ASCII character set. An
expression is made up of symbols. Normal symbols are characters and numbers, but there are
other symbols that have special meaning in Lex. The following two tables define some of the
symbols used in Lex and give a few typical examples.
Character Meaning
A-Z, 0-9, a-z Characters and numbers that form part of the pattern.
. Matches any character except \n.
Used to denote range. Example: A-Z implies all characters from A
- to Z.
A character class. Matches any character in the brackets. If the first
[] character is ^ then it indicates a negation pattern. Example: [abC]
matches either of a, b, and C.
* Match zero or more occurrences of the preceding pattern.
Matches one or more occurrences of the preceding pattern.(no
empty string).
+ Ex: [0-9]+ matches “1”,”111” or “123456” but not an empty string.
Matches zero or one occurrences of the preceding pattern.
Ex: -?[0-9]+ matches a signed number including an optional
? leading minus.
$ Matches end of line as the last character of the pattern.
1) Indicates how many times a pattern can be present. Example:
A{1,3} implies one to three occurrences of A may be present.
2) If they contain name, they refer to a substitution by that name.
{} Ex: {digit}
Used to escape meta characters. Also used to remove the special
\ meaning of characters as defined in this table.
2. 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.
%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 non-terminal 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.
Apart from the program code, it includes the current activity represented by
Program Counter,
Process Stack which contains temporary data like function parameters,
return addresses and local variables
Data section which contains global variables
Heap for dynamic memory allocation
Switching the CPU to another process requires performing a state save of the current
process and a state restore of new process, this is Context Switch.
CPU utilization:
Throughput: The number of processes that are completed per unit time.
Priority Scheduling
4.2 Deadlocks
A process requests resources; and if the resource is not available at that time, the
process enters a waiting state. Sometimes, a waiting process is never able to change state,
because the resource is has requested is held by another process which is also waiting. This
situation is called Deadlock. Deadlock is characterized by four necessary conditions
Mutual Exclusion
Hold and Wait
No Preemption
Circular Wait
Shortest remaining time, also known as shortest remaining time first (SRTF), is a
scheduling method that is a pre-emptive 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.
The name of the algorithm comes from the round-robin principle known from other
fields, where each person takes an equal share of something in turn.
Banker’s algorithm:
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.
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.
Parsing:
A parser is a compiler or interpreter component that breaks data into smaller
elements for easy translation into another language. A parser takes input in the form of a
sequence of tokens or program instructions and usually builds a data structure in the form of
a parse tree or an abstract syntax tree.
A parser's main purpose is to determine if input data may be derived from the start
symbol of the grammar.
Top-Down Parsing:
When the parser starts constructing the parse tree from the start symbol and then tries
to transform the start symbol to the input, it is called top-down parsing.
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.
Example: One solution to the quadratic equation using three address code is as
below.x = (-b + sqrt(b^2 - 4*a*c)) / (2*a)
t1 = b * b
t2 = 4 * a
t3 = t2 * c
t4 = t1 - t3
t5 = sqrt(t4)
t6 = 0 - b
t7 = t5 + t6
t9 = t7 / t8
x = t9
t8 = 2 * a
$ lex filename.l
$ yacc –d filename.y
$ cc lex.yy.c y.tab.c –ll
$./a.out
Enter the string
Aabb
Given string is accepted
6. LAB PROGRAMS
1. a). 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.
%{
#include<stdio.h>
int id=0,op=0,bc=0,i=0,j=0,x;
int flag=0;
charopa[20];
charida[20];
%}
%%
"(" {bc++; flag=1;}
")" {if(flag==1) { bc--; flag=0;}
elsebc--;
}
"+"|"*" { op++; opa[i++]=*yytext;}
[0-9]+ { id++; ida[j++]=atoi(yytext);}
. ;
%%
yywrap()
{
return 1;
}
main()
{
printf("Enter the expression:");
yylex();
if((flag!=0)||(bc!=0)||(id-op)!=1)
{
printf("Invalid Expression!!\n");
}
else
{
printf("Valid expression\n");
printf("List of operators are:\n");
for(x=0;x<i;x++)
printf("%c\t",opa[x]);
printf("\nNo of operators are:%d\n",i);
printf("List of identifiers are:");
for(x=0;x<j;x++)
printf("%d",ida[x]);
printf("\nNo of identifiers are:%d\n",j);
}
Expected Output:
YACC Part
%{ int yywrap();
Void yyerror();
int yyparse();
%}
%{ #include <stdio.h>
int valid=1,flag=1;
%}
%token num;
%left '+''-'
%left '*''/'
%left '('')'
%nonassoc UMINUS
%%
expr:e {if((flag==1)&&(valid==1))
printf("result %d\n",$$);
if((flag==1)&&(valid==0))
printf("division by by zero not allowed \n");
}
e:e'+'e {$$=$1+$3;}
|e'-'e {$$=$1-$3;}
|e'*'e {$$=$1*$3;}
|e'/'e {if($3==0) valid=0;
else $$=$1/$3;}
|'-'e %prec UMINUS {($$=-$2);}
|'('e')' {$$=$2;}
|num {$$=$1;}
%%
void yyerror()
{
flag=0;}
int yywrap()
{
return 1;}
int main()
{
printf("enter the expr:\n");
yyparse();
if(flag==0)
printf("expr is wrong\n");
}
Expected Output:
2. Develop, Implement and Execute a program using YACC tool to recognize all strings
n
ending with b preceded by n a’s using the grammar a b (note: input n value).
Lex Part
%{
#include"y.tab.h"
%}
%%
a {return A;}
b {return B;}
. {returnyytext[0];}
\n {return 0;}
%%
YACC Part
%{
intyywrap();
voidyyerror();
intyyparse();
%}
%{
#include<stdio.h>
int valid=1,c=0,n;
extern FILE *yyin;
%}
%token A
%token B
%%
S:A S {c++;}|B;
%%
voidyyerror()
{
valid=0;
}
intyywrap()
{
return 1;
}
int main()
{
printf("enter the value for n:\n");
scanf("%d",&n);
yyin=fopen("string.txt","r");
yyparse();
if(valid==0 || c!=n)
{
printf("invalid string\n");
}
if(valid==1 && c==n)
{
printf("valid string\n");
}
fclose(yyin);
}
Expected Output:
#include<stdio.h>
#include<string.h>
char prod[3][10]={"A->aBa","B->bB","B->@"};
char first[3][10]={"a","b","@"};
char follow[3][10]={"$","a","a"};
char table[3][4][10];
char input[10];
int top=-1;
char stack[25];
charcurp[20];
push(char item)
{
stack[++top]=item;
}
pop()
{
top=top-1;
}
display()
{
inti;
for(i=top;i>=0;i--)
printf("%c",stack[i]);
}
numr(char c)
Dept. of CSE, Atria Institute of Technology Jan 2020 25|5 1
System Software and Operating System Lab 17CSL67
{
switch(c)
{
case 'A': return 1;
case 'B': return 2;
case 'a': return 1;
case 'b': return 2;
case '@': return 3;
}
return(1);
}
void main()
{
char c;
inti,j,k,n;
for(i=0;i<3;i++)
for(j=0;j<4;j++)
strcpy(table[i][j],"e");
printf("\n Grammar:\n");
for(i=0;i<3;i++)
printf("%s\n",prod[i]);
printf("\nfirst= {%s,%s,%s}",first[0],first[1],first[2]);
printf("\nfollow ={%s %s}\n",follow[0],follow[1]);
printf("\nPredictive parsing table for the given grammar\n");
strcpy(table[0][0]," ");
strcpy(table[0][1],"a");
strcpy(table[0][2],"b");
strcpy(table[0][3],"$");
strcpy(table[1][0],"A");
strcpy(table[2][0],"B");
for(i=0;i<3;i++)
{
k=strlen(first[i]);
for(j=0;j<k;j++)
if(first[i][j]!='@')
strcpy(table[numr(prod[i][0])][numr(first[i][j])],prod[i]);
else
strcpy(table[numr(prod[i][0])][numr(follow[i][j])],prod[i]);
}
printf("\n-------------------------------------------------------
\n");
for(i=0;i<3;i++)
for(j=0;j<4;j++)
{
printf("%-10s",table[i][j]);
if(j==3) printf("\n-------------------------------------------------
-------\n");
}
printf("enter the input string terminated with $ to parse :- ");
scanf("%s",input);
for(i=0;input[i]!='\0';i++)
if((input[i]!='a')&&(input[i]!='b')&&(input[i]!='$'))
{
printf("invalid string");
exit(0);
}
if(input[i-1]!='$')
Dept. of CSE, Atria Institute of Technology Jan 2020 26|5 1
System Software and Operating System Lab 17CSL67
{
printf("\n\nInput String Entered Without End marker $");
exit(0);
}
push('$');
push('A');
i=0;
printf("\n\n");
printf(" stack\t Input \taction ");
printf("\n-----------------------------------------\n");
while(input[i]!='$' && stack[top]!='$')
{
display();
printf("\t\t%s\t ",(input+i));
if (stack[top]==input[i])
{
printf("\tmatched %c\n",input[i]);
pop();
i++;
}
else
{
if(stack[top]>=65 && stack[top]<92)
{
strcpy(curp,table[numr(stack[top])][numr(input[i])]);
if(!(strcmp(curp,"e")))
{
printf("\n invalid string- Rejected\n");
exit(0);
}
else
{
printf(" \tapply production %s\n",curp);
if(curp[3]=='@')
pop();
else
{
pop();
n=strlen(curp);
for(j=n-1;j>=3;j--)
push(curp[j]);
}
}
}
}
}
display();
printf("\t\t%s\t ",(input+i));
printf("\n--------------------------------------------\n");
if(stack[top]=='$' && input[i]=='$' )
{
printf("\n valid string - Accepted\n");
}
else
{
printf("\ninvalid string- Rejected\n");
}
Dept. of CSE, Atria Institute of Technology Jan 2020 27|5 1
System Software and Operating System Lab 17CSL67
Expected Output:
#include<stdio.h>
//#include<conio.h>
#include<string.h>
//#include<process.h>
charstk[20],input[20],act[20];
void main()
{
inti=0,k=0,c;
strcpy(stk,"$");
printf("The grammer is E->E+T|T\nT->T*F|F\nF->(E)|id\n");
printf("input the string\n");
scanf("%s",input);
c=strlen(input);
printf("stack\tInput\tAction\n");
while(i<=c)
{
if(stk[k]=='$')
{
if(input[i]=='(')
{
stk[k]='(';
input[i]=' ';
i=i+1;
}
else if(input[i]=='i'&&input[i+1]=='d')
{
stk[k]='i';
stk[k+1]='d';
k=k+1;
input[i]=' ';
input[i+1]=' ';
i=i+2;
}
else
{
printf("error input\n");
exit(0);
}
strcpy(act,"Shift");
printf("$%s\t%s$\t%s\n",stk,input,act);
}
else if(stk[k]=='(')
{
if(input[i]=='i'&&input[i+1]=='d')
{
stk[k+1]=input[i];
stk[k+2]=input[i+1];
k=k+1;
input[i]=' ';
input[i+1]=' ';
i=i+2;
}
else
{
printf("error input");
exit(0);
}
strcpy(act,"Shift");
printf("$%s\t%s$\t%s\n",stk,input,act);
Dept. of CSE, Atria Institute of Technology Jan 2020 29|5 1
System Software and Operating System Lab 17CSL67
}
else if(stk[k-1]=='i'&&stk[k]=='d')
{
if(input[i]=='+'||
input[i]=='*'||input[i]=='\0')
{
stk[k-1]='F';
stk[k]=' ';
k=k-1;
strcpy(act,"Redue F->id");
}
else
{
printf("error input\n");
exit(0);
}
printf("$%s\t%s$\t%s\n",stk,input,act);
}
else if(stk[k]=='*'||stk[k]=='+')
{
if(input[i]=='i'&&input[i+1]=='d')
{
stk[k+1]='i';
stk[k+2]='d';
k=k+2;
input[i]=' ';
input[i+1]=' ';
i=i+2;
strcpy(act,"Shift");
}
else
{
printf("error input");
exit(0);
}
printf("$%s\t%s$\t%s\n",stk,input,act);
}
else if(stk[k]=='F')
{
if(input[i]=='+'||input[i]=='*'||(input[i]=='\0'&&stk[k-
1]=='+'))
{
stk[k]='T';
strcpy(act,"RedceT->F");
}
else if(input[i]=='\0'&&stk[k-1]=='*')
{
stk[k-2]='T';
stk[k]=' ';
stk[k-1]=' ';
k=k-2;
strcpy(act,"ReduceT->T*F");
}
else
{
printf("error input");
exit(0);
}
Dept. of CSE, Atria Institute of Technology Jan 2020 30|5 1
System Software and Operating System Lab 17CSL67
printf("$%s\t%s$\t%s\n",stk,input,act);
}
else if(stk[k]=='T')
{
if(input[i]=='+')
{
stk[k]='E';
strcpy(act,"Reduce E->T");
}
else if(input[i]=='*')
{
stk[k+1]='*';
k=k+1;
input[i]=' ';
i=i+1;
strcpy(act,"Shift");
}
else if(input[i]=='\0')
{
stk[k-2]='E';
stk[k]=' ';
stk[k-1]=' ';
k=k-2;
strcpy(act,"Reduce E->E+T");
}
else
{
printf("error input");
exit(0);
}
printf("$%s\t%s$\t%s\n",stk,input,act);
}
else if(stk[k]=='E')
{
if(input[i]=='+'||input[i]==')')
{
stk[k+1]=input[i];
k=k+1;
input[i]=' ';
i=i+1;
strcpy(act,"Shift");
}
else if(input[i]=='\0')
{
strcpy(act,"Accept");
printf("$%s\t%s$\t%s\n",stk,input,act);
exit(0);
}
printf("$%s\t%s$\t%s\n",stk,input,act);
else if(stk[k]==')')
{
stk[k-2]='F';
stk[k]=' ';
stk[k-1]=' ';
k=k-2;
Dept. of CSE, Atria Institute of Technology Jan 2020 31|5 1
System Software and Operating System Lab 17CSL67
strcpy(act,"Redue F->(E)");
printf("$%s\t%s$\t%s\n",stk,input,act);
}
else
{
printf("error input");
exit(0);
}
}
//getch();
}
Expected Output:
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-
addressform:
T1=-B
T2=C+D
T3=T1+T2
A=T3
#include<stdio.h>
#include<string.h>
void main()
{
charicode[10][30],opr;
char op1[5],op2[5],res[5];
inti=0,n,j,k;
printf("\nEnter the number of intermediate statements:");
scanf("%d",&n);
printf("Enter the set of intermediate code\n");
for(i=0;i<n;i++)
{
scanf("%s",icode[i]);
}
printf("\n");
for(i=0;i<n;i++)
{
j=0,k=0;
while(icode[i][j]!='=')
{
res[k]=icode[i][j];
j=j+1;
k=k+1;
}
res[j]='\0';
k=0;
j++;
if(icode[i][j]=='-')
{
j++;
while(icode[i][j]!='\0')
{
op1[k]=icode[i][j];
j++;
k++;
}
op1[k]='\0';
printf("LOAD R1,%s\n",op1);
printf("NEG R1\n");
printf("STORE %s,R1\n",res);
}
else
{
k=0;
while(icode[i][j]!='\0' &&icode[i][j]!='+'
&&icode[i][j]!='-')
{
op1[k]=icode[i][j];
j++;
k++;
}
op1[k]='\0';
if(icode[i][j]=='\0')
{
Dept. of CSE, Atria Institute of Technology Jan 2020 33|5 1
System Software and Operating System Lab 17CSL67
printf("LOAD R4,%s\n",op1);
printf("STORE %s,R4\n",res);
continue;
}
else
{
opr=icode[i][j];
k=0;
j++;
while(icode[i][j]!='\0')
{
op2[k]=icode[i][j];
j++;
k++;
}
op2[k]='\0';
}
switch(opr)
{
case '+' : printf("LOAD R1,%s\n",op1);
printf("LOAD R2,%s\n",op2);
printf("ADD R1,R2\n");
printf("STORE %s,R1\n",res);
break;
case '-' : printf("LOAD R1,%s\n",op1);
printf("LOAD R1,%s\n",op2);
printf("SUB R1,R2\n");
printf("Store %s,R1\n",res);
break;
default :printf("\nInvalid statement");
}
}
}
}
Expected Output:
6. a) Write a LEX program to eliminate comment lines in a C program and copy the
resulting program into a separate file.
%{
#include<stdio.h>
int flag=0,n=0,cmt=0;
%}
%%
"//".* {cmt++;}
"/*".*"*/" {cmt++;}
"/*".* {flag=1;n++;}
\n {if(flag==1) n++;else ECHO;}
.*"*/" {if(flag==1) cmt+=n;flag=0;n=0;}
. {if(flag==0) ECHO;}
%%
intyywrap()
{
return 1;}
int main()
{
yyin=fopen("p1.c","r");
yyout=fopen("out.txt","w");
yylex();
fclose(yyin);
fclose(yyout);
printf("no. of comment lines=%d\n",cmt++);
}
b). Write YACC program to recognize valid identifier, operators and keywords in
the given text (C program) file.
LEX part
%{
#include<stdio.h>
#include "y.tab.h"
externintyylval;
%}
%%
[\t] ;
[+|-|*|\|=] {printf("operator is %c\n",yytext[0]);
return OP;}
int|main|printf|for {printf("\n keyword is %s\n",yytext);
return KEY;}
[_a-zA-Z][0-9A-Z]* {printf("\n identifier is %s\n",yytext);
return ID;}
[0-9][a-z][0-9a-z]* ;
"(".*");" ;
. ;
%%
YACC part
%{ intyywrap();
voidyyerror();
intyyparse();
%}
%{
#include<stdio.h>
int id=0,key=0,op=0,valid=1;
extern FILE *yyin;
%}
%token ID KEY OP
%%
input:ID {id++;}|KEY {key++;}|OP {op++;}|input ID {id++;}|input OP
{op++;}|input KEY {key++;}
%%
void yyerror()
{
valid=0;
}
Int yywrap()
{
return 1;}
int main()
{
yyin=fopen("input.c","r");
yyparse();
if(valid!=0)
printf("%d %d %d",id,op,key);
}
Expected Output:
#include<stdio.h>
#include<stdlib.h>
struct proc
{
int id;
int arrival;
int burst;
int rem;
int wait;
int finish;
int turnaround;
float ratio;
}process[10];
struct proc temp;
int no;
int chkprocess(int);
int nextprocess();
void roundrobin(int,int,int[],int[]);
void strf(int);
int main()
{
int n,tq,choice;
int bt[10],st[10],i,j,k;
for(;;)
{
printf("Enter the choice:\n");
printf("1.Roundrobin\n2.SRT\n3.Exit\n");
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("Roundrobin algorithm\n");
printf("Enter the number of processes:\n");
scanf("%d",&n);
printf("Enter the burst time for
sequences:\n");
for(i=0;i<n;i++)
{
scanf("%d",&bt[i]);
st[i]=bt[i];
}
printf("Enter the time quantum:");
scanf("%d",&tq);
roundrobin(n,tq,st,bt);
break;
case 2:
printf("\n\n---SHORTEST REMAING TIME NEXT--
\n\n");
printf("\nEnter the no of processes:");
scanf("%d",&n);
strf(n);
break;
case 3:
exit(0);
}
}
return 0;
}
void roundrobin(int n,int tq,int st[],int bt[])
{
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)
{
count++;
continue;
}
if(st[i]>tq)
st[i]=st[i]-tq;
else if(st[i]>=0)
{
temp1=st[i];
st[i]=0;
}
sq=sq+temp1;
tat[i]=sq;
}
if(n==count)
break;
}
for(i=0;i<n;i++)
{
wt[i]=tat[i]-bt[i];
swt=swt+wt[i];
stat=stat+tat[i];
}
awt=(float)swt/n;
atat=(float)stat/n;
printf("process_no burst_time wait_time
turnaround_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\nAvgturn around time
is:%f\n",awt,atat);
}
int chkprocess(int s)
{
int i;
for(i=1;i<=s;i++)
{
if(process[i].rem!=0)
return 1;
}
return 0;
}
int nextprocess()
{
int i,min,l;
min=32000;
for(i=1;i<=no;i++)
{
if(process[i].rem!=0&&process[i].rem<min)
{
min=process[i].rem;
l=i;
}
}
return l;
}
void strf(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++)
{
if(process[i].arrival>process[j].arrival)
{
temp=process[i];
process[i]=process[j];
process[j]=temp;
}
}
}
no=0;
j=1;
while(chkprocess(n)==1)
{
if(process[no+1].arrival==time)
{
no++;
if(process[j].rem==0)
process[j].finish=time;
j=nextprocess();
}
if(process[j].rem!=0)
{
process[j].rem--;
for(i=1;i<=no;i++)
{
if(i!=j&&process[i].rem!=0)
process[i].wait++;
}
}
else
{
process[j].finish=time;
j=nextprocess();
time--;
k=j;
}
time++;
}
process[k].finish=time;
printf("\n\n--SHORTEST REMAINING TIME FIRST--\n\n");
printf("\n\nprocess arrival burst waiting finishing
turnaround Tr/Tb \n");
printf("%5s%9s%7s%10s%8s%9s\n\n","id","time","time","time","tim
e","time");
for(i=1;i<=n;i++)
{
process[i].turnaround=process[i].wait+process[i].burst;
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].arr
ival,process[i].burst,process[i].wait,process[i].finish,process[i].t
urnaround,process[i].ratio);
tavg=tavg+process[i].turnaround;
wavg=wavg+process[i].wait;
printf("\n\n");
}
tavg=tavg/n;
wavg=wavg/n;
printf("\ntavg=%f\t \nwavg=%f\n",tavg,wavg);
}
Expected Output:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int max[10][10],need[10][10],alloc[10][10],avail[10],completed[10],selfsequence[10];
int p,r,i,j,process,count;
count=0;
printf("Enter the number of process: ");
scanf("%d",&p);
for(i=0;i<p;i++)
{
completed[i]=0;
printf("Enter the number of resource: ");
scanf("%d",&r);
printf("Enter the Max matrix for each process:\n");
for(i=0;i<p;i++)
{
printf("for process %d\n",i+1);
for(j=0;j<r;j++)
{
scanf("%d",&max[i][j]);
}
}
printf("Enter the allocation for each process:\n");
for(i=0;i<p;i++)
{
printf("process %d\n",i+1);
for(j=0;j<r;j++)
{
scanf("%d",&alloc[i][j]);
}
}
printf("enter the available resource:\n");
for(i=0;i<r;i++)
scanf("%d",&avail[i]);
for(i=0;i<p;i++)
for(j=0;j<r;j++)
need[i][j]=max[i][j]-alloc[i][j];
do
{
printf("\nmax matrix\tallocation matrix:\n");
for(i=0;i<p;i++)
{
for(j=0;j<r;j++)
printf("%d",max[i][j]);
printf("\t\t");
for(j=0;j<r;j++)
printf("%d",alloc[i][j]);
printf("\n");
}
process=-1;
for(i=0;i<p;i++)
{
if(completed[i]==0)
{
process=i;
for(j=0;j<r;j++)
{
if(avail[j]<need[i][j])
{
process=-1;
break;
}
}
}
if(process!=-1)
break;
}
if(process!=-1)
{
printf("process runs to completion %d\n",process+1);
selfsequence[count]=process+1;
count++;
for(j=0;j<r;j++)
{
avail[j]+=alloc[process][j];
alloc[process][j]=0;
max[process][j]=0;
completed[process]=1;
}
}
}
while(count!=p&&process!=-1);
if(count==p)
{
printf("The system is in a safestate\n");
printf("safe sequence:");
for(i=0;i<p;i++)
{
printf("%d",selfsequence[i]);
printf(">\n");
}
}
else
printf("the file system is in unsafe state\n");
}
}
Expected Output:
#include<stdio.h>
#include<stdlib.h>
void FIFO(char [ ],char [ ],int,int);
void lru(char [ ],char [ ],int,int);
void opt(char [ ],char [ ],int,int);
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\t4: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 4:
exit(0);
}
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\t FRAMES\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++)
{
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,cnt=0,top=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++)
{
Dept. of CSE, Atria Institute of Technology Jan 2020 47|5 1
System Software and Operating System Lab 17CSL67
F[k]=F[k+1];
}
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;
}
}
Expected Output:
7. VIVA QUESTIONS