0% found this document useful (0 votes)
11 views44 pages

CD File

The document discusses YACC and LEX, which are tools used to generate parsers and lexical analyzers. YACC generates parsers based on context-free grammars specified in BNF-like notation. LEX generates scanners that recognize patterns in input text defined by regular expressions. The document provides examples and explanations of how these tools work.

Uploaded by

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

CD File

The document discusses YACC and LEX, which are tools used to generate parsers and lexical analyzers. YACC generates parsers based on context-free grammars specified in BNF-like notation. LEX generates scanners that recognize patterns in input text defined by regular expressions. The document provides examples and explanations of how these tools work.

Uploaded by

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

Gateway Institute of Engineering & Technology (GIET)

Program-1
To study about yacc and lex.
YACC: Yet Another Compiler-Compiler

The computer program YACC is a LALR parser generator developed by Stephen C. Johnson at
AT&T Corporation for the Unix operating system in 1970. The name is an acronym for "Yet
Another Compiler-Compiler". It generates a parser, the part of a compiler that tries to make
syntactic sense of the source code, specifically a LALR parser, based on an analytic grammar
written in a notation similar to BNF.

YACC itself used to be available as the default parser generator on most Unix systems, though it
has since been supplanted as the default by more recent, largely compatible, programs such as
Berkeley YACC, GNU bison, MKS YACC and Abraxas PCYACC. YACC has also been rewritten
for other languages, including Ratfor, ML, Ada, Pascal, Java, Python, Ruby, Go and Common Lisp.

The IEEE POSIX P1003.2 standard defines the functionality and requirements for both Lex and
YACC.

Computer program input generally has some structure; in fact, every computer program that does
input can be thought of as defining an ``input language'' which it accepts. An input language may
be as complex as a programming language, or as simple as a sequence of numbers. Unfortunately,
usual input facilities are limited, difficult to use, and often are lax about checking their inputs for
validity.

YACC provides a general tool for describing the input to a computer program. The YACC user
specifies the structures of his input, together with code to be invoked as each such structure is
recognized. YACC turns such a specification into a subroutine that handles the input process;
frequently, it is convenient and appropriate to have most of the flow of control in the user's
application handled by this subroutine.

YACC Theory

Grammars for YACC are described using a variant of Backus Naur Form (BNF). This technique,
pioneered by John Backus and Peter Naur, was used to describe ALGOL60. A BNF grammar can
be used to express context-free languages. Most constructs in modern programming languages can
be represented in BNF. For example, the grammar for an expression that multiplies and adds
numbers is

1 E -> E + E
2 E -> E * E
3 E -> id

Sakshi 1 21010001018
Gateway Institute of Engineering & Technology (GIET)

Three productions have been specified. Terms that appear on the left-hand side (lhs) of a
production, such as E, are nonterminals. Terms such as id (identifier) are terminals (tokens returned
by lex) and only appear on the right-hand side (rhs) of a production. This grammar specifies that
an expression may be the sum of two expressions, the product of two expressions, or an identifier.
We can use this grammar to generate expressions:
E -> E * E (r2)
-> E * z (r3)
-> E + E * z (r1)
-> E + y * z (r3)
-> x + y * z (r3)
At each step we expanded a term and replace the lhs of a production with the corresponding rhs.
The numbers on the right indicate which rule applied. To parse an expression we a need to do the
reverse operation. Instead of starting with a single nonterminal (start symbol) and generating an
expression from a grammar we need to reduce an expression to a single nonterminal. This is known
as bottom-up or shift reduce parsing and uses a stack for storing terms. Here is the same derivation
but in reverse order:
1 . x + y * z shift
2 x . + y * z reduce(r3)
3 E . + y * z shift
4 E + . y * z shift
5 E + y . * z reduce(r3)
6 E + E . * z shift
7 E + E * . z shift
8 E + E * z . reduce(r3)
9 E + E * E . reduce(r2) emit multiply
10 E + E . reduce(r1) emit add
11 E . accept
Terms to the left of the dot are on the stack while remaining input is to the right of the dot. We start
by shifting tokens onto the stack. When the top of the stack matches the rhs of a production we
replace the matched tokens on the stack with the lhs of the production. In other words the matched
tokens of the rhs are popped off the stack, and the lhs of the production is pushed on the stack. The
matched tokens are known as a handle and we are reducing the handle to the lhs of the production.
This process continues until we have shifted all input to the stack and only the starting nonterminal
remains on the stack. In step 1 we shift the x to the stack. Step 2 applies rule r3 to the stack to
change x to E. We continue shifting and reducing until a single nonterminal, the start symbol,
remains in the stack. In step 9, when we reduce rule r2, we emit the multiply instruction. Similarly
the add instruction is emitted in step 10. Consequently multiply has a higher precedence than
addition.
Consider the shift at step 6. Instead of shifting we could have reduced and apply rule r1. This would
result in addition having a higher precedence than multiplication. This is known as a shiftreduce
conflict. Our grammar is ambiguous because there is more than one possible derivation that will

Sakshi 2 21010001018
Gateway Institute of Engineering & Technology (GIET)

yield the expression. In this case operator precedence is affected. As another example, associativity
in the rule

E -> E + E

is ambiguous, for we may recurse on the left or the right. To remedy the situation, we could rewrite
the grammar or supply YACC with directives that indicate which operator has precedence. The
latter method is simpler and will be demonstrated in the practice section.

YACC takes a default action when there is a conflict. For shift-reduce conflicts YACC will shift.
For reduce-reduce conflicts it will use the first rule in the listing. It also issues a warning message
whenever a conflict exists. The warnings may be suppressed by making the grammar unambiguous.
Several methods for removing ambiguity will be presented in subsequent sections.

Lex - A Lexical Analyzer Generator

Lex is a computer program that generates lexical analyzers ("scanners" or "lexers").


Lex is commonly used with the YACC parser generator. Lex, originally written by Mike Lesk and
Eric Schmidt and described in 1975, is the standard lexical analyzer generator on many Unix
systems, and a tool exhibiting its behavior is specified as part of the POSIX standard.
Lex reads an input stream specifying the lexical analyzer and outputs source code implementing
the lexer in the C programming language.

Lex helps write programs whose control flow is directed by instances of regular expressions in the
input stream. It is well suited for editor-script type transformations and for segmenting input in
preparation for a parsing routine.

Lex source is a table of regular expressions and corresponding program fragments. The table is
translated to a program which reads an input stream, copying it to an output stream and partitioning
the input into strings which match the given expressions. As each such string is recognized the
corresponding program fragment is executed. The recognition of the expressions is performed by
a deterministic finite automaton generated by Lex. The program fragments written by the user are
executed in the order in which the corresponding regular expressions occur in the input stream.

Lex Theory

During the first phase the compiler reads the input and converts strings in the source to tokens.
With regular expressions we can specify patterns to lex so it can generate code that will allow it to
scan and match strings in the input. Each pattern in the input to lex has an associated action.
Typically an action returns a token that represents the matched string for subsequent use by the
parser. Initially we will simply print the matched string rather than return a token value.

Sakshi 3 21010001018
Gateway Institute of Engineering & Technology (GIET)

The following represents a simple pattern, composed of a regular expression, that scans for
identifiers. Lex will read this pattern and produce C code for a lexical analyzer that scans for
identifiers.

letter(letter|digit)*

This pattern matches a string of characters that begins with a single letter followed by zero or
more letters or digits. This example nicely illustrates operations allowed in regular expressions:

 repetition, expressed by the " * " operator


 alternation, expressed by the "|" operator
 concatenation

Any regular expression expressions may be expressed as a finite state automaton (FSA). We can
represent an FSA using states, and transitions between states. There is one start state and one or
more final or accepting states.

In Figure 3 state 0 is the start state and state 2 is the accepting state. As characters are read we make
a transition from one state to another. When the first letter is read we transition to state 1. We
remain in state 1 as more letters or digits are read. When we read a character other than a letter or
digit we transition to accepting state 2. Any FSA may be expressed as a computer program. For
example, our 3-state machine is easily programmed:

start: goto state0

state0: read c if c = letter


goto state1 goto state0
state1: read c if c = letter
goto state1 if c = digit goto
state1 goto state2 state2:
accept string

Sakshi 4 21010001018
Gateway Institute of Engineering & Technology (GIET)

This is the technique used by lex. Regular expressions are translated by lex to a computer program
that mimics an FSA. Using the next input character and current state the next state is easily
determined by indexing into a computer-generated state table.

Now we can easily understand some of lex’s limitations. For example, lex cannot be used to
recognize nested structures such as parentheses. Nested structures are handled by incorporating a
stack. Whenever we encounter a "(" we push it on the stack. When a ")" is encountered we match
it with the top of the stack and pop the stack. However lex only has states and transitions between
states. Since it has no stack it is not well suited for parsing nested structures. YACC augments an
FSA with a stack and can process constructs such as parentheses with ease. The important thing is
to use the right tool for the job. Lex is good at pattern matching. YACC is appropriate for more
challenging tasks.

Sakshi 5 21010001018
Gateway Institute of Engineering & Technology (GIET)

Program-2
Write a Program to store 10 elements in an array. Compute sum of all the even and
elements. Display the result.
Source code -:
#include<stdio.h>
#include<conio.h> void
main() {
int ar[10], i, s1, s2; clrscr();
for(i=0; i<=9; i++)
{
printf("\nEnter element: ”);
scanf(“%d”,&ar[i]);
} s1=0;
s2=0;
for(i=0; i<=9; i++) {
if(ar[i]%2==0) s1=s1+ar[i];
Else s2=s2+ar[i]; printf("\nEven
sum=%d”,s1); printf("\nOdd
sum=%d”,s2);
getch();
}

Sakshi 6 21010001018
Gateway Institute of Engineering & Technology (GIET)

Output:-

Sakshi 7 21010001018
Gateway Institute of Engineering & Technology (GIET)

Program-3
Write a program to implement string functions in C language.
Source code-:
#include<stdio.h>
#include<string.h>
int main()
{
char gram[20],part1[20],part2[20],modifiedGram[20],newGram[20],tempGram[20];
int i,j=0,k=0,l=0,pos;
printf("Enter Production : A->");
gets(gram);
for(i=0;gram[i]!='|';i++,j++)
part1[j]=gram[i];
part1[j]='\0';
for(j=++i,i=0;gram[j]!='\0';j++,i++)
part2[i]=gram[j];
part2[i]='\0';
for(i=0;i<strlen(part1)||i<strlen(part2);i++)
{
if(part1[i]==part2[i])
{
modifiedGram[k]=part1[i];
k++;
pos=i+1;
}
}
for(i=pos,j=0;part1[i]!='\0';i++,j++){
newGram[j]=part1[i];

Sakshi 8 21010001018
Gateway Institute of Engineering & Technology (GIET)

}
newGram[j++]='|';
for(i=pos;part2[i]!='\0';i++,j++){
newGram[j]=part2[i];
}
modifiedGram[k]='X';
modifiedGram[++k]='\0';
newGram[j]='\0';
printf("\n A->%s",modifiedGram);
printf("\n X->%s\n",newGram);
}

Sakshi 9 21010001018
Gateway Institute of Engineering & Technology (GIET)

Output:

1.String Length:

2.String Concatenation:

3.String Compare:

Sakshi 10 21010001018
Gateway Institute of Engineering & Technology (GIET)

4. String Copy:

5. String Reverse:

Sakshi 11 21010001018
Gateway Institute of Engineering & Technology (GIET)

Program-4
Write a program to implement stack in C language.
Source code -:
#include<stdio.h>
#include<conio.h>
#define max 5
int top=-1,a[max];
void push()
{
int x;
if(top==max-1)
{
printf("\nStack Overflow!");
return;
}
printf("\nEnter a number: ");
scanf("%d",&x);
top=top+1;
a[top]=x;
printf("\nElement %d successfully pushed.",x);
return;
}
void pop()
{
int y;
if(top==-1)
{
printf("\nStack Underflow");
return;
}
y=a[top];
top=top-1;
printf("\nElement %d successfully poped.",y);
return;
}
void display()
{
int i;
if(top==-1)
{
printf("\nStack is empty.");
return;
}
printf("\nElements of stack are: ");
for(i=top; i>=0; i--)
Sakshi 12 21010001018
Gateway Institute of Engineering & Technology (GIET)

{
printf("\n%d",a[i]);
}
return;
}
void main()
{
clrscr();
int ch;
do
{
printf("\n\nOperation you want to perform on stack: ");
printf("\n1. Push");
printf("\n2. Pop");
printf("\n3. Display");
printf("\n4. Exit");
printf("\nEnter your choice: ");
scanf("%d",&ch);
switch(ch)
{
case 1: push();
break;
case 2: pop();
break;
case 3: display();
break;
case 4: printf("\nProgram ends.");
break;
default: printf("\nWrong choice!");
break;
}
}while(ch!=4);
getch();
}

Sakshi 13 21010001018
Gateway Institute of Engineering & Technology (GIET)

Output:

Sakshi 14 21010001018
Gateway Institute of Engineering & Technology (GIET)

Program- 5
Write a program to Perform Read And Write Operations Of A Text File.
Source code -:
#include<stdio.h>
#include<conio.h>
void main( )
{
FILE *fp;
char ch;
// writing the text file
fp = fopen("test", "w");
printf("\n Enter a character ");
ch = getchar( );
while ( ch != '\n' )
{
putc(ch, fp);
fflush(stdin); // To clear the buffer
printf("\n Enter another character ");
ch = getchar( );
}
fclose(fp);
// reading the test file
fp = fopen("test", "r");
ch = getc(fp);
printf(“\n Reading from file “);
while ( ch != EOF )
{
printf("%c", ch);

Sakshi 15 21010001018
Gateway Institute of Engineering & Technology (GIET)

ch = getc(fp);
}
fclose(fp);
}

Sakshi 16 21010001018
Gateway Institute of Engineering & Technology (GIET)

Output:

Sakshi 17 21010001018
Gateway Institute of Engineering & Technology (GIET)

Program -6
WAP to check whether a string belongs to a Grammar or not.
Source Code:
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main() {
char string[50];
int flag,count=0;
clrscr();
printf("The grammar is: S->aS, S->Sb, S->ab\n");
printf("Enter the string to be checked:\n");
gets(string);
if(string[0]=='a') {
flag=0;
for (count=1;string[count-1]!='\0';count++) {
if(string[count]=='b') {
flag=1;
continue;
} else if((flag==1)&&(string[count]=='a')) {
printf("The string does not belong to the specified grammar");
break;
} else if(string[count]=='a')
continue; else if((flag==1) && (string[count]=='\0')) {
printf("String accepted..!!!!");
break;
} else {
printf("String not accepted");

Sakshi 18 21010001018
Gateway Institute of Engineering & Technology (GIET)

}
}
}
getch();
}

Sakshi 19 21010001018
Gateway Institute of Engineering & Technology (GIET)

Output

Sakshi 20 21010001018
Gateway Institute of Engineering & Technology (GIET)

Program-7
WAP to find leading & trailing of non-terminals.
Source code -:
#include<stdio.h>
#include<string.h>
int nt,t,top=0;
char s[50],NT[10],T[10],st[50],l[10][10],tr[50][50];
int searchnt(char a)
{
int count=-1,i;
for(i=0;i<nt;i++)
{
if(NT[i]==a)
return i;
}
return count;
}

int searchter(char a)
{
int count=-1,i;
for(i=0;i<t;i++)
{
if(T[i]==a)
return i;
}
return count;
}

Sakshi 21 21010001018
Gateway Institute of Engineering & Technology (GIET)

void push(char a)
{
s[top]=a;
top++;
}
char pop()
{
top--;
return s[top];
}
void installl(int a,int b)
{
if(l[a][b]=='f')
{
l[a][b]='t';
push(T[b]);
push(NT[a]);
}
}
void installt(int a,int b)

{
if(tr[a][b]=='f')
{
tr[a][b]='t';
push(T[b]);
push(NT[a]);
}

Sakshi 22 21010001018
Gateway Institute of Engineering & Technology (GIET)

}
void main()
{
int i,s,k,j,n;
char pr[30][30],b,c;
clrscr();
printf("Enter the no of productions:");
scanf("%d",&n);
printf("Enter the productions one by one\n");
for(i=0;i<n;i++)
scanf("%s",&pr[i]);
nt=0;
t=0;
for(i=0;i<n;i++)
{
if((searchnt(pr[i][0]))==-1)
NT[nt++]=pr[i][0];
}
for(i=0;i<n;i++)
{
for(j=3;j<strlen(pr[i]);j++)
{
if(searchnt(pr[i][j])==-1)
{
if(searchter(pr[i][j])==-1)
T[t++]=pr[i][j];
}
}

Sakshi 23 21010001018
Gateway Institute of Engineering & Technology (GIET)

}
for(i=0;i<nt;i++)
{
for(j=0;j<t;j++)
l[i][j]='f';
}
for(i=0;i<nt;i++)
{
for(j=0;j<t;j++)
tr[i][j]='f';
}
for(i=0;i<nt;i++)
{
for(j=0;j<n;j++)
{
if(NT[(searchnt(pr[j][0]))]==NT[i])
{
if(searchter(pr[j][3])!=-1)
installl(searchnt(pr[j][0]),searchter(pr[j][3]));
else
{
for(k=3;k<strlen(pr[j]);k++)
{
if(searchnt(pr[j][k])==-1)
{
installl(searchnt(pr[j][0]),searchter(pr[j][k]));
break;
}

Sakshi 24 21010001018
Gateway Institute of Engineering & Technology (GIET)

}
}
}
}
}
while(top!=0)
{
b=pop();
c=pop();
for(s=0;s<n;s++)
{
if(pr[s][3]==b)
installl(searchnt(pr[s][0]),searchter(c));
}
}
for(i=0;i<nt;i++)
{
printf("Leading[%c]\t{", NT[i]);
for(j=0;j<t;j++)
{
if(l[i][j]=='t')
printf("%c,",T[j]);
}
printf("}\n");
}
top=0;
for(i=0;i<nt;i++)
{

Sakshi 25 21010001018
Gateway Institute of Engineering & Technology (GIET)

for(j=0;j<n;j++)
{
if(NT[searchnt(pr[j][0])]==NT[i])
{
if(searchter(pr[j][strlen(pr[j])-1])!=-1)
installt(searchnt(pr[j][0]),searchter(pr[j][strlen(pr[j])-1]));
else
{
for(k=(strlen(pr[j])-1);k>=3;k--)
{
if(searchnt(pr[j][k])==-1)
{
installt(searchnt(pr[j][0]),searchter(pr[j][k]));
break;
}
}
}
}
}
}
while(top!=0)
{
b=pop();
c=pop();
for(s=0;s<n;s++)
{
if(pr[s][3]==b)
installt(searchnt(pr[s][0]),searchter(c));

Sakshi 26 21010001018
Gateway Institute of Engineering & Technology (GIET)

}
}
for(i=0;i<nt;i++)
{
printf("Trailing[%c]\t{", NT[i]);
for(j=0;j<t;j++)
{
if(tr[i][j]=='t')
printf("%c,", T[j]);
}
printf("}\n");
}
getch();
}

Sakshi 27 21010001018
Gateway Institute of Engineering & Technology (GIET)

Output:

Sakshi 28 21010001018
Gateway Institute of Engineering & Technology (GIET)

Program-8
WAP to find whether a grammar is operator precedence or not.
Source code -:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<conio.h>
// function f to exit from the loop
// if given condition is not true
void f()
{
printf("Not operator grammar");
getch();
exit(0);
}
void main()
{
char grm[20][20], c;
// Here using flag variable,
// considering grammar is not operator grammar
int i, n, j = 2, flag = 0;
clrscr();
// taking number of productions from user
printf("\n enter no of productions ");
scanf("%d", &n);
printf("\n enter production one by one \n");
for (i = 0; i < n; i++)
scanf("%s", grm[i]);

Sakshi 29 21010001018
Gateway Institute of Engineering & Technology (GIET)

for (i = 0; i < n; i++) {


c = grm[i][2];
while (c != '\0') {
if (grm[i][3] == '+' || grm[i][3] == '-'
|| grm[i][3] == '*' || grm[i][3] == '/')
flag = 1;
else
{
flag = 0;
f();
}
if (c == '$') {
flag = 0;
f();
}
c = grm[i][++j];
}
}
if (flag == 1)
printf("Operator grammar");
getch();
}

Sakshi 30 21010001018
Gateway Institute of Engineering & Technology (GIET)

Output:

Sakshi 31 21010001018
Gateway Institute of Engineering & Technology (GIET)

Program-9
Write a program to find FIRST of a non terminals.
Source code -:
#include<stdio.h>
#include<ctype.h>
void FIRST(char );
int count,n=0;
char prodn[10][10], first[10];
main()
{
int i,choice;
char c,ch;
printf("How many productions ? :");
scanf("%d",&count);
printf("Enter %d productions epsilon= $ :\n\n",count);
for(i=0;i<count;i++)
scanf("%s%c",prodn[i],&ch);
do
{
n=0;
printf("Element :");
scanf("%c",&c);
FIRST(c);
printf("\n FIRST(%c)= { ",c);
for(i=0;i<n;i++)
printf("%c ",first[i]);
printf("}\n");
printf("press 0 for Exit & 1 to continue : ");

Sakshi 32 21010001018
Gateway Institute of Engineering & Technology (GIET)

scanf("%d%c",&choice,&ch);
}
while(choice==1);}
void FIRST(char c)
{
int j;
if(!(isupper(c)))first[n++]=c;
for(j=0;j<count;j++)
{
if(prodn[j][0]==c)
{
if(prodn[j][2]=='$')
first[n++]='$';
else if(islower(prodn[j][2]))
first[n++]=prodn[j][2];
else
FIRST(prodn[j][2]);
}
}
}

Sakshi 33 21010001018
Gateway Institute of Engineering & Technology (GIET)

Output:

Sakshi 34 21010001018
Gateway Institute of Engineering & Technology (GIET)

Program-10
Write a program to find FOLLOW of non-terminals.
Source code -:
#include<stdio.h>

#include<string.h>

int n,m=0,p,i=0,j=0;

char a[10][10],followResult[10];

void follow(char c);

void first(char c);

void addToResult(char);

int main()

int i;

int choice;

char c,ch;

printf("Enter the no.of productions: ");

scanf("%d", &n);

printf(" Enter %d productions\nProduction with multiple terms should be give as separate productions
\n", n);

for(i=0;i<n;i++)

scanf("%s%c",a[i],&ch);

// gets(a[i]);

do

m=0;

printf("Find FOLLOW of -->");

scanf(" %c",&c);

follow(c);

printf("FOLLOW(%c) = { ",c);

Sakshi 35 21010001018
Gateway Institute of Engineering & Technology (GIET)

for(i=0;i<m;i++)

printf("%c ",followResult[i]);

printf(" }\n");

printf("Do you want to continue(Press 1 to continue....)?");

scanf("%d%c",&choice,&ch);

while(choice==1);

void follow(char c)

if(a[0][0]==c)addToResult('$');

for(i=0;i<n;i++)

for(j=2;j<strlen(a[i]);j++)

if(a[i][j]==c)

if(a[i][j+1]!='\0')first(a[i][j+1]);

if(a[i][j+1]=='\0'&&c!=a[i][0])

follow(a[i][0]);

void first(char c)

int k;

if(!(isupper(c)))

Sakshi 36 21010001018
Gateway Institute of Engineering & Technology (GIET)

//f[m++]=c;

addToResult(c);

for(k=0;k<n;k++)

if(a[k][0]==c)

if(a[k][2]=='$') follow(a[i][0]);

else if(islower(a[k][2]))

//f[m++]=a[k][2];

addToResult(a[k][2]);

else first(a[k][2]);

void addToResult(char c)

int i;

for( i=0;i<=m;i++)

if(followResult[i]==c)

return;

followResult[m++]=c;

Sakshi 37 21010001018
Gateway Institute of Engineering & Technology (GIET)

Output:

Sakshi 38 21010001018
Gateway Institute of Engineering & Technology (GIET)

Program- 11
Write a program to remove recursion.
Source code -:
#include<stdio.h>
#include<string.h>
#define SIZE 10
int main () {
char non_terminal;
char beta,alpha;
int num;
char production[10][SIZE];
int index=3; /* starting of the string following "->" */
printf("Enter Number of Production : ");
scanf("%d",&num);
printf("Enter the grammar as E->E-A :\n");
for(int i=0;i<num;i++){
scanf("%s",production[i]);
}
for(int i=0;i<num;i++){
printf("\nGRAMMAR : : : %s",production[i]);
non_terminal=production[i][0];
if(non_terminal==production[i][index]) {
alpha=production[i][index+1];
printf(" is left recursive.\n");
while(production[i][index]!=0 && production[i][index]!='|')
index++;
if(production[i][index]!=0) {
beta=production[i][index+1];

Sakshi 39 21010001018
Gateway Institute of Engineering & Technology (GIET)

printf("Grammar without left recursion:\n");


printf("%c->%c%c\'",non_terminal,beta,non_terminal);
printf("\n%c\'->%c%c\'|E\n",non_terminal,alpha,non_terminal);
}
else
printf(" can't be reduced\n");
}
else
printf(" is not left recursive.\n");
index=3;
}
}

Sakshi 40 21010001018
Gateway Institute of Engineering & Technology (GIET)

Output:

Sakshi 41 21010001018
Gateway Institute of Engineering & Technology (GIET)

Program-12
Write a program to remove Factoring.
Source code -:
#include<stdio.h>
#include<string.h>
int main()
{
char gram[20],part1[20],part2[20],modifiedGram[20],newGram[20],tempGram[20];
int i,j=0,k=0,l=0,pos;
printf("Enter Production : A->");
gets(gram);
for(i=0;gram[i]!='|';i++,j++)
part1[j]=gram[i];
part1[j]='\0';
for(j=++i,i=0;gram[j]!='\0';j++,i++)
part2[i]=gram[j];
part2[i]='\0';
for(i=0;i<strlen(part1)||i<strlen(part2);i++)
{
if(part1[i]==part2[i])
{
modifiedGram[k]=part1[i];
k++;
pos=i+1;
}
}
for(i=pos,j=0;part1[i]!='\0';i++,j++){
newGram[j]=part1[i];

Sakshi 42 21010001018
Gateway Institute of Engineering & Technology (GIET)

}
newGram[j++]='|';
for(i=pos;part2[i]!='\0';i++,j++){
newGram[j]=part2[i];
}
modifiedGram[k]='X';
modifiedGram[++k]='\0';
newGram[j]='\0';
printf("\n A->%s",modifiedGram);
printf("\n X->%s\n",newGram);
}

Sakshi 43 21010001018
Gateway Institute of Engineering & Technology (GIET)

Output:

Sakshi 44 21010001018

You might also like