Sie sind auf Seite 1von 83

NAZEER HUSSAIN UNIVERSITY

FACULTY LABORATORY MANUAL

For

COMPILER DESIGN

compilled by

Adnan Alam Khan

DEPARTMENT OF

COMPUTER SCIENCE AND ENGINEERING


CERTIFICATE

Name of the Laboratory : COMPILER DESIGN

Name of the Faculty : Mr.Adnan Alam Khan

Department : CS

Program : B.S

Year : III

Semester :I

IQAC Members:

Name(s):

Signature(s):
HOD
INDEX

PROGRAM Page
SNO DESCRIPTION
NO. No.
1 LAB OBJECTIVE
2 UNIVERSITY / JNTU Syllabus
3 List of Programs
4 SCHEDULE/CYCLE CHART
Design a lexical analyzer for given language and
5 1 the lexical analyzer should ignore redundant 1
spaces, tabs and new lines.
6 2 Simulate First and Follow of a Grammar. 6
Develop an operator precedence parser for a
7 3 13
given language.
Construct a recursive descent parser for an
8 4 18
expression.
9 5 Construct a LL(1) parser for an expression. 25
10 6 Design predictive parser for the given language. 32
Implementation of shift reduce parsing
11 7 41
algorithm.
Design a LALR bottom up parser for the given
12 8 45
language.
Implement the lexical analyzer using JLex, flex
13 9 47
or lex or other lexical analyzer generating tools.
14 10 Write a program to perform loop unrolling. 51
Convert the BNF rules into YACC form and
15 11 54
write code to generate abstract syntax tree.
16 12 Write a program for constant propagation. 60
Additional Programs
Write a program to check whether a string
17 13 62
belongs to a grammar or not
Write a program to find out whether given
18 14 66
string is identifier or not
19 APPENDIX
20 REFERENCE
Lab Objective

1. To provide an Understanding of the language translation peculiarities by


designing complete translator for mini language.
2. To provide an understanding of the design aspect of operating system.

After this lab the student will able to learn

1. Acquire knowledge in different phases and passes of Compiler, and specifying


different types of tokens by lexical analyzer, and also able to use the Compiler
tools like LEX, YACC, etc.
2. Parser and its types i.e. Top-down and Bottom-up parsers.
3. Construction of LL, SLR, CLR and LALR parse table.
4. Techniques for code optimization.
5. Different techniques of symbol table organization and Code generation and its
limitations.

Co to po mapping:

Subject Course outcomes A B C D E F G H I J K L

Compiler Acquire knowledge in different


Design phases and passes of Compiler, and
specifying different types of tokens by
lexical analyzer, and also able to use
the Compiler tools like LEX, YACC,
etc.
Parser and its types i.e. Top-down and
Bottom-up parsers,
Construction of LL,SLR, CLR and
LALR parse table.
Techniques for code optimization.
Program1:

Aim: Design a lexical analyzer for given language and the lexical analyzer should
ignore redundant spaces, tabs and new lines.

Algorithm:

Step 1: Declare the necessary variables.


Step2:Declare an array and store the
keywords in that array
Step 3: Open the input file in read open
Step 4:read the string from the file till the end of file.
Step 4.1:If the first character in the strings # then print that string as
header file.
Step 4.2:If the string matches with any of the keywords print
That string isa keyword
Step 4.3:If the string matches with operator and special
Symbols print the corresponding message
Step 4.4 : If the string is not a keyword then prints that as an identifier.

Source code:
#include<string.h>
#include<ctype.h>
#include<stdio.h>
void keyword(char str[10])
{
if(strcmp("for",str)==0||strcmp("while",str)==0||strcmp("do",str)==0||strcmp(
"int",str
)==0||strcmp("float",str)==0||strcmp("char",str)==0||strcmp("double",str)==0
||strcmp("static",str)==0||strcmp("switch",str)==0||strcmp("case",str)==0)
printf("\n%s is a keyword",str);
else
printf("\n%s is an identifier",str);
}
main()
{
FILE *f1,*f2,*f3;
char c,str[10],st1[10];
int num[100],lineno=0,tokenvalue=0,i=0,j=0,k=0;
printf("\nEnter the c program");/*gets(st1);*/
f1=fopen("input","w");
1|Page
while((c=getchar())!=EOF)
putc(c,f1);
fclose(f1);
f1=fopen("input","r");
f2=fopen("identifier","w");
f3=fopen("specialchar","w");
while((c=getc(f1))!=EOF)
{
if(isdigit(c))
{
tokenvalue=c-'0';
c=getc(f1);
while(isdigit(c))
{
tokenvalue*=10+c-'0';
c=getc(f1);
}
num[i++]=tokenvalue;
ungetc(c,f1);
}
else
if(isalpha(c))
{
putc(c,f2);
c=getc(f1);
while(isdigit(c)||isalpha(c)||c=='_'||c=='$')
{
putc(c,f2);
c=getc(f1);
}
putc(' ',f2);
ungetc(c,f1);
}
else
if(c==' '||c=='\t')
printf(" ");
else
if(c=='\n')
lineno++;
else
putc(c,f3);
}
fclose(f2);

2|Page
fclose(f3);
fclose(f1);
printf("\nThe no's in the program are");
for(j=0;j<i;j++)
printf("%d",num[j]);
printf("\n");
f2=fopen("identifier","r");
k=0;
printf("The keywords and identifiersare:");
while((c=getc(f2))!=EOF)
{
if(c!=' ')
str[k++]=c;
else
{
str[k]='\0';
keyword(str);
k=0;
}
}
fclose(f2);
f3=fopen("specialchar","r");
printf("\nSpecial characters are");
while((c=getc(f3))!=EOF)
printf("%c",c);
printf("\n");
fclose(f3);
printf("Total no. of lines are:%d",lineno);
}

Expected Output:

Enter the C program


a+b*c
Ctrl-D
The nos in the program are:
The keywords and identifiers are:
a is an identifier and terminal
b is an identifier and terminal
c is an identifier and terminal
Special characters are:
+*
Total no. of lines are: 1

3|Page
Output :

Viva voice questions:

1.what is lexical analysis?


Ans : Input to the parser is a stream of tokens, generated by the lexical analyzer.
2.Type of tokens?
Ans : Token are 5 types

C tokens:
C tokens are the basic buildings blocks in C language which are constructed together to
write a C program.
Each and every smallest individual units in a C program are known as C tokens.
C tokens are of six types. They are,
1. Keywords (eg: int, while),
2. Identifiers (eg: main, total),
3. Constants (eg: 10, 20),
4. Strings (eg: total, hello),
5. Special symbols (eg: (), {}),
6. Operators (eg: +, /,-,*)

4|Page
3.C tokens example program?
Ans : int main()
{
int x, y, total;
x = 10, y = 20;
total = x + y;
Printf (Total = %d \n, total);
}
find tokens in the above program
main identifier
{,}, (,) delimiter
int keyword
x, y, total identifier
main, {, }, (, ), int, x, y, total tokens

4.Real time application C programs for your reference to ?


Ans : 1. C program example Real time Calculator program
2. C program example Real time Bank Application program
5. what are properties Identifiers in C language?

Each program elements in a C program are given a name called identifiers.


Names given to identify Variables, functions and arrays are examples for
identifiers. eg. x is a name given to integer variable in above program.

6. Rules for constructing identifier name in C?

1. First character should be an alphabet or underscore.


2. Succeeding characters might be digits or letter.
3. Punctuation and special characters arent allowed except underscore.
4. Identifiers should not be keywords.

7.Keywords in C language?

Keywords are pre-defined words in a C compiler.


Each keyword is meant to perform a specific function in a C program.
Since keywords are referred names for compiler, they cant be used as variable
name.
Example : for,do,while,if,case and etc

5|Page
Program2:

Aim :Simulate First and Follow of a Grammar.

ALGORITHM for first:


Step 1: Start
Step 2: Declare FILE *fp
Step 3: open the file in.txt in write mode
Step 4: Read the Productions
Step 5: Compute First function
Step 6: stop the procuctions.
Function first:
Step1 : If X is a terminal then First(X) is just X!
Step2: If there is a Production X then add to first(X)
Step3: If there is a Production X Y1Y2..Yk then add first(Y1Y2..Yk)
to first(X)
First(Y1Y2..Yk) is either First(Y1) (if First(Y1) doesn't contain )OR (if
First(Y1) does contain ) then First (Y1Y2..Yk) is everything in First(Y1)
<except for > as well as everything in First(Y2..Yk)
Step4 : If First(Y1) First(Y2)..First(Yk) all contain then add to
First(Y1Y2..Yk) as well.

ALGORITHM for follow:


Step 1: Start
Step 2: Declare FILE *fp
Step 3: open the file in.txt in write mode
Step 4: Read the follow Productions
Step 5: Compute First function
Step 6: stop the procuctions.

Function Follow :
Step1:First put $ (the end of input marker) in Follow(S) (S is the start
symbol)
Step2:If there is a production A aBb, (where a can be a whole string)
then everything in FIRST(b) except for is placed in
FOLLOW(B).
Step3:If there is a production A aB, then everything in FOLLOW(A)
is in FOLLOW(B)
Step4 :If there is a production A aBb, where FIRST(b) contains , then everything
in FOLLOW(A) is in FOLLOW(B)
Source code:
#include<stdio.h>

6|Page
#include<string.h>
int i,j,l,m,n=0,o,p,nv,z=0,x=0;
char str[10],temp,temp2[10],temp3[20],*ptr;
struct prod
{
char lhs[10],rhs[10][10],ft[10],fol[10];
int n;
}pro[10];
void findter()
{
int k,t;
for(k=0;k<n;k++)
{
if(temp==pro[k].lhs[0])
{
for(t=0;t<pro[k].n;t++)
{
if( pro[k].rhs[t][0]<65 || pro[k].rhs[t][0]>90 )
pro[i].ft[strlen(pro[i].ft)]=pro[k].rhs[t][0];
else if( pro[k].rhs[t][0]>=65 && pro[k].rhs[t][0]<=90 )
{
temp=pro[k].rhs[t][0];
if(temp=='S')
pro[i].ft[strlen(pro[i].ft)]='#';
findter();
}
}
break;
}
}
}
void findfol()
{
int k,t,p1,o1,chk;
char *ptr1;
for(k=0;k<n;k++)
{
chk=0;
for(t=0;t<pro[k].n;t++)
{
ptr1=strchr(pro[k].rhs[t],temp);
if( ptr1 )
{

7|Page
p1=ptr1-pro[k].rhs[t];
if(pro[k].rhs[t][p1+1]>=65 && pro[k].rhs[t][p1+1]<=90)
{
for(o1=0;o1<n;o1++)
if(pro[o1].lhs[0]==pro[k].rhs[t][p1+1])
{
strcat(pro[i].fol,pro[o1].ft);
chk++;
}
}
else if(pro[k].rhs[t][p1+1]=='\0')
{
temp=pro[k].lhs[0];
if(pro[l].rhs[j][p]==temp)
continue;
if(temp=='S')
strcat(pro[i].fol,"$");
findfol();
chk++;
}
else
{
pro[i].fol[strlen(pro[i].fol)]=pro[k].rhs[t][p1+1];
chk++;
}
}
}
if(chk>0)
break;
}
}
int main()
{
FILE *f;
clrscr();

for(i=0;i<10;i++)
pro[i].n=0;
f=fopen("tab5.txt","r");
while(!feof(f))
{
fscanf(f,"%s",pro[n].lhs);
if(n>0)

8|Page
{
if( strcmp(pro[n].lhs,pro[n-1].lhs) == 0 )
{
pro[n].lhs[0]='\0';
fscanf(f,"%s",pro[n-1].rhs[pro[n-1].n]);
pro[n-1].n++;
continue;
}
}
fscanf(f,"%s",pro[n].rhs[pro[n].n]);
pro[n].n++;
n++;
}
printf("\n\nTHE GRAMMAR IS AS FOLLOWS\n\n");
for(i=0;i<n;i++)
for(j=0;j<pro[i].n;j++)
printf("%s -> %s\n",pro[i].lhs,pro[i].rhs[j]);

pro[0].ft[0]='#';
for(i=0;i<n;i++)
{
for(j=0;j<pro[i].n;j++)
{
if( pro[i].rhs[j][0]<65 || pro[i].rhs[j][0]>90 )
{
pro[i].ft[strlen(pro[i].ft)]=pro[i].rhs[j][0];
}
else if( pro[i].rhs[j][0]>=65 && pro[i].rhs[j][0]<=90 )
{
temp=pro[i].rhs[j][0];
if(temp=='S')
pro[i].ft[strlen(pro[i].ft)]='#';
findter();
}
}
}
printf("\n\nFIRST\n");
for(i=0;i<n;i++)
{
printf("\n%s -> ",pro[i].lhs);
for(j=0;j<strlen(pro[i].ft);j++)
{
for(l=j-1;l>=0;l--)

9|Page
if(pro[i].ft[l]==pro[i].ft[j])
break;
if(l==-1)
printf("%c",pro[i].ft[j]);
}
}
for(i=0;i<n;i++)
temp2[i]=pro[i].lhs[0];
pro[0].fol[0]='$';
for(i=0;i<n;i++)
{
for(l=0;l<n;l++)
{
for(j=0;j<pro[i].n;j++)
{
ptr=strchr(pro[l].rhs[j],temp2[i]);
if( ptr )
{
p=ptr-pro[l].rhs[j];
if(pro[l].rhs[j][p+1]>=65 && pro[l].rhs[j][p+1]<=90)
{
for(o=0;o<n;o++)
if(pro[o].lhs[0]==pro[l].rhs[j][p+1])
strcat(pro[i].fol,pro[o].ft);
}
else if(pro[l].rhs[j][p+1]=='\0')
{
temp=pro[l].lhs[0];
if(pro[l].rhs[j][p]==temp)
continue;
if(temp=='S')
strcat(pro[i].fol,"$");
findfol();
}
else
pro[i].fol[strlen(pro[i].fol)]=pro[l].rhs[j][p+1];
}
}
}
}

printf("\n\nFOLLOW\n");
for(i=0;i<n;i++)

10 | P a g e
{
printf("\n%s -> ",pro[i].lhs);
for(j=0;j<strlen(pro[i].fol);j++)
{
for(l=j-1;l>=0;l--)
if(pro[i].fol[l]==pro[i].fol[j])
break;
if(l==-1)
printf("%c",pro[i].fol[j]);
}
}
printf("\n");
getch();
}

Expected Output :
At
B Aq
S f
Aw
FIRST
S #pta
A pt
B pt
Sf
Aw
FOLLOW
S$
Aptq
B
S
Aptq
$pt

11 | P a g e
Output :

Viva voice question :

1. Rules for First Sets?

Ans 1. If X is a terminal then First(X) is just X!


2. If there is a Production X then add to first(X)
3.If there is a Production X Y1Y2..Yk then add first(Y1Y2..Yk) to first(X)
4.First(Y1Y2..Yk) is either
4.1)First(Y1) (if First(Y1) doesn't contain )
4.2)OR(if First(Y1) does contain ) then First (Y1Y2..Yk) is everything
in First(Y1) <except for > as well as everything in First(Y2..Yk)
4.3)first(Y1) First(Y2)..First(Yk) all contain then add to
first(Y1Y2..Yk) as well.

2. Rules for Follow Sets?

1. First put $ (the end of input marker) in Follow(S) (S is the start symbol)
2. If there is a production A aBb, (where a can be a whole string) then everything
in FIRST(b) except for is placed in FOLLOW(B).

12 | P a g e
3. If there is a production A aB, then everything in FOLLOW(A) is in
FOLLOW(B)
4. If there is a production A aBb, where FIRST(b) contains , then everything in
FOLLOW(A) is in FOLLOW(B)

3. Find first terms for given grammer?

E TE'

E' +TE'
E'
T FT'
T' *FT'
T'
F (E)
F id
Ans : FIRST(E) = {'(',id}
FIRST(E') = {+,}
FIRST(T) = {'(',id}
FIRSTFOLLOW(E') = {$,)}
FOLLOW(T) = {+,$,)}
FOLLOW(T') = {+,$,)}
FOLLOW(F) = {*,+,$,)}
(T') = {*,}
FIRST(F) = {'(',id}
4. Find FOLLOW(E) terms for above grammer?
Ans: FOLLOW(E) = {$,)}

13 | P a g e
Program3:
Aim :Develop an operator precedence parser for a given language.

Algorithm :

Step 1: Push # onto stack


Step 2: Read first input symbol and push it onto stack
Step 3: Do
Obtain OP relation between the top terminal symbol on the stack
and the next input symbol
If the OP relation is < or =
i. Pop top of the stack into handle, include non-terminalsymbol if
appropriate.
ii. Obtain the relation between the top terminal symbol on
the stack and the leftmost terminal symbol in the handle .
iii. While the OP relation between terminal symbols is =o Do
Pop top terminal symbol and associated non-
terminal symbol on stack into handle.
Obtain the OP relation between the top terminal
symbol on the stack and the leftmost terminal
symbol in the handle.
iv. Match the handle against the RHS of all productions v.
Push N onto the stack
Step 4: Until end-of-file and only and N are on the stack

Source code:

#include <stdio.h>
#include <string.h>
#include <conio.h>
char stack[20],stack1[20],next,s[10];
int top=-1;
char prod[9][10]={">><<<<<>>",">><<<<<>>",">>>><<<>>",
">>>><<<>>",
">>>><<<>>",
">>>>>ee>>",
"<<<<<<<=e",
">>>>>ee>>",
"<<<<<<" };
char G[7][6]={
"E->E+E",

14 | P a g e
" /E-E",
" /E*E",
" /E/E",
" /(E)",
" /i "
};
void main()
{
char symbol,G[10][10];
int i=0,flag=0;
int j,k;
clrscr();
printf("Grammar\n");
for(j=0;j<7;j++)
{
for(k=0;k<6;k++)
printf("%c",G[j][k]);
printf("\n");
}
printf("\n\n OPERATOR PRECEDENCE RELATIONS \n");
printf("\n -------------------------------------------------------- \n");
printf("%c\t%c\t%c\t%c\t%c\t%c\t%c\t%c\t%c\t",'+','-','*','/','^','i','(',')','$');
printf("\n------------------------------------------------------------------\n");
for(j=0;j<9;j++)
{
for(k=0;k<10;k++)
printf("%c\t",prod[j][k]);
printf("\n");
}
printf("Enter the string : ");
gets(s);
++top;
stack[top]='$';
next=s[i];
while(1)
{
if(stack[top]=='$'&& next=='$'||next=='\0')
break;
else
{
symbol=prod[f(stack[top])][f(next)];
if(symbol=='<'||symbol=='=')
{

15 | P a g e
stack[++top]=symbol;
stack[++top]=next;
}
else if(symbol=='>')
{
do
{
top--;
}while(stack[top]!='<');
stack[++top]=next;
if(next!='$')
{
for(j=0;j<=top;j++)
stack1[j]=stack[j];
stack1[j]=symbol;
}
}
else
flag=1;
next=s[++i];
}
}
printf("\n STACK : ");
for(j=0;j<=top;j++)
printf("%c",stack1[j]);
printf("%c",'$');
if(flag==0)
printf("\n\n Accepted");
else
printf("Rejected");
getch();
}
int f(char ch)
{
switch(ch)
{
case '+':return 0;
case '-':return 1;
case '*':return 2;
case '/':return 3;
case '^':return 4;
case 'i':return 5;
case '(':return 6;

16 | P a g e
case ')':return 7;
case '$':return 8;
default :
{
printf("\n ERROR ");
exit(0);
}
}
}

Expected Output:

+ - * / ^ i ( ) $
> > < < < < < > >
> > < < < < < > >
> > > > < < < > >
> > > > < < < > >
> > > > < < < > >
> > > > > e e > >
< < < < < < < = e
> > > > > e e > >
< < < < < <

Enter the string : i+i*i$


STACK : $(+(*))$
Accepted

Output:

17 | P a g e
Viva voice questions :

1. What is user of operator grammer?

Ans : Bottom-up parsers for a large class of context-free grammars


can be easily developed using operator grammars.

2. What is operator grammer?

Ans: Operator grammars have the property that no production right side is empty or
has two adjacent nonterminals.

3. Precedence relation table ?

Ans:
Relation Meaning

a < b a yields precedence to b

a = b a has the same precedence as b

a >b a takes precedence over b

For example, the following operator precedence relations canbe introduced for
simple expressions

id + * $

id > > >

+ < > < >

* < > > >

$ < < < >

4. The input string: id1 + id2 * id3after inserting precedence relations becomes?

Ans : $ < id1 > + < id2>* < id3 > $

5. Having precedence relations allows to identify handles as follows?

Ans : - scan the string from left until seeing >


- scan backwards the string from right to left until seeing <
- everything between the two relations < and > forms the handle
7. Operator Precedence Parsing Algorithm ?
Ans : Initialize: Set ip to point to the first symbol of w$
Repeat: Let X be the top stack symbol, and a the symbol pointed to by ip

18 | P a g e
if $ is on the top of the stack and ip points to $ then return
else
Let a be the top terminal on the stack, and b the symbol pointed to by ip
ifa < b or a = b then
push b onto the stack
advance ip to the next input symbol
else if a >bthen
repeat
pop the stack
until the top stack terminal is related by <
to the terminal most recently popped
else error()
end

19 | P a g e
Program4:

Aim: Construct a recursive descent parser for an expression.

Theory:

For factoring:
Give a set of productions of the form
A1|2||n
Invent a new nonterminal Z and replace this set by the collection:
AZ
Z1|2|n
For substitution:
If we are given a grammar containing AB and if all of the productions with B on the
left side are:
B1|2|n

ALGORITHM:

Step 1: start.
Step 2: Declare the prototype functions E() , EP(),T(), TP(),F()
Step 3: Read the string to be parsed.
Step 4: Check the productions
Step 5: Compare the terminals and Non-terminals
Step 6: Read the parse string.
Step 7: stop the production

Source code:
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
char ip_sym[15],ip_ptr=0,op[50],tmp[50];
void e_prime();
void e();

20 | P a g e
void t_prime();
void t();
void f();
void advance();
int n=0,flag=1;
void e()
{
strcpy(op,"TE'");
printf("E=%-25s",op);
printf("E->TE'\n");
t();
e_prime();
}
void e_prime()
{
int i,n=0,l;
for(i=0;i<=strlen(op);i++)
if(op[i]!='e')
tmp[n++]=op[i];
strcpy(op,tmp);
l=strlen(op);
for(n=0;n < l && op[n]!='E';n++);
if(ip_sym[ip_ptr]=='+')
{
i=n+2;
do
{
op[i+2]=op[i];
i++;
}while(i<=l);
op[n++]='+';
op[n++]='T';
op[n++]='E';
op[n++]=39;
printf("E=%-25s",op);
printf("E'->+TE'\n");
advance();
t();
e_prime();
}
else
{
op[n]='e';

21 | P a g e
for(i=n+1;i<=strlen(op);i++)
op[i]=op[i+1];
printf("E=%-25s",op);
printf("E'->e");
}
}
void t()
{
int i,n=0,l;
for(i=0;i<=strlen(op);i++)
if(op[i]!='e')
tmp[n++]=op[i];
strcpy(op,tmp);
l=strlen(op);
for(n=0;n < l && op[n]!='T';n++);
i=n+1;
do
{
op[i+2]=op[i];
i++;
}while(i < l);
op[n++]='F';
op[n++]='T';
op[n++]=39;
printf("E=%-25s",op);
printf("T->FT'\n");
f();
t_prime();
}
void t_prime()
{
int i,n=0,l;
for(i=0;i<=strlen(op);i++)
if(op[i]!='e')
tmp[n++]=op[i];
strcpy(op,tmp);
l=strlen(op);
for(n=0;n < l && op[n]!='T';n++);
if(ip_sym[ip_ptr]=='*')
{
i=n+2;
do
{

22 | P a g e
op[i+2]=op[i];
i++;
}
while(i < l);
op[n++]='*';
op[n++]='F';
op[n++]='T';
op[n++]=39;
printf("E=%-25s",op);
printf("T'->*FT'\n");
advance();
f();
t_prime();
}
else
{
op[n]='e';
for(i=n+1;i<=strlen(op);i++)
op[i]=op[i+1];
printf("E=%-25s",op);
printf("T'->e\n");
}
}

void f()
{
int i,n=0,l;
for(i=0;i<=strlen(op);i++)
if(op[i]!='e')
tmp[n++]=op[i];
strcpy(op,tmp);
l=strlen(op);
for(n=0;n < l && op[n]!='F';n++);
if((ip_sym[ip_ptr]=='i')||(ip_sym[ip_ptr]=='I'))
{
op[n]='i';
printf("E=%-25s",op);
printf("F->i\n");
advance();
}
else
{
if(ip_sym[ip_ptr]=='(')

23 | P a g e
{
advance();
e();
if(ip_sym[ip_ptr]==')')
{
advance();
i=n+2;
do
{
op[i+2]=op[i];
i++;
}
while(i<=l);
op[n++]='(';
op[n++]='E';
op[n++]=')';
printf("E=%-25s",op);
printf("F->(E)\n");
}
}
else
{
printf("\n\t syntax error"); flag=0;
getch();
exit(1);
}
}
}
void advance()
{
ip_ptr++;
}

void main()
{
int i;
clrscr();
printf("\nGrammar without left recursion");
printf("\n\t\t E->TE' \n\t\t E'->+TE'|e \n\t\t T->FT' ");
printf("\n\t\t T'->*FT'|e \n\t\t F->(E)|i");
printf("\n Enter the input expression:");
gets(ip_sym);
printf("Expressions");

24 | P a g e
printf("\t Sequence of production rules\n");
e();
for(i=0;i < strlen(ip_sym);i++)
{
if(ip_sym[i]!='+'&&ip_sym[i]!='*'&&ip_sym[i]!='('&&
ip_sym[i]!=')'&&ip_sym[i]!='i'&&ip_sym[i]!='I')
{
printf("\nSyntax error");
break;
}
for(i=0;i<=strlen(op);i++)
if(op[i]!='e')
tmp[n++]=op[i];
strcpy(op,tmp);
printf("\nE=%-25s",op);
}
If(flag==1)
Printf(accepted);
getch();
}

Expected output :

Grammer without left recursion


E TE
E+TE|e
TFT
T*FT|e
F(E)|i
Enter the input expression:i+i*i
Expressions Sequence of production rules
E=TE ETE
E=FTE TFT
E=iTE Fi
E=ieE Te
E=i+TE E+TE
E=i+FTE TFT
E=i+iTE Fi
E=i+i*FTE T*FT
E=i+i*iTE Fi
E=i+i*ieE Te
E=i+i*ie Ee
E=i+i*I accepted

25 | P a g e
Output :

Viva voice questions :


1. what type of parsing it is ?
Ans : it is topdown parser.
2. what is Recursive descent parser?

Ans : Recursive descent parsing associates a procedure with each nonterminal in the
grammar, it may require backtracking of the input string.

3. Recursive descent parsing may require backtracking of the input string?

Ans:1) try out all productions, backtrack if necessary.


2)E.g S->cAd, A->ab | a
3) input string cad

4. what is recursive descent parser?

Ans :Itis a kind of top-down parser built from a set of mutually recursive procedures (or
a non-recursive equivalent) where each such procedure usually implements one of the
productions of the grammar.

5. What ate Parsing expressions by recursive descent poses two classic problems?
26 | P a g e
Ans :How to get the abstract syntax tree (or other output) to follow the
precedenceand associativity of operators.

Program5:

Aim : Construct a LL(1) parser for an expression.

Algorithm :

Step1 : If A is a production choice, and there is a derivation


a,where a is a token, then we add A to the table entry M[A, a].
Step 2 : If A is a production choice, and there are derivations
andS$ Aa, where S is the start symbol and a is a token (or $),
then we add A to the table entry M[A, a]

Source code:

#include<stdio.h>
#include<conio.h>
void main()
{
char pro[10][10],first[10][10],follow[10][10],nt[10],ter[10],res[10][10][10],temp[10];
int npro,noter=0,nont=0,i,j,k,flag=0,count[10][10],row,col,l,m,n,index;
clrscr();
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
count[i][j]=NULL;
for(k=0;k<10;k++){
res[i][j][k]=NULL; }
}
}
printf("Enter the no of productions:");
scanf("%d",&npro);
printf("Enter the productions:");
for(i=0;i<npro;i++)
{
scanf("%s",pro[i]);
}

27 | P a g e
for(i=0;i<npro;i++)
{
flag=0;
for(j=0;j<nont;j++)
{
if(nt[j]==pro[i][0])
{
flag=1;
}
}
if(flag==0)
{
nt[nont]=pro[i][0];
nont++;
}
}
printf("\nEnter the first values:\n");
for(i=0;i<nont;i++)
{
printf("First value(%c):",nt[i]);
scanf("%s",first[i]);
}
printf("\nEnter the follow values:\n");
for(i=0;i<nont;i++)
{
printf("Follow value(%c):",nt[i]);
scanf("%s",follow[i]);
}
for(i=0;i<nont;i++)
{
flag=0;
for(j=0;j<strlen(first[i]);j++)
{
for(k=0;k<noter;k++)
{
if(ter[k]==first[i][j])
{
flag=1;
}
}
if(flag==0)
{
if(first[i][j]!='#')

28 | P a g e
{
ter[noter]=first[i][j];
noter++;
}
}
}
}
for(i=0;i<nont;i++)
{
flag=0;
for(j=0;j<strlen(follow[i]);j++)
{
for(k=0;k<noter;k++)
{
if(ter[k]==follow[i][j])
{
flag=1;
}
}
if(flag==0)
{
ter[noter]=follow[i][j];
noter++;
}
}
}
for(i=0;i<nont;i++)
{
for(j=0;j<strlen(first[i]);j++)
{
flag=0;
if(first[i][j]=='#')
{
col=i;
for(m=0;m<strlen(follow[col]);m++)
{
for(l=0;l<noter;l++)
{
if(ter[l]==follow[col][m])
{
row=l;
}
}

29 | P a g e
temp[0]=nt[col];
temp[1]='-' ;
temp[2]='>';
temp[3]='#';
temp[4]='\0';
printf("temp %s",temp);
strcpy(res[col][row],temp);
count[col][row]+=1;
for(k=0;k<10;k++){
temp[k]=NULL; }
}

}
else{
for(l=0;l<noter;l++)
{
if(ter[l]==first[i][j])
{
row=l;
}
}
for(k=0;k<npro;k++){
if(nt[i]==pro[k][0])
{
col=i;
if((pro[k][3]==first[i][j])&&(pro[k][0]==nt[col]))
{
strcpy(res[col][row],pro[k]);
count[col][row]+=1;
}
else
{
if((isupper(pro[k][3]))&&(pro[k][0]==nt[col]))
{
flag=0;
for(m=0;m<nont;m++)
{
if(nt[m]==pro[k][3]){index=m;flag=1;}
}
if(flag==1){
for(m=0;m<strlen(first[index]);m++)
{if(first[i][j]==first[index][m])
{strcpy(res[col][row],pro[k]);

30 | P a g e
count[col][row]+=1;}
}
}
}}}}}
}}
printf("LL1 Table\n\n");
flag=0;
for(i=0;i<noter;i++)
{
printf("\t%c",ter[i]);
}
for(j=0;j<nont;j++)
{
printf("\n\n%c",nt[j]);
for(k=0;k<noter;k++)
{
printf("\t%s",res[j][k]);
if(count[j][k]>1){flag=1;}
}
}
if(flag==1){printf("\nThe given grammar is not LL1");}
else{printf("\nThe given grammar is LL1");}
getch();
}

Expected Output:

Enter the productions : SiEdSA


Sa
AEs
Ae
Eb
Enter the first values:
First values(s):a i
First values(A):$ e
First values(E):b

Ener the follow values:


Follow values(S):$ e
Follow values(A):$ e
Follow values(E):t
LL1 Table
a $ b t

31 | P a g e
S Sa
A
E Eb
The given grammar is LL1

Output :

Viva voice questions:

1. What is LL(1)?
Ans: The parsing table entries are single entries. So each location has not more than
one entry.
This type of grammar is called LL(1) grammar.
2. How to element left factoring for give grammer?
Ans : Consider this following grammar:
S iEtS | iEtSeS | a
Eb
After eliminating left factoring, we have
S iEtSS | a
S eS |
Eb
3. Find first set of terminals for above grammer?
Ans: FIRST(S) = { i, a }
FIRST(S) = {e, }

32 | P a g e
FIRST(E) = { b}
4. Find FOLLOW set of terminals of above grammer?
Ans :FOLLOW(S) = { $ ,e }
FOLLOW(S) = { $ ,e }
FOLLOW(E) = {t}
5. Is the parsing TABLE is given bellow either LL(1) or not?

Ans: NO, Since there are more than one production, the grammar is not LL(1)
grammar.

33 | P a g e
Program6:

Aim : Design predictive parser for the given language.

Algorithm :

STEP 1: X symbol on top of stack,a current input symbol


STEP 2: Stack contents and remaining input called parser configuration
(initially $S on stack and complete inputstring)
2.1.If X=a=$ halt and announce success
2.2.If X=a$ pop X off stack advance input to next symbol
2.3.If X is a non-terminal use M[X ,a] which contains
production
STEP 3: X->rhs or error replace X on stack with rhs or call error
routine, respectively.
EX: X->UVW replace X with WVU(U on top) output the
production (or augment parse tree)

Source code:

#include<stdio.h>
#include<string.h>
# define SIZE 30
char st[100];
int top=-1;
int s1(char),ip(char);
int n1,n2;
char nt[SIZE],t[SIZE];
/*Function to return variable index*/
int s1(char c)
{
int i;
for(i=0;i<n1;i++)
{
if(c==nt[i])
return i;
}

34 | P a g e
}
/*Function to return terminal index*/
int ip(char c)
{
int i;
for(i=0;i<n2;i++)
{
if(c==t[i])
return i;
}
}

void push(char c)
{
top++;
st[top]=c;
return;
}

void pop()
{
top--;
return;
}
main()
{
char table[SIZE][SIZE][10],input[SIZE];
int x,f,s,i,j,u;
printf("Enter the number of variables:");
scanf("%d",&n1);
printf("\nUse single capital letters for variables\n");
for(i=0;i<n1;i++)
{
printf("Enter the %d nonterminal:",i+1);
scanf("%c",&nt[i]);
}
printf("Enter the number of terminals:");
scanf("%d",&n2);
printf("\nUse single small letters for terminals\n");
for(i=0;i<n2;i++)
{
printf("Enter the %d terminal:",i+1);
scanf("%c",&t[i]);

35 | P a g e
}
/*Reading the parsing table*/
printf("Please enter only right sides of productions\n");
printf("Use symbol n to denote no entry and e to epsilon\n");
for(i=0;i<n1;i++)
{
for(j=0;j<n2;j++)
{
printf("\nEnter the entry for %c under %c:",nt[i],t[j]);
scanf("%s",table[i][j]);
}
}
/*Printing the parsing taable*/
for(i=0;i<n2;i++)
printf("\t%c",t[i]);
printf("\n---------------------------------------------------------\n");
for(i=0;i<n1;i++)
{
printf("\n%c|\t",nt[i]);
for(j=0;j<n2;j++)
{
if(!strcmp(table[i][j],"n"))
printf("\t");
else
printf("%s\t",Table[i][j]);
}
printf("\n");
}
printf("Enter the input:");
scanf("%s",input);
/*Initialising the stack*/
top++;
st[top]='$';
top++;
st[top]=nt[0];
printf("STACK content INPUT content PRODUCTION used\n");
printf("--------------------------------------------------------------\n");
i=0;
printf("$%c\t\t\t%s\n\n",st[top],input);
while(st[top]!='$')
{
x=0;
f=s1(st[top]);

36 | P a g e
s=ip(input[i]);
if(!strcmp(table[f][s],"n"))
{
printf("'String not accepted");
}
else
if(!strcmp(table[f][s],"e"))
{
pop();
}
else
if(st[top]==input[i])
{
x=1;
pop();
i++;
}
else
{
pop();
for(j=strlen(table[f][s])-1;j>0;j--)
{
{
push(table[f][s][j]);
}
}
for(u=0;u<=top;u++)
printf("%c",st[u]);
printf("\t\t\t");
for(u=i;input[u]!='\0';u++)
printf("%c",input[u]);
printf("\t\t\t");
if(x==0)
printf("%c->%s\n\n",nt[f],table[f][s]);
printf("'\n\n");
}
printf("\n\nThus string is accepted");
}
}

Expected Output:

Enter the number of variables:5


37 | P a g e
Use single capital letters for the variables
Enter the 1 non terminal:E
Enter the 2 non terminal:A
Enter the 3 non terminal:T
Enter the 4 non terminal:B
Enter the 5 non terminal:F
Enter the number of terminals:6
Use only single small letter for the terminals
Enter the 1 terminal:+
Enter the 2 terminal:*
Enter the 3 terminal:(
Enter the 4 terminal:)
Enter the 5 terminal:i
Enter the 6 terminal:$
Please enter only the right sides of productions.
Use symbol n to denote noentry and e to epsilon
Enter the entry for E under $: n
Enter the entry for E under +: n
Enter the entry for E under *: n
Enter the entry for E under (: TA
Enter the entry for E under ): n
Enter the entry for E under i: TA
Enter the entry for A under +: +TA
Enter the entry for A under *: n
Enter the entry for A under (: n
Enter the entry for A under ): e
Enter the entry for A under i: n
Enter the entry for A under $: e
Enter the entry for T under +: n
Enter the entry for T under *: n
Enter the entry for T under (: FB
Enter the entry for T under ): n
Enter the entry for T under i: FB
Enter the entry for T under $: n
Enter the entry for B under +: e
Enter the entry for B under *: *FB
Enter the entry for B under (: n
Enter the entry for B under ): e
Enter the entry for B under i: n
Enter the entry for B under $: e
Enter the entry for F under +: n
Enter the entry for F under *: n
Enter the entry for F under (: (E)

38 | P a g e
Enter the entry for F under ): n
Enter the entry for F under i: i
Enter the entry for F under $: n
+ * ( ) i $
-----------------------------------------------------------------------------
E| TA TA
A| +TA e e
T| FB FB
B| e *FB e e
F| (E) i
Enter the input: i+i*i$

Stack content Input content Production used


-----------------------------------------------------------------------------------
$E i+i*i$
$A i+i*i$ E->TA
$AB i+i*i$ T->FB
$AB i+i*i$ F->i
$A +i*i$
$ +i*i$ B->e
$AT +i*i$ A->+TA
$A i*i$
$AB i*i$ T->FB
$AB i*i$ F->i
$A *i$
$ABF *i$ B->*FB
$AB i$
$AB i$ F->i
$A $
$ $ B->e
$ A->e

Thus string is accepted

39 | P a g e
Output:

40 | P a g e
Viva voice questions :
1. what are steps require to construct predictive parser?
Ans : 1. Elimination of left recursion, left factoring and ambiguous grammar.

41 | P a g e
2. Construct FIRST() and FOLLOW() for all non-terminals.
3. Construct predictive parsing table.
4. Parse the given input string using stack and parsing table.

2. Step for predictive parser table ?


Ans :
1.For each production A of the grammar, do steps 2 and 3.
2. For each terminal a in FIRST(), add A to M[A, a].
3. If is in FIRST(), add A to M[A, b] for each terminal b in FOLLOW(A). If
is in FIRST() and $ is in FOLLOW(A) , add A to M[A, $].
4.Make each undefined entry of M be error.

3. what sre rule for FOLLOW?


Ans :
If S is a start symbol, then FOLLOW(S) contains $.
If there is a production A B, then everything in FIRST() except is
placed infollow(B).
If there is a production A B, or a production A B where FIRST() contains
, then everything in FOLLOW(A) is in FOLLOW(B)
4. Rules for FIRST?
Ans :1. If X is terminal, then FIRST(X) is {X}.
2. If X is a production, then add to FIRST(X).
3. If X is non-terminal and X a is a production then add a to FIRST(X).

42 | P a g e
Program7:

Aim :Implementation of shift reduce parsing algorithm.

Algorithm :

STEP1: Initial State: the stack consists of the single state, s0; ip points to the
first character in w.
STEP 2: For top-of-stack symbol, s, and next input symbol, a case action of
T[s,a]
STEP 3: shift x: (x is a STATE number) push a, then x on the top of the stack and
advance ip to point to the next input symbol.
STEP 4: reduce y: (y is a PRODUCTION number) Assume that the production is
of the form A ==> beta pop 2 * |beta| symbols of the stack.
STEP 5: At this point the top of the stack should be a state number, say s. push A, then goto
of T[s,A] (a state number) on the top of the stack.

Source code:

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<string.h>
char ip_sym[15],stack[15];
int ip_ptr=0,st_ptr=0,len,i;
char temp[2],temp2[2];
char act[15];
void check();
void main()
{
clrscr();
printf("\n\t\t SHIFT REDUCE PARSER\n");
printf("\n GRAMMER\n");
printf("\n E->E+E\n E->E/E");
printf("\n E->E*E\n E->a/b");
printf("\n enter the input symbol:\t");
gets(ip_sym);
printf("\n\t stack implementation table");
printf("\n stack\t\t input symbol\t\t action");
printf("\n______\t\t ____________\t\t ______\n");

43 | P a g e
printf("\n $\t\t%s$\t\t\t--",ip_sym);
strcpy(act,"shift ");
temp[0]=ip_sym[ip_ptr];
temp[1]='\0';
strcat(act,temp);
len=strlen(ip_sym);
for(i=0;i<=len-1;i++)
{
stack[st_ptr]=ip_sym[ip_ptr];
stack[st_ptr+1]='\0';
ip_sym[ip_ptr]=' ';
ip_ptr++;
printf("\n $%s\t\t%s$\t\t\t%s",stack,ip_sym,act);
strcpy(act,"shift ");
temp[0]=ip_sym[ip_ptr];
temp[1]='\0';
strcat(act,temp);
check();
st_ptr++;
}
st_ptr++;
check();
}
void check()
{
int flag=0;
temp2[0]=stack[st_ptr];
temp2[1]='\0';
if((!strcmpi(temp2,"a"))||(!strcmpi(temp2,"b")))
{
stack[st_ptr]='E';
if(!strcmpi(temp2,"a"))
printf("\n $%s\t\t%s$\t\t\tE->a",stack, ip_sym);
else
printf("\n $%s\t\t%s$\t\t\tE->b",stack,ip_sym);
flag=1;
}
if((!strcmpi(temp2,"+"))||(strcmpi(temp2,"*"))||(!strcmpi(temp2,"/")))
{
flag=1;
}
if((!strcmpi(stack,"E+E"))||(!strcmpi(stack,"E\E"))||(!strcmpi(stack,"E*E")))
{

44 | P a g e
strcpy(stack,"E");
st_ptr=0;
if(!strcmpi(stack,"E+E"))
printf("\n $%s\t\t%s$\t\t\tE->E+E",stack,ip_sym);
else
if(!strcmpi(stack,"E\E"))
printf("\n $%s\t\t %s$\t\t\tE->E\E",stack,ip_sym);
else
printf("\n $%s\t\t%s$\t\t\tE->E*E",stack,ip_sym);
flag=1;
}

if(!strcmpi(stack,"E")&&ip_ptr==len)
{
printf("\n $%s\t\t%s$\t\t\tACCEPT",stack,ip_sym);
getch();
exit(0);
}
if(flag==0)
{
printf("\n%s\t\t\t%s\t\t reject",stack,ip_sym);
exit(0);
}
return;
}

Expected Output:

GRAMMAR
EE+E
EE/E
EE*E
Ea/b
Enter the input symbol: a+a
Stack implementation table
Stack Input symbol Action

$ a+a$ --

$a +a$ Shift a

$E +a$ Ea

45 | P a g e
$E+ a$ Shift +

$E+a $ Shift a

$E+E $ Ea

$E $ EE*E

$E $ ACCEPT

Output:

Viva voice questions :

1. What type parser it is?


Ans: It is BOTTOM-UP PARSING.
2. What is BOOTOM_UP PARSER?
Ans : Constructing a parse tree for an input string beginning at the leaves and going
towards the root is called bottom-up parsing.
3. What is SHIFT?
Ans : 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.
4. What is REDUCE?
Ans: 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

46 | P a g e
reduce, a POP function is performed on the stack which pops off the handle and
replaces it with LHS non-terminal symbol.
5. What is ACCEPT?
Ans : The parser announces succefully completion parsing.
6. What is error?
Ans : The parser discovers that a syntax error occur and calls error recovery routine.
7. What are the two types of conflicts ?
Ans : 1) shift reduce conflict
2)Reduce reduce conflict
Program 8:

Aim :Design a LALR bottom up parser for the given language.

Algorithm :

STEP 1: Represent Ii by its CLOSURE, those items that are either the initial
item[S .S; eof] or do not have the . at the left end of the rhs.
STEP 2 : Compute shift, reduce, and goto actions for the state derived from Ii directly from
CLOSURE(Ii)
Source code:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
void push(char *,int *,char);
char stacktop(char *);
void isproduct(char,char);
int ister(char);
int isnter(char);
int isstate(char);
void error();
void isreduce(char,char);
char pop(char *,int *);
void printt(char *,int *,char [],int);
void rep(char [],int);
struct action
{
char row[6][5];
};
const struct action A[12]={
{"sf","emp","emp","se","emp","emp"},
{"emp","sg","emp","emp","emp","acc"},
{"emp","rc","sh","emp","rc","rc"},
{"emp","re","re","emp","re","re"},
{"sf","emp","emp","se","emp","emp"},

47 | P a g e
{"emp","rg","rg","emp","rg","rg"},
{"sf","emp","emp","se","emp","emp"},
{"sf","emp","emp","se","emp","emp"},
{"emp","sg","emp","emp","sl","emp"},
{"emp","rb","sh","emp","rb","rb"},
{"emp","rb","rd","emp","rd","rd"},
{"emp","rf","rf","emp","rf","rf"}
};
struct gotol
{
char r[3][4];
};
const struct gotol G[12]={
{"b","c","d"},
{"emp","emp","emp"},
{"emp","emp","emp"},
{"emp","emp","emp"},
{"i","c","d"},
{"emp","emp","emp"},
{"emp","j","d"},
{"emp","emp","k"},
{"emp","emp","emp"},
{"emp","emp","emp"},
};
char ter[6]={'i','+','*',')','(','$'};
char nter[3]={'E','T','F'};
char states[12]={'a','b','c','d','e','f','g','h','m','j','k','l'};
char stack[100];
int top=-1;
char temp[10];
struct grammar
{
char left;
char right[5];
};
const struct grammar rl[6]={
{'E',"e+T"},
{'E',"T"},
{'T',"T*F"},
{'T',"F"},
{'F',"(E)"},
{'F',"i"},
};
void main()
{
char inp[80],x,p,dl[80],y,bl='a';
int i=0,j,k,l,n,m,c,len;
clrscr();

48 | P a g e
printf(" Enter the input :");
scanf("%s",inp);
len=strlen(inp);
inp[len]='$';
inp[len+1]='\0';
push(stack,&top,bl);
printf("\n stack\t\t\t input");
printt(stack,&top,inp,i);
do
{
x=inp[i];
p=stacktop(stack);
isproduct(x,p);
if(strcmp(temp,"emp")==0)
error();
if(strcmp(temp,"acc")==0)
break;
else
{
if(temp[0]=='s')
{
push(stack,&top,inp[i]);
push(stack,&top,temp[1]);
i++;
}
else
{
if(temp[0]=='r')
{
j=isstate(temp[1]);
strcpy(temp,rl[j
-
2].right);
dl[0]=rl[j-2].left;
dl[1]='\0';
n=strlen(temp);
for(k=0;k<2*n;k++)
pop(stack,&top);
for(m=0;dl[m]!='\0';m++)
push(stack,&top,dl[m]);
l=top;
y=stack[l-1];
isreduce(y,dl[0]);
for(m=0;temp[m]!='\0';m++)
push(stack,&top,temp[m]);
}
}
}

49 | P a g e
printt(stack,&top,inp,i);
}while(inp[i]!='\0');
if(strcmp(temp,"acc")==0)
printf("\n accept the input ");
else
printf("\n do not accept the input ");
getch();
}
void push(char *s,int *sp,char item)
{
if(*sp==100)
printf(" stack is full ");
else
{
*sp=*sp+1;
s[*sp]=item;
}
}
char stacktop(char *s)
{
char i;
i=s[top];
return i;
}
void isproduct(char x,char p)
{
int k,l;
k=ister(x);
l=isstate(p);
strcpy(temp,A[l-1].row[k-1]);
}
int ister(char x)
{
int i;
for(i=0;i<6;i++)
if(x==ter[i])
return
i+1;
return 0;
}
int isnter(char x)
{
int i;
for(i=0;i<3;i++)
if(x==nter[i])
return i+1;
return 0;
}

50 | P a g e
int isstate(char p)
{
int i;
for(i=0;i<12;i++)
if(p==states[i])
return i+1;
return 0;
}
void error()
{
printf(" error in the input ");
exit(0);
}
void isreduce(char x,char p)
{
int k,l;
k=isstate(x);
l=isnter(p);
strcpy(temp,G[k-1].r[l-1]);
}
char pop(char *s,int *sp)
{
char item;
if(*sp==-1)
printf(" stack is empty ");
else
{
item=s[*sp];
*sp=*sp-1;
}
return item;
}
void printt(char *t,int *p,char inp[],int i)
{
int r;
printf("\n");
for(r=0;r<=*p;r++)
rep(t,r);
printf("\t\t\t");
for(r=i;inp[r]!='\0';r++)
printf("%c",inp[r]);
}
void rep(char t[],int r)
{
char c;
c=t[r];
switch(c)
{

51 | P a g e
case 'a':printf("0");
break;
case 'b':printf("1");
break;
case 'c':printf("2");
break;
case 'd':printf("3");
break;
case 'e':printf("4");
break;
case 'f':printf("5");
break;
case 'g':printf("6");
break;
case 'h':printf("7");
break;
case 'm':printf("8");
break;
case 'j':printf("9");
break;
case 'k':printf("10");
break;
case 'l':printf("11");
break;
default
:printf("%c",t[r]);
break;
}
}

Expected Output:
Enter the input : i+i
Stack input
0 i+i$
0i5 +i$
0F3 +i$
0T2 +i$
0E1 +i$
0E1+6 i$
0E1+6i5 $
0E1+6F3 $
0E1+6T9 $
0E1 $
accept the input _

52 | P a g e
Output:

Viva voice questions


1. What is full form LALR?
Ans: look ahead LR parsre
2. What is CLOSURE?
Ans :CLOSURE(I) set of items built from I (1) initially add every item I to closure(I)
(2) if A->B is in CLOSURE(I) and B-> then add B- > to CLOSURE(I) if not
already there
3.what are two functions used in LALR?
Ans: 1. CLOSURE() 2. GOTO()
4.What are Kernel Items?
Ans : 1)S->S
2) all items whose dots are not at the left end
5)what are Non-kernel Items?
Ans : 1)all items with their dots at the left end 2)Except S->S
6)what is an augmented grammar ?
Ans :G - grammar with starting symbol S. G augmented grammar for G, S- >S

53 | P a g e
Program9:

Aim :Implement the lexical analyzer using JLex, flex or lex or other lexical
analyzer generating tools.

Algorithm :

STEP1 : WHILE there is more input

InputChar := GetChar
State := Table[0, InputChar]
STEP2 : WHILE State != Blank
InputChar := GetChar
State := Table[State, InputChar]
STEP 3: ENDWHILE
STEP 4: Retract
STEP 5 : Accept
STEP 6: Return token = (Class, Value)

STEP7 :ENDWHILE

Source code:

/* program name is lexp.l */


%{
/* program to recognize a c program */
int COMMENT=0;
%}
identifier [a-zA-Z][a-zA-Z0-9]*
%%
#.* { printf("\n%s is a PREPROCESSOR DIRECTIVE",yytext);}
int |
float |
char |
double |
while |
for |
do |

54 | P a g e
if |
break |
continue |
void |
switch |
case |
long |
struct |
const |
typedef |
return |
else |
goto {printf("\n\t%s is a KEYWORD",yytext);}
"/*" {COMMENT = 1;}
/*{printf("\n\n\t%s is a COMMENT\n",yytext);}*/
"*/" {COMMENT = 0;}
/* printf("\n\n\t%s is a COMMENT\n",yytext);}*/
{identifier}\( {if(!COMMENT)printf("\n\nFUNCTION\n\t%s",yytext);}
\{ {if(!COMMENT) printf("\n BLOCK BEGINS");}
\} {if(!COMMENT) printf("\n BLOCK ENDS");}
{identifier}(\[[0-9]*\])? {if(!COMMENT) printf("\n %s IDENTIFIER",yytext);}
\".*\" {if(!COMMENT) printf("\n\t%s is a STRING",yytext);}
[0-9]+ {if(!COMMENT) printf("\n\t%s is a NUMBER",yytext);}
\)(\;)? {if(!COMMENT) printf("\n\t");ECHO;printf("\n");}
\( ECHO;
= {if(!COMMENT)printf("\n\t%s is an ASSIGNMENT OPERATOR",yytext);}
\<= |
\>= |
\< |
== |
\> {if(!COMMENT) printf("\n\t%s is a RELATIONAL OPERATOR",yytext);}
%%
int main(int argc,char **argv)
{
if (argc > 1)
{
FILE *file;
file = fopen(argv[1],"r");
if(!file)
{
printf("could not open %s \n",argv[1]);
exit(0);
}

55 | P a g e
yyin = file;
}
yylex();
printf("\n\n");
return 0;
} int yywrap()
{
return 0;
}

Expected Output:

$lex lex.l
$cc lex.yy.c
$./a.out var.c
#include<stdio.h> is a PREPROCESSOR DIRECTIVE
FUNCTION
main (
)
BLOCK BEGINS
int is a KEYWORD
a IDENTIFIER
b IDENTIFIER
BLOCK ENDS

Output:

Viva voice questions :


56 | P a g e
1.what is A lexical analyzer?
Ans: A lexical analyzer breaks an input stream of characters into tokens. Writing lexical
analyzers by hand can be a tedious process, so software tools have been developed to
ease this task.

2)Lex is a lexical analyzer generator for what ?


Ans : the UNIX operating system, targeted to the C programming language.

3)how many sections a JLex input file is organized?


Ans : A JLex input file is organized into three sections

4)what are the sections in Jlex?


Ans : 1)user code 2)JLex directives 3)regular expression rules

5) Define User code?


Ans :User code precedes the first double-percent directive (``%%'). This code is copied
verbatim into the lexical analyzer source file that JLex outputs, at the top of the file.
Therefore, if the lexer source file needs to begin with a package declaration or with the
importation of an external class, the user code section should begin with the
corresponding declaration. This declaration will then be copied onto the top of the
generated source file.

6) Define Jlex directive?


Ans :The JLex directive section begins after the first ``%%'' and continues until the second
``%%'' delimiter. Each JLex directive should be contained on a single line and should
begin that line.

57 | P a g e
Program10:

Aim :Write a program to perform loop unrolling.

THEORY:
Loop unrolling transforms a loop into a sequence of statements. It is a parallelizing and
optimizing compiler technique where loop unrolling us used to eliminate loop overhead
to test loop control flow such as loop index values and termination conditions technique
was also used to expose instruction-level parallelism. Syntax tree.

Algorithm :

Step1: start
Step2: declare n
Step3: enter n value
Step4: loop rolling display countbit1 or move to next step 5
Step5: loop unrolling display countbit2
Step6:end

Source code:

#include<stdio.h>
#include<conio.h>
void main()
{ int n;
printf("Enter n value:");
scanf("%d",&n);
printf("loop rolling output:%d\n",countbit1(n));
printf("loop unrolling output:%d\n",countbit2(n));
getch();
}

int countbit1(unsigned int n)


{
int bits = 0;
while (n != 0)
{
if (n & 1) bits++;
n >>= 1;

58 | P a g e
}
return bits;
}
int countbit2(unsigned int n)
{
int bits = 0;
while (n != 0)
{
if (n & 1) bits++;
if (n & 2) bits++;
if (n & 4) bits++;
if (n & 8) bits++;
n >>= 4;
}
return bits;
}

Expected Output:

Enter a value:5
Loop rolling output:2
Loop unrolling output:2

Output:

59 | P a g e
Viva voice questions :
1.define loop unrolling?
Ans : Loop overhead can be reduced by reducing the number of terations
and replicating the body of the loop.
2.example of loop unrolling?
Ans 1)an array sum loop 2) a dot product loop3)a row operation loop
3)An Array Sum Loop
Ans :The following C code will compute the sum of the entries in a 100-entry
vector A.
double arraySum = 0;
for (int i = 0; i < 100; i++) {
arraySum += A[i];
}

60 | P a g e
Program11 :

Aim :Convert the BNF rules into YACC form and write code to generate abstract
Syntax tree.

Algorithm :

Step1: To specify the syntax of a language : CFG and BNF


Step2: ex: if-else statement in C has the form of statement if (
expression )
statement else statement
Step3: An alphabet of a language is a set of symbols.
step4: ex:{0,1} for a binary number system(language)={0,1,100,101,...}
Step 5:{a,b,c} for language={a,b,c, ac,abcc..}
Step6: {if,(,),else ...} for a if statements={if(a==1)goto10, if--}
Step7: A string over an alphabet
is a sequence of zero or more symbols from the alphabet.
Step8: Ex: 0,1,10,00,11,111,0202 ... strings for a alphabet {0,1}
Step9: Null string is a string which does not have any symbol of
alphabetLanguage.
o Is a subset of all the strings over a given alphabet.
Step10: Alphabets Ai Languages Li for Ai
A0={0,1} L0={0,1,100,101,...}
A1={a,b,c} L1={a,b,c, ac, abcc..}
A2={all of C tokens} L2= {all sentences of C program }

Source code:

<int.l>
%{
#include"y.tab.h"
#include<stdio.h> #include<string.h> int LineNo=1; %}
identifier [a-zA-Z][_a-zA-Z0-9]* number [0-9]+|([0-9]*\.[0-9]+)
%%
main\(\) return MAIN; if return IF; else return ELSE;
while return WHILE;
int |
char | float return TYPE; {identifier} {strcpy(yylval.var,yytext); return VAR;} {number}
{strcpy(yylval.var,yytext);

61 | P a g e
return NUM;}
\< |
\> |
\>= |
\<= |
== {strcpy(yylval.var,yytext);
Compiler design Lab programs
12
return RELOP;}
[ \t] ;
\n LineNo++;
. return yytext[0];
%%
<int.y>
%{
#include<string.h> #include<stdio.h> struct quad { char op[5]; char arg1[10]; char
arg2[10];
char result[10];
}QUAD[30];
struct stack { int items[100]; int top; }stk;
int Index=0,tIndex=0,StNo,Ind,tInd; extern int LineNo;
%}
%union
{
char var[10];
}
%token <var> NUM VAR RELOP
%token MAIN IF ELSE WHILE TYPE
%type <var> EXPR ASSIGNMENT CONDITION IFST ELSEST WHILELOOP
%left '-' '+'
%left '*' '/'
%%
PROGRAM : MAIN BLOCK
;
BLOCK: '{' CODE '}'
;
CODE: BLOCK
| STATEMENT CODE
| STATEMENT
;
STATEMENT: DESCT ';'
| ASSIGNMENT ';'
19

62 | P a g e
CD LAB PROGRAMS
| CONDST
| WHILEST
;
DESCT: TYPE VARLIST
;
VARLIST: VAR ',' VARLIST
| VAR
;
ASSIGNMENT: VAR '=' EXPR{ strcpy(QUAD[Index].op,"=");
strcpy(QUAD[Index].arg1,$3); strcpy(QUAD[Index].arg2,"");
strcpy(QUAD[Index].result,$1); strcpy($$,QUAD[Index++].result);
}
;
EXPR: EXPR '+' EXPR {AddQuadruple("+",$1,$3,$$);}
| EXPR '-' EXPR {AddQuadruple("-",$1,$3,$$);}
| EXPR '*' EXPR {AddQuadruple("*",$1,$3,$$);}
| EXPR '/' EXPR {AddQuadruple("/",$1,$3,$$);}
| '-' EXPR {AddQuadruple("UMIN",$2,"",$$);}
| '(' EXPR ')' {strcpy($$,$2);}
| VAR
| NUM
;
CONDST: IFST{
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index); Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
}
| IFST ELSEST
;
IFST: IF '(' CONDITION ')' { strcpy(QUAD[Index].op,"==");
strcpy(QUAD[Index].arg1,$3); strcpy(QUAD[Index].arg2,"FALSE");
strcpy(QUAD[Index].result,"-1"); push(Index);
Index++;
}
BLOCK { strcpy(QUAD[Index].op,"GOTO"); strcpy(QUAD[Index].arg1,"");
Compiler design Lab programs
14
strcpy(QUAD[Index].arg2,""); strcpy(QUAD[Index].result,"-1");
push(Index);
Index++;
};
ELSEST: ELSE{

63 | P a g e
tInd=pop(); Ind=pop(); push(tInd);
sprintf(QUAD[Ind].result,"%d",Index);
}
BLOCK{
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
};
CONDITION: VAR RELOP VAR {AddQuadruple($2,$1,$3,$$);
StNo=Index-1;
}
| VAR
| NUM
;
WHILEST: WHILELOOP{
Ind=pop();
sprintf(QUAD[Ind].result,"%d",StNo); Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
}
;
WHILELOOP: WHILE '(' CONDITION ')' { strcpy(QUAD[Index].op,"==");
strcpy(QUAD[Index].arg1,$3); strcpy(QUAD[Index].arg2,"FALSE");
strcpy(QUAD[Index].result,"-1");
push(Index);
Index++;
}
BLOCK {
strcpy(QUAD[Index].op,"GOTO"); strcpy(QUAD[Index].arg1,"");
strcpy(QUAD[Index].arg2,""); strcpy(QUAD[Index].result,"-1"); push(Index);
Index++;
}
;
%%
Compiler design Lab programs
15
extern FILE *yyin;
int main(int argc,char *argv[])
{
FILE *fp;
int i;
if(argc>1) {
fp=fopen(argv[1],"r");
if(!fp) {
printf("\n File not found");

64 | P a g e
exit(0); } yyin=fp; } yyparse();
printf("\n\n\t\t ----------------------------""\n\t\t Pos Operator Arg1 Arg2 Result" "\n\t\t
--------------------"); for(i=0;i<Index;i++)
{
printf("\n\t\t %d\t %s\t %s\t %s\t
%s",i,QUAD[i].op,QUAD[i].arg1,QUAD[i].arg2,QUAD[i].result);
}
printf("\n\t\t -----------------------");
printf("\n\n"); return 0; }
void push(int data)
{ stk.top++; if(stk.top==100)
{
printf("\n Stack overflow\n");
exit(0); }
stk.items[stk.top]=data;
} int pop() { int data; if(stk.top==-1)
{
printf("\n Stack underflow\n");
exit(0); }
data=stk.items[stk.top--];
Compiler design Lab programs
16
return data; }
void AddQuadruple(char op[5],char arg1[10],char arg2[10],char result[10])
{
strcpy(QUAD[Index].op,op); strcpy(QUAD[Index].arg1,arg1);
strcpy(QUAD[Index].arg2,arg2); sprintf(QUAD[Index].result,"t%d",tIndex++);
strcpy(result,QUAD[Index++].result);
} yyerror() {
printf("\n Error on line no:%d",LineNo);
}
Input: $vi test.c main() { int a,b,c; if(a<b) { a=a+b; } while(a<b) { a=a+b; } if(a<=b) { c=a-b;
} else { c=a+b;
}
}

Expected Output:

$lex int.l
$yacc d int.y
$gcc lex.yy.c y.tab.c ll lm
$./a.out test.c

65 | P a g e
Pos Operator Arg 1 Arg 2 Result
0 < a b t0
1 == t0 FALSE 5
2 + a b t1
3 = t1 a
4 GOTO 5
5 < a b t2
6 == t2 FALSE 10
7 + a b t3
8 = t3 a
9 GOTO 5
10 <= a b t4
11 == t4 FALSE 15
12 - a b t5
13 = t5 c
14 GOTO 17
15 + a b t3
16 = t6 c

Output:

66 | P a g e
Viva voice questions:
What is the full form of BNF?
Ans:BNF stands for either Backus-Naur Form or Backus Normal Form
What is struture for BNF?
Ans: the Every rule in Backus-Naur form has the following structure:
$\mathit{name}$ ::= $\mathit{expansion}$
Example of BNF Grammar?
<expr> ::= <term> "+" <expr>
| <term>
<term> ::= <factor> "*" <term>
| <factor>
<factor> ::= "(" <expr> ")"
| <const>
<const> ::= integer
What is the BNF Converter?
The BNF Converter is a compiler construction tool generating a compiler front-end from
a Labelled BNF grammar
What is full form of YACC?
Ans : Yacc: Yet Another Compiler-Compiler

67 | P a g e
Program12:

Aim:Write a program for constant propagation.

THEORY:

The algorithm we shall present basically tries to find for every statement in
the program a mapping between variables, and values of N T { , } . If a
variable is mapped to a constant number, that number is the variables value
in that statement on every execution. If a variable is mapped to T (top), its
value in the statement is not known to be constant, and in the variable is
mapped to (bottom), its value is not initialized on every execution, or the
statement is unreachable. The algorithm for assigning the mappings to the
statements is an iterative algorithm, that traverses the control flow graph of
the algorithm, and updates each mapping according to the mapping of the
previous statement, and the functionality of the statement. The traversal is
iterative, because non-trivial programs have circles in their control flow
graphs, and it ends when a fixed-point is reached i.e., further iterations
dont change the mappings.

ALGORITHM:

Step1: start
Step2: declare a=30,b=3,c
Step3: display result of propagation
Step4:end
Source code:

#include<stdio.h>
#include<conio.h>
void main()
{
printf("result of constant propagation is %d",constantpropagation());
getch();
}

int constantpropagation()

68 | P a g e
{
int a = 30;
int b = 3;
int c;

c = b * 4;
if (c > 10) {
c = c - 10;
}
return c * 2;
}

Expected Output:

Result of constant propagation is 4

Output:

69 | P a g e
Viva voice questions
What is a compiler?
Ans : a program that translates an executable program in one language into an
executable program in another language
we expect the program produced by the compiler to be better, in some way, than the
original.

What is an interpreter?
a program that reads an executable program and produces the
results of running that program
usually, this involves executing the source program in some fashion

Program13 :

Aim: Write a program to check whether a string belongs to a grammar or not

Algorithm :
Step1: Start.
Step2: Declare two character arrays str[],token[] and initialize integer
variables a=0,b=0,c,d. Input the string from the user.
Step3: Repeat steps 5 to 12 till str[a] =\0.
If str[a] =='(' or str[a] =='{' then token[b] =4, b++.
If str[a] ==')' or str[a] =='} then token[b] =5, b++.
Step4: Check if isdigit(str[a]) then repeat steps 8 till isdigit(str[a]) a++.
Step5: a--, token[b] =6, b++.
Step6:If(str[a]=='+) then token[b]='2',b++.
Step7:If(str[a]=='*') then token[b]=3,b++.
a++
token[b]='\0';
then print the token generated for the string .
Step8: b=0.
Repeat step 22 to 31 till token[b]!='\0'
Step9: c=0.
Repeat step 24 to 30 till (token[b]=='6' and token[b+1]=='2' and

70 | P a g e
token[b+2]=='6') or (token[b]=='6' and token[b+1]=='3'and
token[b+2]=='6') or (token[b]=='4' and token[b+1]=='6' and
token[b+2]=='5') or (token[c]!='\0').
token[c]='6';
c++;
step10:Repeat step 27 to 28 till token[c]!='\0'.
token[c]=token[c+2].c++.
Step11:token[c-2]=\0. print token. b++.

Step12: Compare token with 6 and store the result in d.


Step13: If d=0 then print that the string is in the grammar.
Else print that the string is not in the grammar.
Step14: Stop.

Source code :

#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#include<string.h>
void main()
{
int a=0,b=0,c;
char str[20],tok[11]; clrscr();
printf("Input the expression = ");
gets(str);
while(str[a]!='\0')
{
if((str[a]=='(')||(str[a]=='{'))
{
tok[b]='4';
b++;
}
if((str[a]==')')||(str[a]=='}'))
{
tok[b]='5';
b++;

71 | P a g e
}
if(isdigit(str[a]))
{
while(isdigit(str[a]))
{
a++;
}
a--; tok[b]='6';
b++;
}
if(str[a]=='+')
{
tok[b]='2';
b++;
}
if(str[a]=='*')

{
tok[b]='3';
b++;
}

a++;
}
tok[b]='\0';
puts(tok);
b=0;
while(tok[b]!='\0')
{

if(((tok[b]=='6')&&(tok[b+1]=='2')&&(tok[b+2]=='6'))||((tok[b]=='6')&&(tok[b+1

]=='3')&&(tok[b+2]=='6'))||((tok[b]=='4')&&(tok[b+1]=='6')&&(tok[b+2]=='5'))/*||((to
k[b
]!=6)&&(tok[b+1]!='\0'))*/)
{
tok[b]='6';
c=b+1;
while(tok[c]!='\0')
{
tok[c]=tok[c+2];
c++;
}

72 | P a g e
tok[c]='\0';
puts(tok);
b=0;
}
else
{

b++;
puts(tok);
}
}
int d;
d=strcmp(tok,"6");
if(d==0)
{
printf("It is in the grammar.");
}
else
{
printf("It is not in the grammar.");
}
getch();
}

Expected Output:

Input the expression = (23+) 4625 4625 4625 4625 4625

It is not in the grammar.

OUTPUT :

73 | P a g e
Viva voice questions

1.What is target code?


Ans :Code generated in the final phase of compilation Through post code generation,
optimization process is known as target code.

2.What is machine code?


Ans : a computer programming language consisting of binary or hexadecimal instructions which
a computer can respond to directly.
Translate machine code to

3.What is Cross compiler?


Ans : a compiler which can convert instructions into machine code or low-level code for a
computer other than that on which it is run.
Translate cross compiler to

4.Give the example for cross compiler?


Ans NET and java is cross compiler language,When the program is compiled in .NET, we have
to choose the option like X86, X64 or Any CPU. What that means? Also in setup project we

74 | P a g e
have to choose the option between x86 and x64. So if the program is compiled in x86 and msi
file has been created on x64 will it run on both X64 and x86 or any one of ?

5.What is the difference between syntax & Semantics?

Ans Syntax refers to the structure of a language, tracing its etymology to how things are out
together.
For example you mgiht require the code to be put together by declaring a type then a name and
then a semicolon, to be syntactically correct.

Type token;

On the other hand, the semantics is about meaning. A compiler or interpreter could complain
about syntax errors. Your co-workers will complain about semantics.

Program14:

Aim: Write a program to find out whether given string is identifier or not

Algorithm :

Step1: Start
Step2: Check if the first char is a letter goto step 3 with rest of the string
else goto 5.
Step3: Check if the first character of the given string is a letter or a digit
repeat step 3 with rest of the string else goto step 5.
Step4: print The given string is an identifier and goto step 6.
Step5: Print The given string is not an identifier.
Step6: Exit

Source Code:

75 | P a g e
#include<stdio.h>

#include<conio.h>
int isiden(char*); int
second(char*); int
third();
void main()
{

char *str; int i = -


1;
clrscr();

printf("\n\n\t\tEnter the desired String:


"); do

{
++i;
str[i] = getch(); if(str[i]!=10 &&
str[i]!=13)

printf("%c",str[i]);
if(str[i] == '\b')

{
--i;
printf(" \b");

}
}while(str[i] != 10 && str[i] != 13);

if(isident(str))

printf("\n\n\t\tThe given strig is an identifier");

else
printf("\n\n\t\tThe given string is not an identifier");
getch();

//To Check whether the given string is identifier


or not //This function acts like first stage of dfa

76 | P a g e
int isident(char *str)
{

if((str[0]>='a' && str[0]<='z') || (str[0]>='A' && str[0]<='Z'))


{
return(second(str+1));

}
else
return 0;

//This function acts as second stage of


dfa int second(char *str)
{

if((str[0]>='0' && str[0]<='9') || (str[0]>='a' && str[0]<='z') || (str[0]>='A' &&


str[0]<='Z'))
{
return(second(str+1)); //Implementing the loop from second stage to

second stage

}
else

{
if(str[0] == 10 || str[0] == 13)
{

return(third(str));
}
else

{
return 0;

}
}
}

77 | P a g e
//This function acts as third stage of dfa
int third()

{
return 1; //Being final stage reaching it mean the string is identified
}

EXPECTED OUTPUT:
Enter the desired String: a123

The given string is an identifier

OUTPUT:

Viva voice questions:

78 | P a g e
1)What is an identifier?
Ans : An identifier is used for any variable, function, data definition, etc. In the programming
language C, an identifier is a combination of alphanumeric characters, the first being a letter of
the alphabet or an underline, and the remaining being any letter of the alphabet, any numeric
digit, or the underline
2)What are the rules followed for constructing an identifier?
Rules for constructing identifiers
1. The first character in an identifier must be an alphabet or an underscore and can be followed
only by any number alphabets, or digits or underscores.
2. They must not begin with a digit.
3. Uppercase and lowercase letters are distinct. That is, identifiers are case sensitive.
4. Commas or blank spaces are not allowed within an identifier.
5. Keywords cannot be used as an identifier.
6. Identifiers should not be of length more than 31 characters.
7. Identifiers must be meaningful, short, quickly and easily typed and easily read.

3)How do you declare a variable that will hold string values?

Ans The char keyword can only hold 1 character value at a time. By creating an array of
characters, you can store string values in it. Example: char MyName[50]; declares a string
variable named MyName that can hold a maximum of 50 characters.

4)Can the if function be used in comparing strings?

Ans No. if command can only be used to compare numerical values and single character
values. For comparing string values, there is another function called strcmp() that deals
specifically with strings.

79 | P a g e

Das könnte Ihnen auch gefallen