You are on page 1of 56

Shah Anant S 200705A01099

Batch:C1 2010-11

Practical - 1

Aim: Write a program to implement the lexical analyzer.


Software Required:Turbo C Compiler
Knowledge Required: Concepts of lexical analysis.
Theory/Logic:

• Lexical analysis is a function in which the stream of characters making up


the source program is read from left to right and grouped into tokens that are
sequences of characters having a collective meaning.
• In a compiler, lexical analysis is called linear analysis or Scanning.
• A lexical analyzer reads and converts the input into a stream of tokens to be
analyzed by the parser.
• The sentences of a language consist of string of tokens.
• A sequence of input characters that comprises a single token is called a
lexeme.
• A lexical Analyzer can insulate a parser from the lexeme representation of
tokens.
• A lexical analyzer generates tokens for any program that is given as an input
to it.
• It mainly generates 7 types of tokens: keywords, identifiers, constants,
literals, special symbols, operators, comments.

SOURCE LEXICAL TOKENS


CODE ANALYZER

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

Source Code:
#include<stdio.h>
#include<conio.h>
#define MAX 30
void main()
{
char str[MAX];
int state=0;
int i=0, j, startid=0, endid, startcon, endcon;
FILE *fp;
clrscr();
fp=fopen("lex.txt","r");
printf("Given Grammar:\n");
while(!feof(fp))
{
str[i]=getc(fp);
printf("%c",str[i]);
i++ ;
switch(state)
{
case 0: if(str[i]=='i') state=1; //if
else if(str[i]=='w') state=3; //while
else if(str[i]=='d') state=8; //do
else if(str[i]=='e') state=10; //else
else if(str[i]=='f') state=14; //for
else if(isalpha(str[i]) || str[i]=='_')
{
state=17;
startid=i;
} //identifiers

else if(str[i]=='<') state=19; //relational '<' or '<='


else if(str[i]=='>') state=21; //relational '>' or '>='
else if(str[i]=='=') state=23; //relational '==' or '='
else if(isdigit(str[i]))
{
state=25; startcon=i;
} //constant.

else if(str[i]=='(') state=26; //special characters '('


else if(str[i]==')') state=27;//special characters ')'
else if(str[i]==';') state=28; //special characters ';'
else if(str[i]=='+') state=29; //operator '+'
else if(str[i]=='-') state=30; //operator '-'

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

break;
//States for 'if'
case 1: if(str[i]=='f') state=2;
else { state=17; startid=i-1; i--; }
break;

case 2: if(str[i]=='(' || str[i]==NULL)


{
printf("\nif : Keyword\n");
state=0;
i--;
}
else { state=17; startid=i-2; i--; }
break;

//States for 'while'


case 3: if(str[i]=='h') state=4;
else { state=17; startid=i-1; i--; }
break;
case 4: if(str[i]=='i') state=5;
else { state=17; startid=i-2; i--; }
break;
case 5: if(str[i]=='l') state=6;
else { state=17; startid=i-3; i--; }
break;
case 6: if(str[i]=='e') state=7;
else { state=17; startid=i-4; i--; }
break;
case 7: if(str[i]=='(' || str[i]==NULL)
{
printf("\nwhile : Keyword\n");
state=0;
i--;
}
else { state=17; startid=i-5; i--; }
break;

//States for 'do'


case 8: if(str[i]=='o') state=9;
else { state=17; startid=i-1; i--; }
break;
case 9: if(str[i]=='{' || str[i]==' ' || str[i]==NULL ||
str[i]=='(')
{
printf("\ndo : Keyword\n");

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

state=0;
i--;
}
break;

//States for 'else'


case 10: if(str[i]=='l') state=11;
else { state=17; startid=i-1; i--; }
break;
case 11: if(str[i]=='s') state=12;
else { state=17; startid=i-2; i--; }
break;
case 12: if(str[i]=='e') state=13;
else { state=17; startid=i-3; i--; }
break;
case 13: if(str[i]=='{' || str[i]==NULL)
{
printf("\nelse : Keyword\n");
state=0;
i--;
}
else { state=17; startid=i-4; i--; }
break;

//States for 'for'


case 14: if(str[i]=='o') state=15;
else { state=17; startid=i-1; i--; }
break;
case 15: if(str[i]=='r') state=16;
else { state=17; startid=i-2; i--; }
break;
case 16: if(str[i]=='(' || str[i]==NULL)
{
printf("\nfor : Keyword\n");
state=0;
i--;
}
else { state=17; startid=i-3; i--; }
break;

//States for identifiers


case 17:if(isalnum(str[i]) || str[i]=='_')
{
state=18; i++;
}

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

elseif(str[i]==NULL||str[i]=='<'||str[i]=='>'||str[i]=='('||str[i]==')'
||str[i]==';'||str[i]=='='||str[i]=='+'||str[i]=='-') state=18;
i--;
break;
case 18:if(str[i]==NULL || str[i]=='<' || str[i]=='>' || str[i]=='(' ||
str[i]==')' || str[i]==';' || str[i]=='=' || str[i]=='+' ||str[i]=='-')
{
endid=i-1;
printf(" ");
for(j=startid; j<=endid; j++)
printf("%c", str[j]);
printf(" : Identifier\n");
state=0;
i--;
}
break;

//States for relational operator '<' & '<='


case 19: if(str[i]=='=') state=20;
else if(isalnum(str[i]) || str[i]=='_')
{
printf("\n< : Relational operator\n");
i--;
state=0;
}
break;
case 20: if(isalnum(str[i]) || str[i]=='_')
{
printf("\n<= : Relational operator\n");
i--;
state=0;
}
break;

//States for relational operator '>' & '>='


case 21: if(str[i]=='=') state=22;
else if(isalnum(str[i]) || str[i]=='_')
{
printf("\n > : Relational operator\n");
i--;
state=0;
}
break;
case 22: if(isalnum(str[i]) || str[i]=='_')
{

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

printf("\n>= : Relational operator\n");


i--;
state=0;
}
break;

//States for relational operator '==' & assignment operator '='


case 23: if(str[i]=='=') state=24;
else
{
printf("\n= : Assignment operator\n");
i--;
state=0;
}
break;
case 24: if(isalnum(str[i]))
{
printf("\n== : Relational operatorn\n");
state=0;
i--;
}
break;

//States for constants


case 25: if(isalpha(str[i]))
{
printf(" *** ERROR ***");
puts(str);
for(j=0; j<i; j++)
printf(" ");
printf("^");
printf("Error at position %d Alphabet cannot
follow digit", i);
state=99;
}
else if(str[i]=='(' || str[i]==')' || str[i]=='<' || str[i]=='>' ||
str[i]==NULL || str[i]==';' || str[i]=='=')
{
endcon=i-1;
printf(" ");
for(j=startcon; j<=endcon; j++)
printf("%c", str[j]);
printf(": Constant\n");
state=0;
i--;

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

}
break;
case 26: printf("\n( : Special character\n");

//State for special character '('


startid=i;
state=0;
i--;
break;
case 27: printf("\n) : Special character\n");

//State for special character ')'


state=0;
i--;
break;
case 28: printf("\n; : Special character\n");

//State for special character ';'


state=0;
i--;
break;
case 29: printf("\n+ : Operator\n");

//State for operator '+'


state=0;
i--;
break;
case 30: printf("\n+ : Operator\n");

//State for operator '-'


state=0;
i--;
break;
}
i++;
getch();
}
Output:-
The grammer is: for(x1=0; x1<=10; x1++);
for : Keyword
( : Special character
x1 : Identifier
= : Assignment operator
0 : Constant
; : Special character

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

x1 : Identifier
<= : Relational operator
10 : Constant
; : Special character
x1 : Identifier
+ : Operator
+ : Operator
) : Special character
; : Special character

Advantages:Simple Design: As Lexical Analyzer is separated from other analysis phases of


compilation, its design becomes simpler and easy to implement.
• Compiler efficiency and portability is improved.

Disadvantages:A large amount of time is spent in reading the source program and
partitioning it into tokens.
• So specialized buffering techniques for reading input characters and processing
tokens need to be applied to speed up compiler.
• One more disadvantage is that the lexical analyzer needs to read the whole
symbol table every time an identifier is encountered in the source code.

Application:Removal of White Spaces and comments.


• Recognizing Identifiers and Keywords, Recognizing Constants.

Conclusion:A Lexical Analyzer reads and converts the input into a stream of tokens to be
analyzed by the parser.

Question: What is Lexical Analyzer?


Answer:
Lexical Analysis is a function in which the stream of characters making up the source
program is read from left to right and grouped into tokens that are sequences of characters
having a collective meaning.

Question: Why Lexical Analyzer is separated from syntax analyzer?


Answer:
The lexical analyzer is separated from the syntax analyzer to improve the efficiency
of the compiler and the portability of the lexical analyzer as it can be used with any other
syntax analyzer.

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

Practical - 2

Aim: Write a program to left factoring of the given grammar.


S=iEiSeS|iEts|b
Software Required:Turbo C Compiler
Knowledge Required: Algorithm to remove the Left Factoring from the given grammar.
Theory/Logic:

• Left factoring is a grammar transformation that is useful for


producing a grammar suitable for predictive parsing.

• The basic idea is that when it is not clear which of the two
alternative productions to use to expand a non terminal A ,we may be able to
rewrite the A production to defer the decision until we have seen enough of
the input to make the right choice.

Algorithm:
Input: Grammar G with no cycles or Є productions.

Output: An equivalent grammar with no left recursion


.
Method:

• for each non terminal A find the longest prefix a common to two or
more of its alternatives.

• If a!=null replace all the A productions A->aB |aB |….Y where Y


represents all the alternatives that do not begin with a by
A->aA|Y
A->B|B|…..B

Here A is the new non terminal repeatedly apply this alternative until
no two alternative have common prefix

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

Source Code:
#include<stdio.h>
#include<conio.h>
#include<string.h>
FILE *fsrc;
void main()
{
int i=0,j=0,k=0,l=0,m=0,temp=0,a=0,len1,len2;
char grammar[100], nt[5][10][10], dummy[2]="\0", final[10]="\0",
final1[10]="\0";
clrscr();
fsrc=fopen("grammer.txt","r");
printf("Given Grammar:\n");
while(!feof(fsrc))
{
grammar[i]=getc(fsrc);
printf("%c",grammar[i]);
i++;
}
for(j=0;j<i;j++)
{
if(grammar[j]!='\n')
{
if(grammar[j]!='|')
{
if(l==0)
{
if(temp<=2)
{
dummy[temp]=grammar[j];
temp++;
}
else
{
nt[k][l][m]=grammar[j];
m++;
}
}
else
{
nt[k][l][m]=grammar[j];
m++;
}
}
else

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

{
nt[k][l][m]='\0'; l++;
temp=0;
m=0;
}
}
else
{
nt[k][l][m]='\0';
k++;
l=0;
m=0;
}
}
len1=strlen(nt[0][0]);
len2=strlen(nt[0][1]);
for(i=0;i<len1;i++)
{
if(len1<len2)
{
if(nt[0][0][i]!=nt[0][1][i])
goto aa;
else
a++;
}
else
{
if(nt[0][1][i]!=nt[0][0][i])
goto aa;
else
a++;
}
}
aa: if(len1<len2)
{
for(i=0;i<len2;i++)
final[i]=nt[0][1][i+a];
for(i=0;i<a;i++)
final1[i]=nt[0][0][i];
}
else
{ for(i=0;i<len2;i++)
final[i]=nt[0][0][i+a];
for(i=0;i<a;i++)
final1[i]=nt[0][1][i];

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

}
printf("\n\nAfter Left Factoring the Grammer is:");
printf("\n%c->%sS'|%s\nS'->%s|@",grammar[0],final1,nt[0][2],final);
printf("\n%c->%c",dummy[0],nt[1][0][0]);
getch();
}

Output:
Given grammer S=iEtSeS|iEtS|b
S1 : iEtSeS
S2 : iEtS
S3 : b
S=iEtSA|b
A=eS|#

Advantage:

• Left factoring is d grammar transformation that is useful for producing a grammar


suitable for predictive parsing.
• We can eliminate repetitive grammar productions.
• Parsing would become more efficient and we can distingue between two alternatives
in order to predict optimum alternative for the given non terminal

Disadvantage:

• There might be in the grammar that no left factoring is there so in that case this
method is not useful in parsing.
• The program requires more data structure in order to make left factoring possible
because the new non terminals have to be added, and if the grammar contains more
alternatives than there would be memory over flow problem.
Application: Syntax Analyzer in compilers.
Conclusion:

Left factoring requires to find out the longest prefix in each right side production
alternatives in order to make top down parsing without backtracking successful.
Question: Give another example of the left factoring to properly understand the method?
The grammar is:

S->iEts | itSes | a
E->b

Answer: By eliminating left factoring,


S->iEtSS’ | a
S’->eS | @
E-> b

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

Practical - 3

Aim: Write a program to remove the Left Recursion from a given grammar.
Software Requirements:Turbo C Compiler
Knowledge Requirement: Left Recursion Technique for grammars
Theory/Logic: Top-down parsing methods can not handle left-recursive grammars.
So a transformation that eliminates left-recursion is needed.
This program will eliminate left-recursion problem of given grammar.
Algorithm:
Input: Grammar G with no cycles or null-productions.
Output:An equivalent grammar with no left recursion.
Method:Apply the algorithm given below to G.
Note that the resulting non-left-recursive grammar may have null-productions.
1. Arrange the non terminals in some order A1, A2 ,…..An.
2. for i:=1 to n do begin
for j:=1 to i-1 do begin
Replace each production of the form Ai->Ajy
by the production Aj->s1y|s2y|….|sky.
Where Aj->s1|s2|…|sk are all the current Aj-productions;
End
Eliminate the immediate left recursion among the Ai-productions.
End

Source Code:
#include<stdio.h>
#include<conio.h>
#include<string.h>
void ELR(char nonterminal);
FILE *fsrc,*fpw;
int i,j,k,l,m,i1;
char nt[10][10][10],grammar[100];
void main()
{
clrscr();
fsrc=fopen("left.txt","r");
printf("Given Grammar\n");
i=k=l=m=0;
while(!feof(fsrc))
{
grammar[i]=getc(fsrc);
printf("%c",grammar[i]);
i++;
}
printf("\n\nAfter Elimination of Left Recursion (For Above Grammar):");
for(j=0;j<=i;j++)

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

{
if(grammar[j]!='\n')
{
if(grammar[j]!='|')
{ nt[k][l][m]=grammar[j];
m++;
}
else
{
nt[k][l][m]='\0';
l++;
m=0;
}
}
else
{
nt[k][l][m]='\0';
k++;
l=0;
m=0;
}
}
for(i1=0;i1<=k;i1++)
ELR(nt[i1][0][3]);
getch();
}
void ELR(char prod1)
{
char prod0,prod2,prod3,prod4;
prod0=nt[i1][0][0];
prod1=nt[i1][0][3];
prod2=nt[i1][1][0];
prod3=nt[i1][0][4];
prod4=nt[i1][0][5];
if(prod0==prod1)
{ printf("\n%c->%c%c'",prod0,prod2,prod0);
printf("\n%c'->%c%c%c'|@",prod0,prod3,prod4,prod0);
}
else
printf("\n%s|%s",nt[i1][0],nt[i1][1]);
}

Output: Given Grammar


E→E+T|T

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

T→T*F|F
F → (E) | id

E → TE’
E’ → +TE’ | €
T → FT’
T’ → *FT’ | €
F → (E) | id

Advantage:Top-down parsing methods cannot handle left-recursive grammars, so a


transformation that eliminates left recursion is needed.

Disadvantage:It is not easier process for each and every grammar to eliminate left recursion.
There might be in the grammar that no left recursion is there so in that case this method is not
useful in parsing.

Application: Syntax Analyzer in compilers.

Conclusion:Removing Left recursion requires to eliminate the same non terminal in left and
right hand side production alternatives in order to remove the infinite looping of the
productions as parsing process goes on.

Questions:

1. Give another example of the left recursion to properly understand the method?
The grammar is:

S->Aa | b
A-> Ac | Sd | @

Answer:
By eliminating left-recursion,
S-> Aa | b
A-> bdA’ | A’
A’->cA’| adA’ | #

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

Practical - 4

Aim: Write a C program for finding a FIRST set of all non-terminals of a given grammar.
E → TE’
E’ → +TE’ | €
T → FT’
T’ → *FT’ | €
F → (E) | id
Software Required:Turbo C Compiler
Knowledge Required: Concepts of First set of the grammar.
What is first and what is included in the first set of the non terminal.
Theory/Logic:

• If α is any string of grammar symbols, let FIRST(α) be the set of terminals that begin
the strings derived from α. If α =*> €, then € is also in FIRST(α).
• The construction of a predictive parser is aided by two functions associated with a
grammar G. These functions, FIRST and FOLLOW, allow us to fill in the entries of a
predictive parsing table for G, whenever possible. Sets of tokens yielded by the
FOLLOW function can also be used as synchronizing tokens during panic-mode error
recovery.
• To compute FIRST(X) for all grammar symbols X, the following rules are used until
no more terminals or € can be added to any FIRST set.
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 a non-terminal and X → Y1 Y2 . . . Yk is a production, then place α in


FIRST(X) if for some i, α is in FIRST(Y1), and € is in all of FIRST(Y1), . . .
FIRST(Yi-1); that is Y1 Y2 . . . Yi-1 => € . If € is in FIRST(Yj) for all j = 1,2, . . .
. ,k, then add € to FIRST(X).
• For example, everything in FIRST(Y1) is surly in FIRST(X). If Y1
does not derive €, then we add nothing more to FIRST(X), but if Y 1 => €, then we add
FIRST(Y2) and so on.
Source Code:

#include<stdio.h>
#include<conio.h>

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

#include<string.h>
void Find_First(char nt);

FILE *fsrc,*fpw;
int i=0,j,k=0,l=0,m=0,i1,i2;
char nt[10][10][10],grammar[100];
void main()
{
clrscr();
fsrc=fopen("grammar.txt","r");
if(fsrc==NULL)
{
printf("\nThe File Cant be opened");
}
else
{
printf("Given Grammar\n");
while(!feof(fsrc))
{
grammar[i]=getc(fsrc);
printf("%c",grammar[i]);
i++;
}
printf("\n\nFIRST SET (For Above Grammar):");
for(j=0;j<=i;j++)
{
if(grammar[j]!='\n')
{
if(grammar[j]!='|')
{
nt[k][l][m]=grammar[j];
m++;
}
else
{
nt[k][l][m]='\0';
l++;
m=0;
}
}
else
{
nt[k][l][m]='\0';
k++;
l=0;

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

m=0;
}
}
for(i2=0;i1,i2<=k;i1++,i2++)
{
printf("\nFIRST(%c)={",nt[i1][0][0]);
Find_First (nt[i1][0][3]);
printf("}");
}
}
getch();
}
void Find_First(char prod1)
{
char prod2;
prod1=nt[i1][0][3];
prod2=nt[i1][1][0];
if(prod1<65 || prod1>90)
{
printf("%c,",prod1);
if(prod2=='@' || prod2=='i')
{
printf("%c",prod2);
}
}
else
{
for(i=0;i<5;i++)
{
if(prod1==nt[i][0][0])
{
i1=i;
Find_First(prod1);
i1=i2;
}
}
if(prod2=='@')
{
printf("%c",prod2);
}
}
}
Output:
Given Grammar:
E → TE’

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

E’ → +TE’ | €
T → FT’
T’ → *FT’ | €
F → (E) | id

First Set:

FIRST(E)={ ( , id }
FIRST(E’)={ + , € }
FIRST(T)={ ( , id }
FIRST(T’)={ * , € }
FIRST(F)={ ( , id }

Advantages: Use to generate parse table.


To find FOLLOW of given grammar.

Disadvantage:It is some what tedious to understand the algorithm.

Conclusion:
• FIRST is the function, used in the construction of predictive parser.
• If α is any string of grammar symbols, let FIRST(α) be the set of
terminals that begin the strings derived from α.

Questions:

1) Find the FIRST of given grammar:

S=ABa
A=aaB
B=bB
B=^

Answer:
FIRST(S)=FIRST(A)={a}
FIRST(B)={b}{^}
FIRST(B)={b}{^}

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

Practical - 5

Aim: Write a C program for finding a FOLLOW set of all non-terminals of given grammar.
E → TE’
E’ → +TE’ | €
T → FT’
T’ → *FT’ | €
F → (E) | id

Software Required:Turbo C Compiler


Knowledge Required: Concepts of Follow set of the Grammar.
The whole knowledge of the First set of the Grammar.
Theory/Logic:

• Define FOLLOW(A), for non-terminal A, to be the set of terminals α that can


appear immediately to the right of A in some sentential form, that is, the set of
terminals α such that there exist a derivation from S=> αA| αB for some α and
B.

• To compute Follow(A) for all non-terminals A, the following rules are used
u8ntill nothing can be added to any Follow set:

1. Place $ in Follow(S), where S is the starting symbol and $ is the input


right end marker.

2. If there is a production A-> αBβ, then everything in First(β) except for


NULL is placed in Follow(B).

3. If there is a production A-> αB, or a production A-> αBβ where First(β)


contains NULL, then every thing in Follow(A) is in Follow(B)
Source Code:
#include<stdio.h>
#include<conio.h>
#include<process.h>
#include<string.h>
char non_terminals[10];
char statement[10][80],no_of_non_terminal;
char str_temp[40],pos;
int first_for_follow(char);
int lines,flag;
char *t;
void sep_pipes()
{
FILE *fp1,*fp2;
char str[79],statement[10][80];

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

int i,j,k,l,lines,pipe_sym;
char ch;
char temp_str[10];
clrscr();
fp1=fopen("source.txt","r");
if(!fp1)
{
printf("Grammar not Found");
getch();
exit(0);
}
printf("\t\t\t This is My Grammar\n");
lines=0;
while(fgets(str,79,fp1))
{
printf("%s",str);
strcpy(statement[lines],str);
lines++;
}
fp2=fopen("temp.txt","w");
for(i=0;i<lines;i++)
{
ch=statement[i][0];
pipe_sym=0;
for(j=0;j<strlen(statement[i]);j++)
{
if(statement[i][j]=='|')
{
pipe_sym++;
}
}
strtok(statement[i],":");
for(j=0;j<pipe_sym;j++)
{
strcpy(temp_str,strtok(NULL,"|"));
fprintf(fp2,"%c:%s\n",ch,temp_str);

}
strcpy(temp_str,strtok(NULL,"\n"));
fprintf(fp2,"%c:%s\n",ch,temp_str);
}
fclose(fp2);
fclose(fp1);
}
void main()

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

{
FILE *fp1,*fp2;
char *temp;
char str[79];
int i,j,k,l;
char temp_str[10];
char* find_first(char);
char* find_follow(char);
//int first_for_follow(char);
fp1=fopen("temp.txt","r");
lines=0;
sep_pipes();
getch();
while(fgets(str,79,fp1))
{
strcpy(statement[lines],str);
lines++;
}
getch();
printf("\n\t\t\t Finding FIRST\n\n\n");
for(i=0;i<lines;i++)
{
non_terminals[i]=statement[i][0];
}
for(i=0;i<lines;i++)
{
for(j=i+1;j<lines;j++)
{
if(non_terminals[j]==non_terminals[i])
{
non_terminals[i]='*';
}
}
}
no_of_non_terminal=0;
for(i=0;i<lines;i++)
{
if(non_terminals[i]!='*')
{
non_terminals[no_of_non_terminal]=non_terminals[i];
no_of_non_terminal++;
}
}
for(i=0;i<no_of_non_terminal;i++)
{

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

printf("FIRST( %c )",non_terminals[i]);
strcpy(str_temp,"");
pos=0;
find_first(non_terminals[i]);
printf(" ==> { %s }",str_temp);
printf("\n");
}
printf("\n\n\t\t\t Finding FOLLOW\n\n\n");
for(i=0;i<no_of_non_terminal;i++)
{
printf("FOLLOW( %c )",non_terminals[i]);
strcpy(str_temp,"");
pos=0;
find_follow(non_terminals[i]);
printf(" ==> { ");
for(j=0;j<strlen(str_temp);j++)
{
for(k=j+1;k<strlen(str_temp);k++)
{
if(str_temp[j]==str_temp[k])
{
str_temp[k]='œ';
}
}
}
for(j=0;j<strlen(str_temp);j++)
{
if(str_temp[j]!='œ')
{
printf("%c",str_temp[j]);
if(str_temp[j+1]!='œ'&&str_temp[j+1]!='\0')
{
printf(", ");
}
}
}
printf(" } ");
printf("\n");
}
fclose(fp1);
getch();
}
char* find_first(char ch)
{
int i,j;

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

for(i=0;i<lines;i++)
{
if(ch==statement[i][0])
{
for(j=0;j<lines;j++)
{
if(statement[i][2]==statement[j][0])
{
find_first(statement[j][0]);
return 0;
}
}
str_temp[pos]=statement[i][2];
pos++;
str_temp[pos]=',';
pos++;
str_temp[pos]='\0';
}
}
pos--;
str_temp[pos]='\0';
return str_temp;
}
char* find_follow(char ch)
{
int i,j,k;
int found,line_no,b_pos;
char *temp;
if(ch==statement[i][0] && i==0)
{
str_temp[pos]='$';
pos++;
str_temp[pos]='\0';

}
for(i=0;i<lines;i++)
{
for(j=2;j<strlen(statement[i]);j++)
{
if(ch==statement[i][j])
{
found=1;
b_pos=j;
line_no=i;
if(b_pos<strlen(statement[i])-2)

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

{
first_for_follow(statement[line_no][b_pos+1]);
}
else
{
temp = find_follow(statement[line_no][0]);
return str_temp;
}
}
}
}
return str_temp;
}
int first_for_follow(char ch)
{
int i,j;
int flag=0;
for(i=0;i<no_of_non_terminal;i++)
{
if(ch==non_terminals[i])
{
flag = 1;
break;
}
}
if (flag==1)
{
for(i=0;i<lines;i++)
{
if(ch==statement[i][0])
{
for(j=0;j<lines;j++)
{
if(statement[i][2]==statement[j][0])
{
first_for_follow(statement[j][0]);
return 0;
}
}
if(statement[i][2]=='^')
{
t=find_follow(statement[i][0]);
strcat(str_temp,t);
return 0;
}

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

if(statement[i][2]!='^')
{
str_temp[pos]=statement[i][2];
pos++;
str_temp[pos]='\0';
}
}
}
}
else
{
if(ch!='^')
{
str_temp[pos]=ch;
pos++;
str_temp[pos]='\0';
}
}
}

Output: Source.txt
E → TE’ E’ → +TE’ | €
T → FT’ T’ → *FT’ | €
F → (E) | id

FOLLOW(E) = { ) , $ }
FOLLOW(E’) = { ) , $ }
FOLLOW(T) = { + , ) , $ }
FOLLOW(T’) = { + , ) , $ }
FOLLOW(F) = { + , * , ) , $ }
Advantages: Allows us to fill the entries of a predictive parsing table for G, whenever
possible.
Application: In the construction of a predictive parser
Sets of tokens yielded by the FOLLOW function can also be used as
synchronizing tokens during panic-mode error recovery.

Conclusion:Allows us to fill in the entries of a predictive parsing table for G, whenever


possible and helps in construction of a predictive parser.

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

Question: Define FOLLOW set of Grammar G?


Answer:
Define FOLLOW(A), for non-terminal A, to be the set of terminals α that can
appear immediately to the right of A in some sentential form, that is, the set of
terminals α such that there exist a derivation from S=> αA| αB for some α and B.

Question: How is Panic Mode error recovery performed?


Answer:
• Panic mode error recovery is based on the simple idea of skipping symbols on the
input until a token is a selected set of synchronizing tokens appears.
• As a stating point during Panic mode recovery, we can place all symbols in
Follow(A) into the synchronization set of non-terminal A.
• If we skip the tokens until an element of Follow(A) is seen and pop A from the
stack, it is unlikely that the parsing will continue .

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

Practical - 6
Aim: Write a C program to parse a given string using Predictive parsing for given grammar.
type → simple | ↑id | array [ simple ] of type
simple → integer | char | num dotdot num
Software Required:Turbo C Compiler
Knowledge Required: Concepts of Predictive parsing
Theory/Logic:

• Recursive-decent parsing is a top-down method of syntax analysis in which we


execute set of recursive procedures to process the input. A procedure is associated
with each non-terminal of a grammar.
• Here, we consider a special form of recursive-decent parsing, called predictive
parsing, in which the look-ahead symbol unambiguously determines the procedure
selected for each non-terminal.
• The sequence of procedures called in processing the input implicitly defines a parse
tree for the input.
• A predictive parser is a program consisting of a procedure for every non-terminal.
Each procedure does two things.
1. It decides which production t use by looking at the look-ahead symbol. The
production with right side α is used if the look-ahead symbol is in FIRST(α). If
there is a conflict between two right sides for any look-ahead symbol, then we
cannot use this parsing method on this grammar. A production with € o the right
side is used if the look-ahead symbol is not in the FIRST set for any other right
hand side.
2. The procedure uses a production by mimicking the right side. A non-terminal
results in a call to the procedure for the non-terminal, and a token matching the
look-ahead symbol results in the next input token being read. If at some point the
token in the production does not match the look-ahead symbol, an error is
declared.

Source code:
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<process.h>

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

void simple(void);
void type(void);
void match(char *a);
FILE *fsrc,*fpw;
int i,j,k,l;
char token[20][20],source[100];
char *lookahead,*token1;
void main()
{
clrscr();
src=fopen("one.txt","r");
rintf("Given String:\n");
i=k=l=0;
while(!feof(fsrc))
{
source[i]=getc(fsrc);
printf("%c",source[i]);
i++;
}
for(j=0;j<=i;j++)
{
if(source[j]!=' ')
{
token[k][l]=source[j];
l++;
}
else
{
token[k][l]='\0';
k++;
l=0;
}
}
printf("\nString Parse Up To:\n");
lookahead=token[0];
type();
printf("\nSuccesfully parse");
getch();
}
void match(char *token1)
{
if(strcmp(lookahead,token1)==0)
{
i1++;
lookahead=token[i1];

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

}
else
{
printf("\nERROR: String is not in given Grammar\n");
getch();
exit(0);
}
}
void type()
{
if(strcmp(lookahead,"integer")==0 || strcmp(lookahead,"char")==0 ||
strcmp(lookahead,"num")==0)
{
simple();
}
else if(strcmp(lookahead,"^")==0)
{
printf("^ ");
match("^");
printf("id ");
match("id");
}
else if(strcmp(lookahead,"array")==0)
{
printf("array ");
match("array");
printf("[ ");
match("[");
simple();
printf("] ");
match("]");
printf("of ");
match("of");
type();
}
else
{
printf("\nERROR: String is not in given Grammar\n");
getch();
exit(0);
}
}
void simple()
{
if(strcmp(lookahead,"integer")==0)

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

{
printf("integer ");
match("integer");
}
else if(strcmp(lookahead,"char")==0)
{
printf("char ");
match("char");
}
else if(strcmp(lookahead,"num")==0)
{
printf("num ");
match("num");
printf("dotdot ");
match("dotdot");
printf("num ");
match("num");
}
else
{
printf("\nERROR: String is not in given Grammar\n");
getch();
exit(0);
}
}

Input: one.txt
array [ num dotdot num ] of integer

Output:
Given String:
array [ num dotdot num ] of integer
String Parse Up To:
array [ num dotdot num ] of integer
Successfully Parse

Application:-For parsing a string.

Advantage:-To construct a string translator predictive parser is used.


Syntax directed translator can be form extending a predictive grammer.
Questions:-
1). what is predictive parser?
Ans:- It is a program consisting of a procedure for every non terminal.

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

Practical - 7

Aim: Write a C program for finding some kind of error in program.


Software Required:Turbo C Compiler
Knowledge Required: Concepts of Syntax analysis.
Theory/Logic:
• The error detection and reporting is done by each phase of compiler. However, after
detecting an error, a phase must somehow deal with that error, so that compilation can
proceed, allowing further errors in the source program to be detected.
• The syntax and semantic analysis phases usually handle large fraction of the errors
detectable by the complier. The lexical phase can detect errors where characters
remaining in the input do not form any token of the language.
• We know that program can contain errors at many different levels. For e.g., errors can
be
o Lexical, such as misspelling and identifier, keyword, or operator.
o Syntactic, such as an arithmetic expression with unbalanced parentheses.
o Semantic, such as an operator applied to an incompatible operand.
o Logical, such as an infinitely recursive call.
• In this program I have tried to detect some kind of errors such as
o Semicolon (‘;’) missing in expression.
o Unbalance pair of parenthesis.
o The structure of if loop doesn’t match.
o The structure of for loop doesn’t match.

Source code:-
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main(int argc,char *argv[])
{
char str[80],prev,ch;
int flag=0,fflag=0,tflag=0,iflag=0,bflag=0,eflag=0,line=0;
FILE *p;
clrscr();
p=fopen(argv[1],"r");
if(p==NULL)
{
printf("can not open the file");
exit();
}
while(fscanf(p,"%s",str)!=EOF)
{
if(strcmp(str,"tushar()")==0)

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

tflag=1;
else if(strcmp(str,"{")==0)
{
if(tflag==1)
bflag=1;
else
{
flag=1;
printf("\nerror on line 1");
break;
}
}
else if(strcmp(str,"Tint")==0)
{
if(bflag==1)
iflag=1;
else
{
flag=1;
printf("\nerror on line 2");
break;
}
}
else if(strcmp(str,"Tfloat")==0)
{
if(iflag==1)
fflag=1;
else
{
flag=1;
printf("\nerror on line 3");
break;
}
}
else if(strcmp(str,"}")==0)
{
if(fflag==1)
eflag=1;
else
{
flag=1;
printf("\nerror on line 4");
break;
}
}

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

}
fclose(p);
p=fopen("text.txt","r");
if(p==NULL)
{
printf("can not open the file");
exit();
}
while((ch=getc(p))!=EOF)
{
if(ch=='\n')
{
line++;
if(prev==')'| prev=='{'| prev=='}')
continue;
if(prev!=';')
{
flag=1;
printf("\nerror on line %d ,semicolon missing",line);
}
}
prev=ch;
}
fclose(p);
if(flag==1)
printf("\n incorrect");
else
printf("\n correct");
getch();
}

Output:-
Input string: text.txt
tushar()
{
Tint a
Tfloat b=1.3;
a=b;
}

Output string:-
Error on line 3, semicolon missing
Incorrect

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

Practical - 8

Aim: Write a C program for finding some kind of error in program


Source code:-
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main(int argc,char *argv[])
{
char str[80],prev,ch;
int flag=0,fflag=0,tflag=0,iflag=0,bflag=0,eflag=0,line=0;
FILE *p;
clrscr();
p=fopen(argv[1],"r");
if(p==NULL)
{
printf("can not open the file");
exit();
}
while(fscanf(p,"%s",str)!=EOF)
{
if(strcmp(str,"tushar()")==0)
tflag=1;
else if(strcmp(str,"{")==0)
{
if(tflag==1)
bflag=1;
else
{
flag=1;
printf("\nerror on line 1");
break;
}
}
else if(strcmp(str,"Tint")==0)
{
if(bflag==1)
iflag=1;
else
{

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

flag=1;
printf("\nerror on line 2");
break;
}
}
else if(strcmp(str,"Tfloat")==0)
{
if(iflag==1)
fflag=1;
else
{
flag=1;
printf("\nerror on line 3");
break;
}
}
else if(strcmp(str,"}")==0)
{
if(fflag==1)
eflag=1;
else
{
flag=1;
printf("\nerror on line 4");
break;
}
}
}
fclose(p);
p=fopen("text.txt","r");
if(p==NULL)
{
printf("can not open the file");
exit();
}
while((ch=getc(p))!=EOF)
{
if(ch=='\n')
{
line++;
if(prev==')'| prev=='{'| prev=='}')
continue;
if(prev!=';')
{
flag=1;

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

printf("\nerror on line %d ,semicolon missing",line);


}
}
prev=ch;
}
fclose(p);
if(flag==1)
printf("\n incorrect");
else
printf("\n correct");
getch();
}

Output:-
Input string: text.txt
func()
{
Tint a
Tfloat b=1.3;
a=b;
}

Output string:-
Error on line 3, semicolon missing
Incorrect

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

Practical: – 9
Aim: Write a program for simple calculator having support of +, - , * , / and unary minus
operators with LEX and YACC.
Source code ( Simple Calculator ):
FILE : hoc.y
%
{
#define YYSTYPE double /* data type of yacc stack */
%
}
%token NUMBER
%left ‘+’ ‘-‘ /* left associative, same precedence */
%left ‘*’ ‘/‘ /* left associative, higher precedence */
%%
list: /* nothing */
| list ‘\n’
| list expr ‘\n’ { printf(“\t%.8g\n”,$2); }
expr: NUMBER { $$ = $1; }
| expr ‘+’ expr { $$ = $1 + $3; }
| expr ‘-’ expr { $$ = $1 - $3; }
| expr ‘*’ expr { $$ = $1 * $3; }
| expr ‘/’ expr { $$ = $1 / $3; }
| ‘(‘ expr ‘)’ { $$ = $2; }
;
%%
/* end of grammar */
#include <stdio.h>
#include <ctype.h>
char *progname; /* for error message */
int lineno = 1;

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

main(argc, argv) /* hoc1 */


char *agrv[];
{
progname = argv[0];
yyparse();
}
yylex() /* Continuing in hoc.y */
{
int c;
while ( ( c=getchar() ) = = ‘ ‘ || c = = ‘\t’ );
if ( c = = EOF )
return 0;
if ( c = = ‘.’ || isdigit ( c ) ) /* number */
{
ungetc(c, stdin);
scanf(“%lf”, &yylval);
return NUMBER;
}
if ( c = = ‘\n’ )
lineno++;
return c;
}
yyerror(s) /* called for yacc syntax error */
char *s;
{
warning( s, ( char * ) 0);
}
warning(s, t) /* print warning message */
char *s, *t;
{

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

fprintf(stderr, “%s: %s” , progname, s);


if ( t )
fprintf(stderr, “ %s”, t);
fprintf(stderr, “ near line %d \n”, lineno);
}
Output:
Compilation of a yacc program is a two-strp process:
$ yacc hoc.y
$ cc y.tab.c –o hoc1
$ hoc1
2/3
0.66666667
-3-4
hoc1: syntax error near line 1

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

Practical: – 10
Aim: Write a program for calculator with arbitrary variable names and built-in functions.
• This program adds several major new capabilities to program in practical-8 and
practical-9. The main new feature is access to built-in functions:
sin cos atan exp log log10 sqrt int abs
We have also added an exponentiation operator ‘^’, it has highest precedence, and is
right associative.
• The program that results from all these changes is big enough that it is best split into
separate files for easier editing and faster compilation. There are now five files
instead of one:
hoc.y Grammar, main, yylex
hoc.h Global data structure for inclusion
symbol.c Symbol table routines, lookup, install
init.c Built-in and constants, init
math.c Interfaces to math routines, sqrt, log, etc.
• Since the program is now lives on five files, not one, the makefile is more
complicated:
$ cat makefile
YFLAGS = -d # force creation of y.tab.h
OBJS = hoc.o init.o math.o symbol.o # abbreviation
hoc3: $ ( OBJS )
cc $ ( OBJS ) –lm -o hoc3
hoc.o: hoc.h
init.o symbol.o: hoc.h y.tab.h
pr:
@pr hoc.y hoc.h init.c math.c symbol.c makefile
clean:

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

rm –f $ ( OBJS ) y.tab. [ ch ]
$
$ make -n
$ make pr | lpr
$ make clean
Source code( Calculator with built-in functions ):
FILE : hoc.h
typedef struct Symbol
{ /* symbol table entry */
char *name;
short type; /* VAR, BLTIN, UNDEF */
union
{
double val; /* if VAR */
double ( *ptr ) ( ); /* if BLTIN*/
} u;
struct Symbol *next; /* to link to another */
} Symbol;
Symbol *install( ), *lookup( ) ;
FILE : symbol.c
#include “hoc.h”
#include “y.tab.h”
static Symbol *symlist = 0; /* symbol table: linked list */
Symbol *lookup( s ) /* find s in symbol table */
Char *s;
{
Symbol *sp;
for ( sp = symlist; sp ! = (Symbol * ) 0; sp = sp -> next )
if ( strcmp( sp -> name, s) = = 0 )
return sp;
return 0;

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

}
Symbol *install( s, t, d) /* install s in symbol list */
char *s;
int t;
double d;
{
Symbol *sp;
char *emalloc( ) ;
sp = ( Symbol * ) emalloc ( sizeof ( Symbol ) );
sp -> name = emalloc ( strlen ( s ) + 1 ) ; /* + 1 for ‘\0’ */
strcpy(sp -> name, s);
sp -> type = t; sp -> u.val = d;
sp -> next = symlist; /* put at front of list */
symlist = sp;
return sp;
}
char * emalloc ( n) /* check return from malloc */
unsigned n;
{
char *p, *malloc ( );
p = malloc ( n );
if ( p = = 0 )
execerror ( “out of memory“, ( char * ) 0 );
}
FILE : init.c
#include “hoc.h”
#include “y.tab.c”
#include <math.h>
extern double Log( ), Log10( ), Exp( ), Sqrt( ), integer( );
static struct

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

{
char *name;
double cval;
}
consts[] = { “PI”, 3.14159265358979323846,
“E”, 2.71828182845904523536,
“GAMMA”, 0.57721566490153286060, /* Euler */
“DEG”, 57.29577951308232087680, /* deg/radian */
“PHI”, 1.61803398874989484820, /* golden ratio */
0, 0};
static struct
{
char *name;
double (*func) ( );
} /* Built-ins */
built-ins[] = { “sin”, sin,
“cos”, cos,
“atan”, atan,
“log”, Log, /* checks argument */
“log 10, Log 10, /* checks argument */
“exp”, Exp, /* checks argument */
“sqrt”, Sqrt, /* checks argument */
“int”, integer,
“abs”, fabs,
0, 0};
init( ) /* install constants and built-ins in table */
{
int i;
Symbol *s;
for (i = 0; consts[i].name; i++)

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

install (consts[i].name, VAR, consts[i].cval);


for (i = 0; builins[i].name; i++)
{
s = install( built-ins[i].name, BLTIN, 0.0 );
s -> u.ptr = built-ins[i].func;
}
}
FILE : hoc.y
%
{
#include “hoc.h”
extern double Pow( );
%
}
%union
{
double val; /* actual value*/
Symbol *sym;
} /* symbol table pointer */
%token <val> NUMBER
%token <sym> VAR BLTIN UNDEF
%type <val> expr asgn
%right ‘=’
%left ‘+’ ‘-‘ /* left associative, same precedence */
%left ‘*’ ‘/‘ /* left associative, higher precedence */
%left UNARYMINUS
%right ‘^’ /* exponentiation */
%%
list: /* nothing */
| list ‘\n’
| list asgn ‘\n’

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

| list expr ‘\n’ { printf(“\t%.8g\n”,$2); }


| list error ‘\n’ { yyerrok; }
asgn: VAR ‘=’ { $$ = $1 -> u.val = $3; $1 -> type = VAR; }
;
expr: NUMBER
| VAR { if (S1 -> type = = UNDEF)
execerror(“undefined variable:, $1 -> name);
$$ = $1 -> u.val; }
| asgn
| BLTIN ‘(‘ expr ‘)’ { $$ = ( * ( $1 -> u.ptr ) ) ( $3 ); }
| expr ‘+’ expr { $$ = $1 + $3; }
| expr ‘-’ expr { $$ = $1 - $3; }
| expr ‘*’ expr { $$ = $1 * $3; }
expr ‘/’ expr {
if ( $3 = = 0.0 )
execerror (“division by zero” , ” ”);
$$ = $1 / $3; }
expr ‘^” expr { $$ = Pow( $1, $3); }
| ‘(‘ expr ‘)’ { $$ = $2; }
| ‘-‘ expr %prec UNARYMINUS { $$ = -$2; }
%% /* end of grammar */

#include <signal.h>
#include <setjmp.h>
jmp_buf begin;
main(argc, argv) /* hoc3 */
char *agrv[];
{
int fpecatch();
progname = argv[0];

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

init( );
setjmp(begin);
signal(SIGFPE, fpecatch);
yyparse();
}
execerror(s, t) /* recover from run-time error */
char *s, *t;
{
warning(s, t);
longjmp(begin, 0);
}
fpecatch() /* catch floating point exceptions*/
{
execerror(“floating point exception”, (char *) 0 ); }
yylex() /* Continuing in hoc.y */
{
int c;
while ( ( c=getchar() ) = = ‘ ‘ || c = = ‘\t’ );
if ( c = = EOF )
return 0;
if ( c = = ‘.’ || isdigit ( c ) ) /* number */
{
ungetc(c, stdin);
scanf(“%lf”, &yylval.val);
return NUMBER;
}
if(islower(c) )
{
yylavl.index = c – ‘a’; /* ASCII only */
}

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

if(isalpha(c) )
{
Symbol *s;
char sbuf(100), *p = sbuf;
do
{
*p++ = c;
}
while ( ( c = getchar( ) ) != EOF && isalnum(c) );
ungetc(c, stdin);
*p = ‘\0’;
if( ( s = lookup(sbuf) ) = = 0 )
s = install(sbuf, UNDEF, 0.0 );
yylval.sym = s;
return s-> type = = UNDEF ? VAR : s -> type;
}
if ( c = = ‘\n’ )
lineno++;
return c;
}
yyerror(s) /* called for yacc syntax error */
char *s;
{
warning( s, ( char * ) 0);
}
warning(s, t) /* print warning message */
cahr *s, *t;
{
fprintf(stderr, “%s: %s” , progname, s);
if ( t )

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

fprintf(stderr, “ %s”, t);


fprintf(stderr, “ near line %d \n”, lineno);
}

FILE: math.c
#include <math.h>
#include <errorno.h>
extern int errorno;
double errcheck( );
double Log( x )
double x;
{
return errcheck( log( x ), “log” );
}
double Log10( x )
double x;
{
return errcheck( log10( x ), “log10” );
}
double Exp( x )
double x;
{
return errcheck( exp( x ), “exp” );
}
double Sqrt( x )
double x;
{
return errcheck( sqrt( x ), “sqrt” );
}
double Pow( x , y )

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

double x , y;
{
return errcheck( pow( x , y ), “exponentiation” );
}
double integer( x )
double x;
{
return ( double ) ( long ) x;
}
double errcheck( d, s ) /* check result of library call */
double d;
char *s;
{
if ( erno = =EDOM )
{
errno = 0;
execerror( s, “argument out of domain”);
}
else if ( errno = = ERANGE )
{
errno = 0;
execerror( s, “result out of range” );
}
return d;
}

Output:
$ hoc3
1.5 ^ 2.3
2.5410306

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

exp(2.3 * log( 1:5 ) )


2.5410306
sin(PI / 2)
1
atan ( 1 )*DEG
45
x = 2 * 3.14159
6.28318 /* value printed for assignment to variable */
x=1 /* Assignment: no value is printed */
x /* Expression*/
6.28318 /* value is printed */

Application:-Used for Generating C code by just inputting the grammar to YACC.


Advantages:- For easily constructing the parser from input a grammar.
• Syntax Directed translator can be formed extending a predictive parser.
Questions:-
1).What is YACC?
- YACC is inbuilt utility of Linux operating system. This utility is used to generating the
C code for parsing from a given grammar as an input.
2).What is LEX?
- YACC is inbuilt utility of Linux operating system. This utility is used to generating the C
code of Lexical analyzer from given set of rules as an input.

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

Practical - 11

Aim: Write a program to perform Recursive Descendent Parsing for Grammar given below.
E -> T + E / T
T -> F * T / F
F -> ( E ) / i

Software Required: Turbo C or Borland C


Knowledge Required: Top-Down Parsing, Recursive Descent Parsing.
Theory/Logic:This is a Top-down Parsing Method without backtracking. It is used to check
the syntax of statements. If any syntax errors are present in the statement then error messages
will be generated as output.

This Program required four functions.


1. Get_Char()

This function returns next character from the input string and assign it to the global variable
‘next’. It also increment the ‘cursor’ pointer.

2. Expr()

This is recursive function.


It checks for E -> T + E / T grammar.

3. Term()

This is recursive function.


It checks for T -> F * T / F grammar.

4. Factor()

It is also recursive function.


It checks for F -> ( E ) / i grammar.

Source Code:-
#include<stdio.h>
#include<conio.h>
# define TRUE 1
# define FALSE 0
char next;
char *input;
int cursor;
char Get_Char();
int Expr();

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

int Term();
int Factor();
void main()
{
cursor=0;
clrscr();
printf("The Grammar is::\n\n");
printf("E -> T+E / T\nT -> F*T / F\nF -> (E) / i\n\n");
printf("Enter String For RDP(Please append '#' at end od input):: ");
gets(input);
next=Get_Char();
if(Expr())
{
if(next=='#')
printf("\nValid Statement");
else
printf("\nInvalid Statement");
}
else
printf("\nInvalid Statement");
getch();
}
int Expr()
{
if(!Term())
return FALSE;
if(next=='+')
{
next=Get_Char();
if(next=='#')
return FALSE;
if(!Expr())
return FALSE;
else
return TRUE;
}
else
return TRUE;
}
int Term()
{
if(!Factor())
return FALSE;
if(next=='*')
{

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

next=Get_Char();
if(next=='#')
return FALSE;
if(!Term())
return FALSE;
else
return TRUE;
}
else
return TRUE;
}
int Factor()
{
if(next=='#')
return FALSE;
if(next=='(')
{
next=Get_Char();
if(next=='#')
return FALSE;
if(!Expr())
return FALSE;
if(next!=')')
return FALSE;
else
{
next=Get_Char();
return TRUE;
}
}
if(next!='i')
return FALSE;
else
{
next=Get_Char();
return TRUE;
}
}

char Get_Char()
{
char ch;
ch=input[cursor];
cursor++;
return ch;

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

OUTPUT:: 1:

The Grammar is::

E -> T+E / T
T -> F*T / F
F -> (E) / i

Enter String For RDP(Please append '#' at end of input): i*(i+i)#

Valid Statement

OUTPUT 2:

The Grammar is:

E -> T+E / T
T -> F*T / F
F -> (E) / i

Enter String For RDP(Please append '#' at end of input): i+i*

Invalid Statement

Advantage: Early detection of syntax errors saves the compilation time. These are will not
propagate in the next phases.

Disadvantage: It recursively calls functions and thus requires implicit use of stack data
structure. There may be a chance of stack overflow.

Application: Syntax Analyzer in compilers.

Conclusion: Recursive–Descent parser requires one function for each Non-Terminal given in
the grammar.

Questions:

1). what are the other Top-down parsing Techniques?


Ans:-
- Recursive - Descent parsing.
- Predictive Parsers.

Hasmukh Goswami College Of Engg.


Vahelal
Shah Anant S 200705A01099
Batch:C1 2010-11

- Nonrecursive Predictive Parsing.

Hasmukh Goswami College Of Engg.


Vahelal