0% found this document useful (0 votes)
48 views50 pages

Lab Manual Compiler (Cs316)

Uploaded by

ramchandra53473
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
48 views50 pages

Lab Manual Compiler (Cs316)

Uploaded by

ramchandra53473
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 50

Department of Computer Science & Engineering

LAB MANUAL

Session 2021-2022

Subject Name : - Compiler Design Lab

Subject Code : - CS316

Branch : - CSE

Year : - 3rd

Semester : - 6th

INTEGRAL UNIVERSITY LUCKNOW


Dsauli, Kursi Road, PO Basha-226026

Dept of CSE /IT 1 CS316


Revision History

REVISION HISTORY
REVISIO AUTHOR(S) REVIEWER(S DATE OF OWNER SUMMARY OF
N# ) RELEASE CHANGES
Revision Mis. Kavita Agarwal Internal 01/01/201 HOD - Initial Release
-1 Mr. Shoeb Ahad Siddiqui Reviewers 4 CSE
Mr. Mohd Arshad Ali
Mr. Tabrez Khan

Revision Departmental 31/01/201 HOD - Major revisions


-2 QAC 4 CSE made.
Incorporated
review comments
from departmental
QAC into
Revision-2
Revision External 28/02/201 HOD -
-3 Reviewers 3 CSE

Dept of CSE /IT 2 CS316


List of Lab Exercises

Week Experiment Name of the Experiments Page


No. No.
Week-1 1 Introduction 4
1.1 Brief discussion about functions and switch case.
Write a program to perform matrix addition, matrix multiplication
and check whether given string is palindrome or not, using case
statements.
Week-2 2 Study of Infix to Postfix expression & Infix to Prefix expression 7
Conversion
2.1 Write a program to convert infix expression to postfix expression 8
with the help of stack.
2.2 Write a program to convert infix expression to prefix expression 9
with the help of stack.
Week-4 3 Token 13
3.1 Write a program to check whether given string is constant or not.
3.2 Write a program to check whether given string is keyword or not. 15
3.3 Write a program to check whether given string is identifier or not. 16
Week-7 4 Write a program to implements Tokenizer for Lexical Analyzer. 18
Week-8 5 First and Follow 22
5.1 Write a program to implement First of a grammar. 23
5.2 Write a program to implement Follow of a grammar. 24
Week-10 6 Recursive Decent Parsing 28
6.1 Write a program to implement recursive decent parsing.
Week-11 7 Predictive Parsing 32
7.1 Write a program to implement predictive parsing.
Week-12 8 Grammar 38
8.1 Write a program to check whether given string is grammar or not.
Week-13 9 Operator Precedence Parser 41
9.1 Write a program to implement operator precedence parser.

Dept of CSE /IT 3 CS316


Introduction

Compiler is a System Software that converts High level language to low level language. We human beings
can’t program in machine language (low level lang.) understood by Computers so we programmed. In high
level language and compiler is the software which bridges the gap between user and computer.

Compiler:-

A compiler is a program that translates a source program written in some high-level programming language
(such as Java) into machine code for some computer architecture (such as the Intel Pentium architecture).
The generated machine code can be later executed many times against different data each time.

Interpreter:-

An interpreter reads an executable source program written in a high-level programming language as well as
data for this program, and it runs the program against the data to produce some results. One example is the
UNIX shell interpreter, which runs operating system commands interactively.
An interpreter is generally slower than a compiler because it processes and interprets each statement in a
program as many times as the number of the evaluations of this statement. For example, when a for-loop is
interpreted, the statements inside the for-loop body will be analyzed and evaluated on every loop step. Some
languages, such as Java and Lisp, come with both an interpreter and a compiler.
A compiler is a special program that processes statements written in a particular programming language and
turns them into machine language or code that a computer's processor uses. Typically, a programmer writes
language statements in a language such as Pascal or C one line at a time using an editor. The file that is
created contains what are called the source statements. The programmer then runs the appropriate language
compiler, specifying the name of the file that contains the source statements.

It’s a very complicated piece of software which took 18 man years to build first compiler. To build this S/w
it is divided into six phases which are

1) Lexical Analysis
2) Syntax Analysis
3) Semantic Analysis
4) Intermediate Code Generation
5) Code Optimization
6) Code Generation.

In the lab sessions students implement Lexical Analyzers and code for each phase to understand compiler
software working and its coding in detail.

Dept of CSE /IT 4 CS316


Week-1
Experiment No- 1

OBJECTIVE

Brief discussion about functions and switch cases.

Switch Statements

A switch statement allows a variable to be tested for equality against a list of values. Each value is called a
case, and the variable being switched on is checked for each switch case.
Syntax:
The syntax for a switch statement in C programming language is as follows:
switch(expression){
case constant-expression :
statement(s);
break; /* optional */
case constant-expression :
statement(s);
break; /* optional */
/* you can have any number of case statements */
default : /* Optional */
statement(s);
}

The following rules apply to a switch statement:

 The expression used in a switch statement must have an integer or enumerated type, or be of a class
type in which the class has a single conversion function to an integral or enumerated type.
 You can have any number of case statements within a switch. Each case is followed by the value to
be compared to and a colon.
 The constant-expression for a case must be the same data type as the variable in the switch, and it
must be a constant or a literal.
 When the variable being switched on is equal to a case, the statements following that case will
execute until a break statement is reached.
 When a break statement is reached, the switch terminates, and the flow of control jumps to the next
line following the switch statement.
 Not every case needs to contain a break. If no break appears, the flow of control will fall through to
subsequent cases until a break is reached.
 A switch statement can have an optional default case, which must appear at the end of the switch.
The default case can be used for performing a task when none of the cases is true. No break is needed in the
default case.

Function

Dept of CSE /IT 5 CS316


Functions are "self contained" modules of code that accomplish a specific task. Functions usually "take in
“data, process it, and "return" a result. Once a function is written, it can be used over and over and
overagain.Functions can be "called" from the inside of other functions.

type functionName( type argname [, type, ...] )


{
// function body
}

Example:

// define a function that adds two integers, returning their sum


int add (int lhs, int rhs)
{
return lhs + rhs;
}
// declare the add function
int add (int, int);

// define the add function later


int add (int lhs, int rhs)
{
return lhs + rhs;
}

Dept of CSE /IT 6 CS316


1.1 Write a program to perform matrix addition, matrix multiplication and check
whether given string is palindrome or not, using case statements.

Solution:
#include<stdio.h>
#include<conio.h>
#include<string.h>
void sum_mat();
void mul_mat();
void str_pal();
void main()
{
int ch;
printf(“Press 1 for sum of matrix\n”);
printf(“Press 2 for Multiplication of matrix\n”);
printf(“Press 3 for to check whether string given string is palindrome or not\n”);
printf(“Press 4 for exit\n”);
printf(“Enter the choice\n”);
scanf(“%d”,&ch);

switch(ch)
{
case 1:
sum_mat();
break;
case 2:
mul_mat();
break;
case 3:
str_pal();
break;
case 4:
exit(0);

default:
printf(“Wrong choice”);

}}
void sum_mat()
{ //code for matrix addition }
void mul_mat()
{
//code for matrix multiplication }
void str_pal()
{
//code for string palindrome
}

Dept of CSE /IT 7 CS316


Week-2
Experiment No 2
OBJECTIVE

 Study of Infix to Postfix conversion with the help of Stack


Postfix expression is one of the intermediate codes to be used in the translation of source code into machine
code. For example, if an expression is like “a+b*c”, it is converted into “abc*+”. In postfix expression, the
operators are moved to the position that is next to the required operands. In order to convert the infix to
postfix expression, three data structure are used: (i) a stack, (ii) input buffer, and (iii) output buffer. During
the evaluation of the expression some portion of the expressions are evaluated first and the other portions are
evaluated next, depending on the priority of the operator

Study of Infix to prefix conversion with the help of Stack

Postfix expression is one of the intermediate codes to be used in the translation of source code into machine
code. For example, if an expression is like “a+b*c”, it is converted into “abc*+”. In postfix expression, the
operators are moved to the position that is next to the required operands. In order to convert the infix to
postfix expression, three data structure are used: (i) a stack, (ii) input buffer, and (iii) output buffer. During
the evaluation of the expression some portion of the expressions are evaluated first and the other portions are
evaluated next, depending on the priority of the operator.

Algorithms
Steps:

1. Create buffer (array) to hold both infix and postfix expression.

2. Create an operator stack.

3. Fix priorities for the operators in the infix string and stack.

4. For every operand or operator read from the infix expression string do step 5.

5. If it is operand place it in postfix string

Else either push the operator on to stack or move the contents of stack to postfix string depending on the

priority of the operator compared with the priority of the stack operator.

Modules:

 Stack related operations

o Creation and disposal of stack

o Checking the empty and full status of the stack for pop and push operations

o Push, Pop, Peep at top operations

Dept of CSE /IT 8 CS316


 Determining the priority of an operator

 Deciding whether the element is operator or operand

 Conversion of infix to postfix expression

Required data structure:

 Buffer for infix and postfix expression

 Operator array

 Infix and stack priority of the operators

Dept of CSE /IT 9 CS316


2.1 Write a program to convert infix expression to postfix expression with the help of
stack.

Solution:
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#include<string.h>
int top=-1,i=0,l;
char infix[50],stk[50],a;
void postfix(char);
int p(char);
void main()
{
clrscr();
printf("Enter infix expression");
gets(infix);
l=strlen(infix);
infix[l]='#';
stk[++top]='#';
printf("Postfix Expression");
while(infix[i]!='#')
{
if(isalpha(infix[i]))
printf("%c",infix[i]);
else
postfix(infix[i]);
i++;
}
while((top!=-1)&&(stk[top]!='#'))
printf("%c",stk[top--]);
getch();
}
void postfix(char a)
{
switch(a)
{
case '(':stk[++top]=a;
break;

default:
if(a==')')
{
while(stk[++top]!=')')
printf("%c",stk[--top]);
}
else if(stk[++top]=='(')
stk[++top]=a;
else if(p(a)>p(stk[top]))

Dept of CSE /IT 10 CS316


stk[++top]=a;
else
{
while(p(stk[top])>p(a))
printf("%c",stk[top--]);
stk[++top]=a;
}
}
}
int p(char a)
{
switch(a)
{
case '^':
return 3;
break;

case '/':
case '*':
return 2;
break;
case '+':
case '-':
return 1;
break;
default:
return 0;
}
}
Output

Enter the infix expression a+b*c#


Infix: a+b*c# is converted into postfix:abc*+

Dept of CSE /IT 11 CS316


Week-3
2.2 Write a program to convert infix expression to prefix expression with the help of
stack.

#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#include<string.h>
int top=-1,t=-1;
char infix[20],sym[20],inf[20],pre[20];
void prefix(char);
int p(char);
void main()
{
int l,i=0;
clrscr();
printf("\n Convert Infix to PrefixExpression\n");
printf("Enter infix expression");
gets(infix);
l=strlen(infix);
while(i<l)
{
inf[i+1]=infix[i];
i++;
}
inf[0]='(';
sym[++t]=')';
i=strlen(inf)-1;
while(i!=0)
{
if(isalpha(inf[i]))
pre[++top]=inf[i];
else
prefix(inf[i]);
i--;
}
while((t!=-1)&&(sym[t]!=')'))
pre[++top]=sym[t--];
printf("Prefix Expression");
while(top!=-1)
printf("%c", pre[top--]);
getch();
}

void prefix(char a)
{
switch(a)
{
case ')':

Dept of CSE /IT 12 CS316


sym[++t]=a;
break;

default:
if(a=='(')
{
while(sym[++t]!=')')
pre[++top]=sym[t--];
t--;
}
else if(a==')')
sym[++t]=a;
else if(p(a)>p(sym[t]))
sym[++t]=a;
else
{
while(p(a)<p(sym[t]))
pre[++top]=sym[t--];
sym[++t]=a;
}
}
}
int p(char a)
{
switch(a)
{
case '^':
return 3;
break;

case '/':
case '*':
return 2;
break;
case '+':
case '-':
return 1;
break;
default:
return 0;
}
}

Output

Enter the infix expression a+b*c#


Infix: a+b*c# is converted into prefix: *+ab#c

Dept of CSE /IT 13 CS316


Week-4
Experiment No - 3

Objectives: To implements Tokenizer


 Check string is constant or not.
 Check string is keyword or not.
 Check string is identifier or not.
3.1 ALGORITHM TO FIND WHETHER A STRING IS A CONSTANT OR NOT

1. Start
2. Declare a character array str[] and initialize integer variables len, a=0.
3. Input the string from the User.
4. Find the length of the string.
5. Repeat step 6 to 7 till a<len.
6. If the str[a] is numeric character then a++.
7. Else it is not a constant, break from the loop and go to step 9.
8. if a==len then print that the entered string is a constant
9. Else it is not a constant.
10. Stop.

Write a program to Check string is constant or not.

Solution:-
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#include<string.h>
void main()
{
char str[10];
int len,a;
clrscr();
printf("\n Input a string :");
gets(str);
len=strlen(str);
a=0;
while(a<len)
{
if(isdigit(str[a]))
{
a++;
}
else
{
printf(" It is not a Constant");
break;
}
}

Dept of CSE /IT 14 CS316


if(a==len)
{
printf(" It is a Constant");
}
getch();
}

OUTPUT
Input a string: 23
It is a Constant

Input a string: a_123


It is not a Constant

Dept of CSE /IT 15 CS316


Week-5

3.2 ALGORITHM TO CHECK WHETHER A STRING IS A KEYWORD OR NOT

1. Start.
2. Declare a character storing the keywords, s[5][10]={"if","else","goto","continue","return"} and
another character array to store the string to be compared st[], initialize integer variables I, flag=0,m.
3. Input the string that is to be compared st[].
4. Repeat step 5 to 6 till counter i becomes equal to number of keywords stored in the array.
5. Compare the string entered by the user with the strings in the character array by using
m=strcmp(st,s[i]), where strcmp function returns true if both the strings are equal.
6. i=i+1.
7. If flag=1 then it is keyword.
8. Else it is not a keyword.
9. Stop.

Write a program to Check string is Keyword or not.


Solution:-
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
int i,flag=0,m;
char s[5][10]={"if","else","goto","continue","return"},st[10];
clrscr();
printf("\n enter the string :");
gets(st);
for(i=0;i<5;i++)
{
m=strcmp(st,s[i]);
if(m==0)
flag=1;
}
if(flag==0)
printf("\n it is not a keyword");
else
printf("\n it is a keyword");
getch();
}

OUTPUT
Enter the string: return
it is a keyword

Enter the string: hello


it is not a keyword

Dept of CSE /IT 16 CS316


Week-6

3.3 ALGORITHM TO IDENTIFY HETHER A GIVEN STRING IS AN IDENTIFIER OR NOT

Step 1. Start
Step 2. Check if the first char is a letter goto step 3 with rest of the string else goto 5.
Step 3. 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.
Step 4. Print “The given string is an identifier” and goto step 6.
Step 5.Print “The given string is not an identifier”.
Step 6. Exit

Write a program to Check string is identifier or not.

Solution:-
#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
int isident(char *str)
{
if((str[0]>='a' && str[0]<='z') || (str[0]>='A' && str[0]<='Z'))
{

Dept of CSE /IT 17 CS316


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));
second stage
}
else
{

//Implementing the loop from second stage to

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


{
return(third(str));
}
else
{
return 0;
}
}
}
//This function acts as third stage of dfa
int third()
{
return 1; //Being final stage reaching it mean the string is identified
}

OUTPUT:
Enter the desired String: a123
The given string is an identifier

Enter the desired String: shailesh


The given string is an identifier

Enter the desired String: 1asd


The given string is not an identifier

Dept of CSE /IT 18 CS316


Week-7
Experiment No -4

Objectives: To implements Tokenizer for Lexical Analyzer.

Algorithms:-

WHILE there is more input


InputChar := GetChar
State := Table[0, InputChar]
WHILE State != Blank
InputChar := GetChar
State := Table[State, InputChar]
ENDWHILE
Retract
Accept
Return token = (Class, Value)
ENDWHILE
1. GetChar: Moves the lookahead pointer ahead one character and returns that character.

2. Retract: Moves the lookahead pointer back one character.

Before Retract

After Retract

3. Accept: Moves the current pointer ahead to the lookahead pointer:

After Accept

4. Return: Returns a token consisting of a class and a value, as well as performs any actions associated
with that state, e.g., installing an identifier into the name table.

Dept of CSE /IT 19 CS316


The driver program scans the input program and comsults the entry at Table [State, InputChar] for the new
state. The entry at Table [State, InputChar] consists of a new state and perhaps an action to be performed
before moving to the new state:

Very smallest unit of any programming is called Token.


There are 5 types of Tokens:
1. Constant
2. Keyword
3. Identifier
4. Punctuation
5. Operator
.

4.1 Write a program to implement Tokenize.


Solution:
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
#define SIZE 128 //Define a Macro and SIZE Assign a value 128
#define NONE -1 //Define a Macro and NONE Assign a value -1
#define EOS '\0' //Define a Macro and EOS is NULL
#define PAREN 257 //Define a Macro and PAREN Assign a value 257
#define NUM 256 //Define a Macro and NUM Assign a value 256
#define KEYWORD 258 //Define a Macro and KEYWORD Assign a value 258
#define ID 259 //Define a Macro and ID Assign a value 259
#define ASSIGN 260 //Define a Macro and ASSIGN OPER Assign a value 260
#define REL_OP 261 //Define a Macro and REL_OP Assign a value 261
#define DONE 262 //Define a Macro and DONE Assign a value 262
#define MAX 99 //Define a Macro and MAX Assign a value 99
char lexeme[MAX];
char buffer[SIZE];
char lastchar=-1;
char lastentry=0;
int tokenval=NONE;
int lexems=1;
int lexeno=1;
void initialize();
void error_massage(char *m);
struct entry
{
char *lexptr;
int token;
}
symboltable[100];
struct entry
keywords[]={"if",KEYWORD,"else",KEYWORD,"for",KEYWORD,"int",KEYWORD,"float",KEYWOR
D,"double",KEYWORD,"char",KEYWORD,"struct",KEYWORD,"return",0,0,0};
void error_massage (char *m)

Dept of CSE /IT 20 CS316


{
fprintf(stdin,"lex=%d","%s\n",lexems,m);
exit(1);
}
int lookup(char s[])
{
int k;
for(k=lastentry;k>0;k=k-1)
if(strcmp(symboltable[k].lexptr,s)==0)
return k;
return 0;
}
int insert (char s[],int tok)
{
int lex;
lex=strlen(s);
if(lastentry+1>=MAX)
error_massage("symbol table is full");
if(lastchar+lex+1>=MAX)
error_massage("lexeme is full");
lastentry = lastentry +1;
symboltable[lastentry].token=tok;
symboltable[lastentry].lexptr=lexeme[lastchar+1];
lastchar=lastchar+lex+1;
strcpy(symboltable[lastentry].lexptr,s);
lexeme[lastchar+1];
return lastentry;
}
void initialize()
{
struct entry *ptr;
for(ptr=keywords;ptr->token;ptr++)
insert(ptr->lexptr,ptr->token);
}
int lexer()
{
int t;
int val,i=0;
while(1)
{
t=getchar();
if(t==' '||t=='\t')
return 0;
else if(t=='('||t==')'||t=='<='||t=='>=')
return REL_OP;
else if(t=='=')
return ASSIGN;
else if(isdigit(t))
{
ungetc(t,stdin);

Dept of CSE /IT 21 CS316


scanf("%d",tokenval);
return NUM;
}
else if(isalpha(t))
{
while(isalnum(t))
{
buffer[i]=t;
t=getchar();
i=i+1;
if(i>=SIZE)
error_massage("Compile Error");
}
buffer[i]=EOS;
if(t!=EOS)
ungetc(t,stdin);
val=lookup(buffer);
if(val==0)
val=insert(buffer,ID);
tokenval=val;
return symboltable[val].token;
}
else if(t==EOF)
return DONE;
else
{
tokenval=NONE;
return t;
}
}
}
void main()
{
int lookahead;
char ans;
clrscr();
printf("\t\t\t press for Lexical Analysis:-");
initialize();
printf("\n Press Ctrl+Z to terminate");
printf("\n Please Enter the Expression:-");
lookahead=lexer();
while(lookahead!=DONE)
{
if(lookahead==NUM)
{
printf("\n NUMBER:-");
printf("\n Tokenval:-%d",tokenval);
}
if(lookahead=='+'||lookahead=='-|lookahead=='*'||lookahead=='%'||lookahead=='/')
printf("\n Operators:-");

Dept of CSE /IT 22 CS316


if(lookahead==PAREN)
printf("\n Parenthesis:-");
if(lookahead==ID)
{
printf("\n Identifiers:-");
printf("%d",symboltable[tokenval].lexptr);
}
if(lookahead==KEYWORD)
printf("\n Keywords:-");
if(lookahead==ASSIGN)
printf("\n Assignment Operator:-");
lookahead=lexer();
}
getch();
}

Out Put:

Press for lexical analyser


Press Ctrl+Z to terminate
Enter the Expression and put at the end:-if (a>b) then a=a+1 else b=b+1

Keywords
Paranthesis
Identifier:-a
Relational Operator
Identifier:-b
Paranthesis
Identifier:-then
Identifier:-a
Assignment Operator
Identifier:-a
Operator
Number:-1
Keywords
Identifier:-b
Assignment Operator
Identifier:-b
Operator
Number:-1

Dept of CSE /IT 23 CS316


Week-8
Experiment No -5
Objective:

First and Follow

ALGORITHM OF FIRST

To compute FIRST(X) for all grammar symbols x, apply the following rules until no more terminals can be
added to any FIRST set.

1. if X is terminal, then FIRST(X) is {X}.


2. if X is nonterminal and X-> aĮ is a production, then add a to FIRST(X). if X->€ to
FIRST(X)
3. if -> Y1,Y2,…….Yk is a production, then for all i such that all of Y1,….Yi-1 are nonterminals and
FIRST(Yj) contains € for j=1,2,…… i-1, add every non-€ symbol in FIRST(Y1) to FIRST(x). if V is
in FIRST(Yj) for j=1,2,………k, then add € to FIRST(X).

ALGORITHM OF FOLLOW

To compute FIRST(X) for all grammar symbols x, apply the following rules until no more terminals can be
added to any FIRST set.

1. if X is terminal, then FIRST(X) is {X}.


2. if X is nonterminal and X-> aĮ is a production, then add a to FIRST(X). if X->€ to
FIRST(X)
3. if -> Y1,Y2,…….Yk is a production, then for all i such that all of Y1,….Yi-1 are nonterminals and
FIRST(Yj) contains € for j=1,2,…… i-1, add every non-€ symbol in FIRST(Y1) to FIRST(x). if V is
in FIRST(Yj) for j=1,2,………k, then add € to FIRST(X).

Week-9

5.1 Write a program to implement First.


5.2 Write a program to implement Follows.

#include"stdio.h"
#include<conio.h>
#define max 10
#define MAX 15
char array[max][MAX],temp[max][MAX];
int c,n,t;
void fun(int,int[]);
int fun2(int i,int j,int p[],int key)

Dept of CSE /IT 24 CS316


{
int k;
if(!key)
{
for(k=0;k<n;k++)
if(array[i][j]==array[k][0])
break;
p[0]=i;p[1]=j+1;
fun(k,p);
return 0;
}
else
{
for(k=0;k<=c;k++)
{
if(array[i][j]==temp[t][k])
break;
}
if(k>c)return 1;
else return 0;
}
}
void fun(int i,int p[])
{
int j,k,key;
for(j=2;array[i][j]!='\0';j++)
{
if(array[i][j-1]=='/')
{
if(array[i][j]>='A'&&array[i][j]<='Z')
{
key=0;
fun2(i,j,p,key);
}
else
{key=1;
if(fun2(i,j,p,key))
temp[t][++c]=array[i][j];
if(array[i][j]=='@'&&p[0]!=-1)
{ //taking ,@, as null symbol.
if(array[p[0]][p[1]]>='A'&&array[p[0]][p[1]]<='Z')
{
key=0;
fun2(p[0],p[1],p,key);
}
else
if(array[p[0]][p[1]]!='/'&&array[p[0]][p[1]]!='\0')
{
if(fun2(p[0],p[1],p,key))
temp[t][++c]=array[p[0]][p[1]];

Dept of CSE /IT 25 CS316


}
}
}
}
}
}
char fol[max][MAX],ff[max];int f,l,ff0;
void ffun(int,int);
void follow(int i)
{
int j,k;
for(j=0;j<=ff0;j++)
if(array[i][0]==ff[j])
return 0;
if(j>ff0)ff[++ff0]=array[i][0];
if(i==0)fol[l][++f]='$';
for(j=0;j<n;j++)
for(k=2;array[j][k]!='\0';k++)
if(array[j][k]==array[i][0])
ffun(j,k);
}
void ffun(int j,int k)
{
int ii,null=0,tt,cc;
if(array[j][k+1]=='/'||array[j][k+1]=='\0')
null=1;
for(ii=k+1;array[j][ii]!='/'&&array[j][ii]!='\0';ii++)
{
if(array[j][ii]<='Z'&&array[j][ii]>='A')
{
for(tt=0;tt<n;tt++)
if(temp[tt][0]==array[j][ii])break;
for(cc=1;temp[tt][cc]!='\0';cc++)
{
if(temp[tt][cc]=='@')null=1;
else fol[l][++f]=temp[tt][cc];
}
}
else fol[l][++f]=array[j][ii];
}
if(null)follow(j);
}
void main()
{
int p[2],i,j;
clrscr();
printf("Enter the no. of productions :");
scanf("%d",&n);
printf("Enter the productions :\n");
for(i=0;i<n;i++)

Dept of CSE /IT 26 CS316


scanf("%s",array[i]);
for(i=0,t=0;i<n;i++,t++)
{
c=0,p[0]=-1,p[1]=-1;
temp[t][0]=array[i][0];
fun(i,p);
temp[t][++c]='\0';
printf("First(%c) : [ ",temp[t][0]);
for(j=1;j<c;j++)
printf("%c,",temp[t][j]);
printf("\b ].\n");
}

/* Follow Finding */
for(i=0,l=0;i<n;i++,l++)
{
f=-1;ff0=-1;
fol[l][++f]=array[i][0];
follow(i);
fol[l][++f]='\0';
}
for(i=0;i<n;i++)
{
printf("\nFollow[%c] : [ ",fol[i][0]);
for(j=1;fol[i][j]!='\0';j++)
printf("%c,",fol[i][j]);
printf("\b ]");
getch();
}
}

Out Put:

Enter the no. of productions: 2


Enter the productions:
S->CC
C->eC/d

First(S) : [ ].
First(C) : [ d ].

Follow[S] : [ $ ]
Follow[C] : [ d,$ ]

Dept of CSE /IT 27 CS316


Week-10
Experiment No 6

Objective: To implement recursive decent parsing.

One of the most straightforward forms of parsing is recursive descent parsing. This is a top-down process in
which the parser attempts to verify that the syntax of the input stream is correct as it is read from left to
right. A basic operation necessary for this involves reading characters from the input stream and matching
then with terminals from the grammar that describes the syntax of the input. Our recursive descent parsers
will look ahead one character and advance the input stream reading pointer when proper matches occur. The
routine presented in figure 1 accomplishes this matching and reading process.

Figure 1 - Symbol Matching Routine


Note that the variable called 'next' looks ahead and always provides the next character that will be read from
the input stream. This feature is essential if we wish our parsers to be able to predict what is due to arrive as
input. Note also that an error indicator is returned.
What a recursive descent parser actually does is to perform a depth-first search of the derivation tree for the
string being parsed. This provides the 'descent' portion of the name. The 'recursive' portion comes from the
parser's form, a collection of recursive procedures.
As our first example, consider the simple grammar
E  x+T
T (E)
T x
and the derivation tree in figure 2 for the expression x+(x+x)

Dept of CSE /IT 28 CS316


Figure 2 - Derivation Tree for x+(x+x)
Writing a recursive descent parser for this is now quite simple. The general factoring algorithm is presented
in figure 3 with  as the common prefix and  i as the suffixes mentioned above.

Figure 3 - Factoring
Let us attempt another example, namely the old favorite, a grammar that generates strings of the
form anbn shown below.

S  aSb
S  ab

Factoring brings us:

S  aZ
Z  Sb
Zb

Which is not quite the form we want since it is unclear when to apply the Z-productions. Substituting for S
will solve this problem and produce the following productions that are exactly what we want to have.

S  aZ
Z  aZb
Zb

Dept of CSE /IT 29 CS316


6.1 Write a program to implement recursive decent parsing.

Solution:
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
int i,l;
int c=0;
char a[10];
clrscr();
printf("Enter the Expression and place $ at the End\n");
for(i=0;i<10;i++)
{
scanf("%c",&a[i]);
}
l=strlen(a);
for(i=0;i<l;i++)
{
if(a[i]=='a'||a[i]=='b'||a[i]=='c'||a[i]=='d'|a[i]=='e')
{
c++;
printf("\n\n Variable:-");
printf("%c",a[i]);
}
else if(a[i]=='+'||a[i]=='-'||a[i]=='*'||a[i]=='/')
{
printf("\n\n Arithmetic Operator:\t");
printf("%c",a[i]);
c++;
}
}
if(a[c]=='$')
printf("\n\n The String is Parsed");
else
printf("\n\n The String is not Parsed");
getch();
}

Dept of CSE /IT 30 CS316


Out Put:

Enter the Expression and place $ at the End


a+b-c*d$

Variable:-a
Arithmetic Operator: +
Variable:-b
Arithmetic Operator: -
Variable:-c
Arithmetic Operator: *
Variable:-d
The String is Parsed

Dept of CSE /IT 31 CS316


Week-11
Experiment No -7

Objective: To implement predictive parsing

The goal of predictive parsing is to construct a top-down parser that never backtracks. To do so, we must
transform a grammar in two ways:
1. eliminate left recursion, and
2. Perform left factoring.

In computer science, a recursive descent parser is 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 production rules of the grammar. Thus the structure of the resulting program closely mirrors that of the
grammar it recognizes.

A predictive parser is a recursive descent parser that does not require backtracking. Predictive parsing is
possible only for the class of LL(k) grammars, which are the context-free grammars for which there exists
some positive integer k that allows a recursive descent parser to decide which production to use by
examining only the next k tokens of input. (The LL(k) grammars therefore exclude all ambiguous grammars,
as well as all grammars that contain left recursion.

Dept of CSE /IT 32 CS316


7.1 Write a program to implement predictive parsing.

Solution:
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
char fin[10][20],st[10][20],ft[20][20],fol[20][20];
int a=0,e,i,t,b,c,n,k,l=0,j,s,m,p;
clrscr();
printf("\n\nenter the no. of Grammer\n");
scanf("%d",&n);
printf("enter the productions in a grammar\n");
for(i=0;i<n;i++)
scanf("%s",st[i]);
for(i=0;i<n;i++)
fol[i][0]='\0';
for(s=0;s<n;s++)
{
for(i=0;i<n;i++)
{
j=3;
l=0;
a=0;
l1:if(!((st[i][j]>64)&&(st[i][j]<91)))
{
for(m=0;m<l;m++)
{
if(ft[i][m]==st[i][j])
goto s1;
}
ft[i][l]=st[i][j];
l=l+1;
s1:j=j+1;
}
else
{
if(s>0)
{
while(st[i][j]!=st[a][0])
{
a++;
}
b=0;
while(ft[a][b]!='\0')
{
for(m=0;m<l;m++)

Dept of CSE /IT 33 CS316


{
if(ft[i][m]==ft[a][b])
goto s2;
}
ft[i][l]=ft[a][b];
l=l+1;
s2:b=b+1;
}
}
}
while(st[i][j]!='\0')
{
if(st[i][j]=='|')
{
j=j+1;
goto l1;
}
j=j+1;
}
ft[i][l]='\0';
}
}
printf("first pos\n");
for(i=0;i<n;i++)
printf("FIRS[%c]=%s\n",st[i][0],ft[i]);
fol[0][0]='$';
for(i=0;i<n;i++)
{
k=0;
j=3;
if(i==0)
l=1;
else
l=0;
k1:while((st[i][0]!=st[k][j])&&(k<n))
{
if(st[k][j]=='\0')
{
k++;
j=2;
}
j++;
}
j=j+1;
if(st[i][0]==st[k][j-1])
{
if((st[k][j]!='|')&&(st[k][j]!='\0'))
{
a=0;
if(!((st[k][j]>64)&&(st[k][j]<91)))

Dept of CSE /IT 34 CS316


{
for(m=0;m<l;m++)
{
if(fol[i][m]==st[k][j])
goto q3;
}
fol[i][l]=st[k][j];
l++;
q3:
}
else
{
while(st[k][j]!=st[a][0])
{
a++;
}
p=0;
while(ft[a][p]!='\0')
{
if(ft[a][p]!='@')
{
for(m=0;m<l;m++)
{
if(fol[i][m]==ft[a][p])
goto q2;
}
fol[i][l]=ft[a][p];
l=l+1;
}
else
e=1;
q2:p++;
}
if(e==1)
{
e=0;
goto a1;
}
}
}
else
{
a1:c=0;
a=0;
while(st[k][0]!=st[a][0])
{
a++;
}
while((fol[a][c]!='\0')&&(st[a][0]!=st[i][0]))
{

Dept of CSE /IT 35 CS316


for(m=0;m<l;m++)
{
if(fol[i][m]==fol[a][c])
goto q1;
}
fol[i][l]=fol[a][c];
l++;
q1:c++;
}
}
goto k1;
}
fol[i][l]='\0';
}
printf("follow pos\n");
for(i=0;i<n;i++)
printf("FOLLOW[%c]=%s\n",st[i][0],fol[i]);
printf("\n");
s=0;
for(i=0;i<n;i++)
{
j=3;
while(st[i][j]!='\0')
{
if((st[i][j-1]=='|')||(j==3))
{
for(p=0;p<=2;p++)
{
fin[s][p]=st[i][p];
}
t=j;
for(p=3;((st[i][j]!='|')&&(st[i][j]!='\0'));p++)
{
fin[s][p]=st[i][j];
j++;
}
fin[s][p]='\0';
if(st[i][k]=='@')
{
b=0;
a=0;
while(st[a][0]!=st[i][0])
{
a++;
}
while(fol[a][b]!='\0')
{
printf("M[%c,%c]=%s\n",st[i][0],fol[a][b],fin[s]);
b++;
}

Dept of CSE /IT 36 CS316


}
else if(!((st[i][t]>64)&&(st[i][t]<91)))
printf("M[%c,%c]=%s\n",st[i][0],st[i][t],fin[s]);
else
{
b=0;
a=0;
while(st[a][0]!=st[i][3])
{
a++;
}
while(ft[a][b]!='\0')
{
printf("M[%c,%c]=%s\n",st[i][0],ft[a][b],fin[s]);
b++;
}
}
s++;
}
if(st[i][j]=='|')
j++;
}
}
getch();
}

OutPut:

Enter the no. of Grammars:-


2
Enter the productions in a grammar
S->CC
C->eC | d

First pos
FIRS[S] = ed
FIRS[C] = ed

Follow pos
FOLLOW[S] =$
FOLLOW[C] =ed$

M [S , e] =S->CC
M [S , d] =S->CC
M [C , e] =C->eC
M [C , d] =C->d

Dept of CSE /IT 37 CS316


Week-12
Experiment No- 8
Objective: Check string belongs to grammar or not.

ALGORITHM

Start.
Declare two character arrays str[],token[] and initialize integer variables a=0,b=0,c,d.
Input the string from the user.
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++.
Check if isdigit(str[a]) then
Repeat steps 8 till isdigit(str[a])
a++.
a--, token[b] =’6’, b++.
Ifstr[a]=='+’then token[b]='2',b++.
If(str[a]=='*')then token[b]=’3’,b++.
a++.
token[b]='\0';
then print the token generated for the string .
b=0.
Repeat step 22 to 31 till token[b]!='\0'
c=0.
Repeat step 24 to 30 till (token[b] =='6' and token [b+1] =='2' and 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++;
Repeat step 27 to 28 till token[c]! ='\0'. token[c]=token[c+2].
c++.
token[c-2]=’\0’.
print token.
b++.
Compare token with 6 and store the result in d.
If d=0 then print that the string is in the grammar.
Else print that the string is not in the grammar.
Stop.

Dept of CSE /IT 38 CS316


8.1 Write a program to check whether given string belongs to grammar or not.

Solution:
#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++;
}
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'))/*||((tok[b ]!=6)&&(tok[b+1]!='\0'))*/)
{

Dept of CSE /IT 39 CS316


tok[b]='6';
c=b+1;
while(tok[c]!='\0')
{
tok[c]=tok[c+2];
c++;
}
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();
}

Output:

Input the expression = (23+)


4625
4625
4625
4625
4625
It is not in the grammar

Input the expression = (2+(3+4)+5) 46246265265


46246265265
46246265265
46246265265
46246265265
462465265
462465265
462465265
462465265
4626265
4626265
46265
46265
465
6
6
It is in the grammar

Dept of CSE /IT 40 CS316


Week-13
Experiment No-9

Objective: to implement operator precedence parsing.

Theory:
An operator precedence parser is a bottom-up parser that interprets an operator-precedence grammar. An
operator-precedence parser is a simple shift-reduce parser that is capable of parsing a subset of LR (1)
grammars. More precisely, the operator-precedence parser can parse all LR (1) grammars where two
consecutive non terminals never appear in the right-hand side of any rule.

Operator-precedence parsers are not used often in practice; however they do have some properties that make
them useful within a larger design. First, they are simple enough to write by hand, which is not generally the
case with more sophisticated shift-reduce parsers. Second, they can be written to consult an operator table at
run time, which makes them suitable for languages that can add to or change their operators while parsing.
This page lists C operators in order of precedence (highest to lowest). Their associatively indicates in what
order operators of equal precedence in an expression are applied.

Operator Description Associativity


() Parentheses (function call) (see Note 1) left-to-right
[] Brackets (array subscript)
. Member selection via object name
-> Member selection via pointer
++ -- Postfix increment/decrement (see Note 2)
++ -- Prefix increment/decrement right-to-left
+- Unary plus/minus
!~ Logical negation/bitwise complement
(type) Cast (convert value to temporary value of type)
* Dereference
& Address (of operand)
sizeof Determine size in bytes on this implementation
* / % Multiplication/division/modulus left-to-right
+ - Addition/subtraction left-to-right
<< >> Bitwise shift left, Bitwise shift right left-to-right
< <= Relational less than/less than or equal to left-to-right
> >= Relational greater than/greater than or equal to
== != Relational is equal to/is not equal to left-to-right
& Bitwise AND left-to-right
^ Bitwise exclusive OR left-to-right
| Bitwise inclusive OR left-to-right
&& Logical AND left-to-right
|| Logical OR left-to-right

Dept of CSE /IT 41 CS316


?: Ternary conditional right-to-left
= Assignment right-to-left
+= -= Addition/subtraction assignment
*= /= Multiplication/division assignment
%= &= Modulus/bitwise AND assignment
^= |= Bitwise exclusive/inclusive OR assignment
<<= >>= Bitwise shift left/right assignment
, Comma (separate expressions) left-to-right

Note 1:
Parentheses are also used to group sub-expressions to force a different
precedence; such parenthetical expressions can be nested and are evaluated from
inner to outer.
Note 2:
Postfix increment/decrement have high precedence, but the actual increment or
decrement of the operand is delayed (to be accomplished sometime before the
statement completes execution). So in the statement y = x * z++; the current value
of z is used to evaluate the expression (i.e., z++ evaluates to z) and z only
incremented after all else is done.

9.1 WRITE A PROGRAMME TO IMPLEMENT OPERATOR PRECEDENCE PARSER.

Solution:

#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#include<string.h>
#include<stdlib.h>
struct stack
{
char nts,trs;
};

struct stack stack[20];


int lead[20][20],trail[20][20],nop,top=0,i;
char nr,tr,p[10][10],nt[20],t[20],opt[20][20],starts,stk[20];
void read_grammar()
{
printf("Enter the Terminal:");
gets(t);
printf("Enter the Non Terminal:");
gets(nt);
printf("Enter No. of Productions:");
scanf("%d", &nop);
for(i=0;i<nop;i++)

Dept of CSE /IT 42 CS316


{
scanf("%s", &p[i]);
}
starts=p[0][0];
}
int nt_no(char x)
{
if(x!='\0')
{
for(i=0;nt[i]!='\0';i++)
{
if(nt[i]==x)
return (i);
}
}
}
int t_no(char x)
{
if(x!='\0')
{
for(i=0;nt[i]!='\0';i++)
{
if(nt[i]==x)
return(i);
if(x=='$')
return(strlen(t));
}
}
}
int nonterminal(char x)
{
if(x!='\0')
{
for(i=0;i<strlen(nt);i++)
{
if(nt[i]==x)
return(1);
}
}
return 0;
}
int terminal(char x)
{
if(x!='\0')
{
for(i=0;i<strlen(nt);i++)
{
if(t[i]==x)
return(1);
}

Dept of CSE /IT 43 CS316


}
return 0;
}
void push(int r,int c)
{
top++;
stack[top].nts=nt[r];
stack[top].nts=t[c];
}
void pop()
{
nr=stack[top].nts;
tr=stack[top].nts;
top--;
}
void install(int r,int c, int lt)
{
if(lt==1)
{
if(!lead[r][c])
{
lead[r][c]=1;
push(r,c);
}
}
if(lt==2)
{
if(!lead[r][c])
{
lead[r][c]=1;
push(r,c);
}
}
}
void leading()
{
char a;
int r,c,no,j,l;
top=0;
for(no=0;nt[no]!='\0';no++)
{
for(i=0;i<nop;i++)
{
if(nt[no]==p[i][0])
{
a=p[i][3];
if(terminal(a))
{
r=nt_no(p[i][0]);
c=t_no(a);

Dept of CSE /IT 44 CS316


install(r,c,l);
}

else if(nonterminal(a) && terminal(p[i][4]))


{
r=nt_no(p[i][0]);
c=t_no(p[i][4]);
install(r,c,l);
}

while(top!=0)
{
pop();
for(j=0;j<nop;j++)
{
char nont=p[j][3];
if(nont==nr)
{
r=nt_no(p[j][0]);
c=t_no(tr);
install(r,c,l);
}
}
}
}
}
}
}
void trailing()
{
char a;
int r,c,no,j,l;
top=0;
for(no=0;nt[no]!='\0';no++)
{
for(i=0;i<nop;i++)
{
if(nt[no]==p[i][0])
{
l=strlen(p[i]);
a=p[i][l-1];
if(terminal(a))
{
r=nt_no(p[i][0]);
c=t_no(a);
install(r,c,2);
}

else if(nonterminal(a) && terminal(p[i][i-2]))


{

Dept of CSE /IT 45 CS316


r=nt_no(p[i][0]);
c=t_no(p[i][l-2]);
install(r,c,2);
}

while(top!=0)
{
pop();
for(j=0;j<nop;j++)
{
char nont=p[j][3];
l=strlen(p[j]);

if(nont==nr)
{
r=nt_no(p[j][0]);
c=t_no(tr);
install(r,c,2);
}
}
}
}
}
}
}
void prec_tab()
{
int r,c,no,j,l,pos,pl;
top=0;
for(no=0;no<nop;no++)
{
l=strlen(p[no]);
for(i=3;i<l-2;i++)
{
if(terminal(p[no][i])&& terminal(p[no][i+1]))
{
r=nt_no(p[no][i]);
c=t_no(p[no][i+1]);
opt[r][c]='=';
}
if(i<l-3)
{
if(terminal(p[no][i]) && terminal(p[no][i+2]) && nonterminal(p[no][i+1]))
{
r=nt_no(p[no][i]);
c=t_no(p[no][i+1]);
opt[r][c]='=';
}
}
if(terminal(p[no][i]) && nonterminal(p[no][i+1]))

Dept of CSE /IT 46 CS316


{
pos=nt_no(p[no][i+1]);
for(j=0;j<strlen(t);j++)
{
if(lead[pos][j])
{
r=nt_no(p[no][i]);
opt[r][j]='<';
}
}
}
if(terminal(p[no][i]) && nonterminal(p[no][i+1]))
{
pos=nt_no(p[no][i]);
for(j=0;j<strlen(t);j++)
{
if(trail[pos][j])
{
r=nt_no(p[no][i]);
opt[j][c]='>';
}
}
}
}
}
pos=nt_no(starts);
l=strlen(t);
for(pl=0;pl<strlen(t);pl++)
if(lead[pos][p])
opt[l][p]='<';
for(pl=0;pl<strlen(t);pl++)
if(trail[pos][p])
opt[l][p]='>';
}
void show()
{
int x,y;
printf("\n Leading:");
for(x=0;x<strlen(nt);x++)
{
printf("\n Leading(%c)={",nt[x]);
for(y=0;y<strlen(t);y++)
if(lead[x][y])
printf("%c", ",", t[y]);
printf("}");
}
printf("\n Trailing:");
for(x=0;x<strlen(nt);x++)
{
printf("\n Leading(%c)={", nt[x]);

Dept of CSE /IT 47 CS316


for(y=0;y<strlen(t);y++)
if(trail[x][y])
printf("%c", t[y]);
printf("}");
}
}
void show_tab()
{
int l=strlen(t),i,j;
clrscr();
printf("\n Operator Precedence Grammar:\n\t");
for(i=0;i<=l;i++)
printf("\t%c", t[i]);
printf("$");
printf("\n _______________\n");
for(i=0;i<=l;i++)
{
if(i==l)
printf("\n $");
else
printf("\n %c", t[i]);
printf("\t");
for(j=0;j<=l;j++)
{
if(opt[i][j]=='\0')
printf("\t");
else
printf("\t%c", opt[i][j]);
}
printf("\n\t");
}
printf("\n _________________");
}
int parse_str(char *str)
{
char ts,cs;
int r,c,pt,pc;
stk[top]='$';
printf("\n STACK \t INPUT \t ACTION \n");
printf("%c\t\t%s\t\t\n", stk[top],str);
while(1)
{
if(stk[top]=='$' && str[0]=='$')
{
printf("%c\t%c\t\t Accept \n", stk[top],str[0]);
return 1;
}
else
{
ts=stk[top];

Dept of CSE /IT 48 CS316


cs=str[0];
r=t_no(ts);
c=t_no(cs);
if(opt[r][c]=='<<'||opt[r][c]=='=')
{
int t=0;
printf(" ");
while(t<=top)
{
printf("%c", stk[top]);
t++;
}
top++;
stk[top]=cs;
printf("%c%c\t", opt[r][c],stk[top]);
strlen(str)!=1?strcpy(str,&str[1]):0;
printf("%s", str);
if(opt[r][c]=='>')
printf("\t\t Shift \n");
}
else if(opt[r][c]=='>')
{
do
{
char pops=stk[top];
int t=0;
printf(" ");
while(t<=top)
{
printf("%c",stk[t]);
t++;
}
top--;
if(stk[top]!='$')
printf("%c%c\t%s\t\t Reduce \n", opt[r][c],stk[top],str);
else
printf("%c\t%s\t\t Reduce \n", opt[r][c],str);
pt=t_no(stk[top]);
pc=t_no(pops);
}
while(opt[pt][pc]!='<');
}
else
break;
}
}
return 0;
}
void main()
{

Dept of CSE /IT 49 CS316


char *str,string[20];
int l;
clrscr();
read_grammar();
clrscr();
leading();
trailing();
clrscr();
show();
getch();
prec_tab();
show_tab();
getch();
clrscr();
printf("Enter string to parse:");
scanf("%s", str);
l=strlen(str);
strcpy(string,str);
str[l]='$';
str[l+1]='\0';
if(parse_str(str))
printf("\n String:%s is accepted", str);
else
printf("\n String:%s is not accepted", str);
getch();
}

Dept of CSE /IT 50 CS316

You might also like