CD Lab Manual
CD Lab Manual
As it is known that Lexical Analysis is the first phase of compiler also known as
scanner. It converts the input program into a sequence of Tokens.
A C program consists of various tokens and a token is either a keyword, an identifier, a
constant, a string literal, or a symbol.
For Example:
1) Keywords: Examples- for, while, if etc.
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
return (true);
return (false);
ch == '=')
return (true);
return (false);
}
// Returns 'true' if the string is a VALID IDENTIFIER.
return (false);
return (true);
!strcmp(str, "break") ||
return (true);
return (false);
if (len == 0)
return (false);
for (i = 0; i < len; i++) {
return (false);
return (true);
if (len == 0)
return (false);
return (false);
if (str[i] == '.')
hasDecimal = true;
return (hasDecimal);
int i;
return (subStr);
str)
0; int len =
strlen(str);
if (isDelimiter(str[right]) == false)
right++;
if (isOperator(str[right]) == true)
right++;
left = right;
} else if (isDelimiter(str[right]) == true && left != right
if (isKeyword(subStr) == true)
left = right;
}
}
return;
// DRIVER FUNCTION
int main()
return (0);
Output:
'int' IS A KEYWORD
'a' IS A VALID IDENTIFIER
'=' IS AN OPERATOR
'b' IS A VALID IDENTIFIER
'+' IS AN OPERATOR
'1c' IS NOT A VALID IDENTIFIER
2. Write a LEX program to implement a Lexical Analyzer using a Lex Tool.
AIM: To write a program for implementing a Lexical analyser using LEX tool in Linux
platform.
ALGORITHM:
Step1: Lex program contains three sections: definitions, rules, and user subroutines.
Each section must be separated from the others by a line containing only the delimiter,
%%. The format is as follows: definitions %% rules %% user_subroutines
Step2: In definition section, the variables make up the left column, and their definitions
make up the right column. Any C statements should be enclosed in %{..}%. Identifier is
defined such that the first letter of an identifier is alphabet and remaining letters are
alphanumeric.
Step3: In rules section, the left column contains the pattern to be recognized in an input
file to yylex(). The right column contains the C program fragment executed when that
pattern is recognized. The various patterns are keywords, operators, new line character,
number, string, identifier, beginning and end of block, comment statements, preprocessor
directive statements etc.
Step4: Each pattern may have a corresponding action, that is, a fragment of C source
code to execute when the pattern is matched.
Step5: When yylex() matches a string in the input stream, it copies the matched text to
an external character array, yytext, before it executes any actions in the rules section.
Step6: In user subroutine section, main routine calls yylex(). yywrap() is used to get
more input.
Step7: The lex command uses the rules and actions contained in file to generate a
program, lex.yy.c, which can be compiled with the cc command. That program can
then receive input, break the input into the logical pieces defined by the rules in file,
and run program fragments contained in the actions in file.
PROGRAM CODE:
//Implementation of Lexical Analyzer using Lex tool
%{
int COMMENT=0;
%}
identifier [a-zA-Z][a-zA-Z0-9]*
%%
#.* {printf("\n%s is a preprocessor directive",yytext);}
int |
float |
char |
double |
while |
for |
struct |
typedef |
do |
if |
break |
continue |
void |
switch |
return |
else |
goto {
printf("\n\t%s is a keyword",yytext);}
"/*" {COMMENT=1;}{
printf("\n\t %s is a COMMENT",yytext);}
{identifier}\( {if(!COMMENT)
printf("\nFUNCTION \n\t%s",yytext);}
\{ {if(!COMMENT)
printf("\n BLOCK BEGINS");}
\} {if(!COMMENT)
printf("BLOCK ENDS ");}
{identifier}(\[[0-9]*\])? {if(!COMMENT)
printf("\n %s IDENTIFIER",yytext);}
\".*\" {if(!COMMENT)
printf("\n\t %s is a
STRING",yytext);} [0-9]+ {if(!
COMMENT)
printf("\n %s is a NUMBER ",yytext);}
\)(\:)? {if(!COMMENT)
printf("\n\t");ECHO;
printf("\n");}
\( ECHO;
= {if(!COMMENT)
printf("\n\t %s is an ASSIGNMENT OPERATOR",yytext);}
\<= |
\>= |
\< |
== |
\> {if(!COMMENT) printf("\n\t%s is a RELATIONAL OPERATOR",yytext);}
%%
int main(int argc, char **argv)
{
FILE *file;
file=fopen("var.c","r"); if(!
file)
{
printf("could not open the file");
exit(0);
}
yyin=file;
yylex();
printf("\n");
return(0);
}
int yywrap()
{
return(1);
}
INPUT:
//var.c
#include<stdio.h>
#include<conio.h>
void main()
{
int a,b,c;
a=1;
b=2;
c=a+b; printf("Sum:%d",c);
}
OUTPUT:
LOGIC : Read the given input. If the given input matches with any operator
symbol. Then display in terms of words of the particular symbol. Else print not a
operator.
PROGRAM:
#include
#include
void
main()
{
char s[5];
clrscr();
printf("\n Enter any
operator:"); gets(s);
switch(s[0])
{
case'>': if(s[1]=='=')
printf("\n Greater than or
printf("\n Greater than");
break;
case'<': if(s[1]=='=')
printf("\n Less than or equal");
else
printf("\nLess than");
break;
case'=': if(s[1]=='=')
printf("\nEqual to");
else printf("\
nAssignment"); break;
case'!': if(s[1]=='=')
printf("\nNot Equal");
else
printf("\n Bit Not");
break;
case'&': if(s[1]=='&')
printf("\nLogical AND");
else
printf("\n Bitwise AND");
break;
case'|': if(s[1]=='|')
printf("\nLogical OR");
else
printf("\nBitwise OR");
break;
case'+': printf("\n Addition");
break;
case'-': printf("\nSubstraction");
break;
case'*': printf("\nMultiplication");
break;
case'/': printf("\nDivision");
break;
case'%': printf("Modulus");
break;
default: printf("\n Not a operator");
}
getch();
}
Input
Enter any operator: *
Output
Multiplicati
First include the package and Necessary variable. I use the following function int
parse::scannt(char a), void parse::input(),int parse::scant(char b), void
parse::process(),void parse::input(), To perform the operation Processing.
Compiler Design Source code Programming
#include<iostream.h>
#include<conio.h>
#include<string.h>
class parse
{
int nt,t,m[20][20],i,s,n,p1,q,k,j;
char p[30][30],n1[20],t1[20],ch,b,c,f[30][30],fl[30][30];
public:
int scant(char);
int scannt(char);
void process();
void input();
};
int parse::scannt(char a)
{
int c=-1,i;
for(i=0;i<nt;i++)
{
if(n1[i]==a)
{
return i;
}
}
return c;
}
int parse::scant(char b)
{
int c1=-1,j;
for(j=0;j<t;j++)
{
if(t1[j]==b)
{
return j;
}
}
return c1;
}
void parse::input()
{
cout<<"Enter the number of productions:";
cin>>n;
cout<<"Enter the productions one by one"<<endl;
for(i=0;i<n;i++)
cin>>p[i];
nt=0;
t=0;
}
void parse::process()
{
for(i=0;i<n;i++)
{
if(scannt(p[i][0])==-1)
n1[nt++]=p[i][0];
}
for(i=0;i<n;i++)
{
for(j=3;j<strlen(p[i]);j++)
{
if(p[i][j]!='e')
{
if(scannt(p[i][j])==-1)
{
if((scant(p[i][j]))==-1)
t1[t++]=p[i][j];
}
}
}
} t1[t+
+]='$';
for(i=0;i<nt;i++)
{
for(j=0;j<t;j++)
m[i][j]=-1;
}
for(i=0;i<nt;i++)
{
cout<<"Enter first["<<n1[i]<<"]:";
cin>>f[i];
}
for(i=0;i<nt;i++)
{
cout<<"Enter follow["<<n1[i]<<"]:";
cin>>fl[i];
}
for(i=0;i<n;i++)
{
p1=scannt(p[i][0]);
if((q=scant(p[i][3]))!=-1)
m[p1][q]=i;
if((q=scannt(p[i][3]))!=-1)
{
for(j=0;j<strlen(f[q]);j++) m[p1][scant(f[q]
[j])]=i;
}
if(p[i][3]=='e')
{
for(j=0;j<strlen(fl[p1]);j++) m[p1][scant(fl[p1]
[j])]=i;
}
}
for(i=0;i<t;i++)
cout<<"\t"<<t1[i];
cout<<endl;
for(j=0;j<nt;j++)
{
cout<<n1[j];
for(i=0;i<t;i++)
{
cout<<"\t"<<"
"; if(m[j][i]!=-1)
cout<<p[m[j][i]];
}
cout<<endl;
}
}
void main()
{
clrscr();
parse p;
p.input();
p.process();
getch();
}
Top Down Parsing in Complier Design output
Enter the number of
productions:8 Enter the
productions one by one E->TA
A->+TA
A->e
T->FB
B->e
B->*FB
F->(E)
F->i
Enter first[E]: (i
Enter first[A]: +e
Enter first[T]: (i
Enter first[B]: *e
Enter first[F]: (i
Enter follow[E]: $)
Enter follow[A]: $)
Enter follow[T]: +)$
Enter follow[B]: +)$
Enter follow[F]: +*)
$
+()i*$
E E->TA E->TA
A A->+TA A->e A->e
T T->FB T->FB
B B->e B->e B->*FB B->e
F F->(E) F->i
5. Write a C program to implement a Recursive Descent Parser.
E -> E+T | T
T -> T*F | F
F -> (E) | id
RD parser will verify whether the syntax of the input stream is correct by checking each
character from left to right. A basic operation necessary is reading characters from the
input stream and matching then with terminals from the grammar that describes the
syntax of the input.
The given grammar can accept all arithmetic equations involving +, * and ().
eg:
a+(a*a) a+a*a , (a), a , a+a+a*a+a.....etc are accepted
a++a, a***a, +a, a*, ((a......etc are rejected.
Solution:
First we have to avoid left recursion
E -> TE'
E' -> +TE' |
ε T -> FT'
T' -> *FT' |
ε F -> (E) |
id
After eliminating Left recursion, we have to simply move from one character to next by
checking whether it follow the grammar. In this program, ε is indicated as $.
recursive.c
#include<stdio.h>
#include<string.h>
#include<ctype.h>
char input[10];
int i,error;
void E();
void T();
void Eprime();
void Tprime();
void F();
main()
{
i=0;
error=0;
printf("Enter an arithmetic expression : "); // Eg: a+a*a
gets(input);
E();
if(strlen(input)==i&&error==
0) printf("\
else printf("\nRejected..!!!\n");
}
void E()
{
T();
Eprime
}
void Eprime()
{
if(input[i]=='+')
{
i++;
T();
Eprime();
}
}
void T()
{
F();
Tprime
}
void Tprime()
{
if(input[i]=='*')
{
i++;
F();
Tprime();
}
}
void F()
{
if(isalnum(input[i]))i++;
else if(input[i]=='(')
{
i++;
E();
if(input[i]==')')
i++;
else
Output:error=1;
a+(a*a) a+a*a , (a), a , a+a+a*a+a.... etc are accepted
}
++a, a***a, +a, a*, ((a . . . etc are rejected.
6. Writeelse
a C program to Caluclate FIRST and FOLLOW of the following Grammer.
error=1;
#include<stdio.h>
#include<ctype.h>
#include<string.h>
int count, n = 0;
// Stores the final result
char calc_first[10][100];
char calc_follow[10][100];
int m = 0;
int k;
char ck;
int e;
int jm = 0;
int km = 0;
int i, choice;
char c, ch;
count = 8;
strcpy(production[1], "R=+TR");
strcpy(production[2], "R=#");
strcpy(production[3], "T=FY");
strcpy(production[4], "Y=*FY");
strcpy(production[5], "Y=#");
strcpy(production[6], "F=(E)");
strcpy(production[7], "F=i");
int kay;
char done[count];
{ calc_first[k][kay] = '!';
c = production[k][0];
point2 = 0;
xxx = 0;
+)
if(c == done[kay])
xxx = 1;
if (xxx == 1)
continue;
// Function call
findfirst(c, 0, 0);
ptr += 1;
done[ptr] = c;
calc_first[point1][point2++] = c;
chk = 1;
break;
if(chk == 0)
calc_first[point1][point2++] = first[i];
printf("}\n");
jm = n;
point1++;
printf("\n");
printf(" \n\n");
char donee[count];
ptr = -1;
point1 = 0;
int land = 0;
ck = production[e][0];
point2 = 0;
xxx = 0;
// Checking if Follow of ck
+)
if(ck == donee[kay])
xxx = 1;
if (xxx == 1)
continue;
land += 1;
// Function call
follow(ck);
ptr += 1;
// Adding ck to the calculated list
donee[ptr] = ck;
calc_follow[point1][point2++] = ck;
if (f[i] == calc_follow[point1][lark])
chk = 1;
break;
if(chk == 0)
calc_follow[point1][point2++] = f[i];
printf(" }\n\n");
km = m;
point1++;
}
void follow(char c)
int i, j;
[0] == c) {
f[m++] = '$';
if(production[i][j] == c)
if(production[i][j+1] != '\0')
followfirst(production[i][j+1], i,
(j+2));
}
if(production[i][j+1]=='\0' && c!=production[i][0])
production follow(production[i]
[0]);
int j;
// encounter a
Terminal if(!
(isupper(c))) {
first[n++] = c;
if(production[j][0] == c)
if(production[j][2] == '#')
{
if(production[q1][q2] == '\0')
first[n++] = '#';
else
first[n++] = '#';
}
else if(!isupper(production[j][2]))
first[n++] = production[j][2];
else
// at the beginning
findfirst(production[j][2], j, 3);
}
}
int k;
// a Terminal
if(!(isupper(c)))
f[m++] = c;
else
int i = 0, j = 1;
if(calc_first[i][0] == c)
break;
while(calc_first[i][j] != '!')
{
if(calc_first[i][j] != '#')
f[m++] = calc_first[i][j];
else
if(production[c1][c2] == '\0')
// end of a production
follow(production[c1][0]);
else
} j+
+;
}
7. Write a C program for eliminating the left recusrion and left Factoring of a
given grammer.
#include<stdio.h
>
#include<string.h>
void main() {
char
input[100],l[50],r[50],temp[10],tempprod[20],productions[25
][50];
int i=0,j=0,flag=0,consumed=0;
printf("Enter the productions: ");
scanf("%1s->%s",l,r);
printf("%s",r);
while(sscanf(r+consumed,"%[^|]s",temp) == 1 &&
consumed <= strlen(r)) {
if(temp[0] == l[0]) {
flag = 1;
sprintf(productions[i++],"%s->%s%s'\0",l,temp+1,l);
}
else
sprintf(productions[i++],"%s'->%s%s'\0",l,temp,l);
consumed += strlen(temp)+1;
}
if(flag == 1) {
sprintf(productions[i++],"%s->ε\0",l);
printf("The productions after eliminating Left Recursion
are:\n");
for(j=0;j<i;j++)
printf("%s\n",productions[j]);
}
else
printf("The Given Grammar has no Left Recursion");
}
OUTPUT:
Left Factoring IN C:
#include<iostream>
#include<string>
int main()
{ string ip,op1,op2,temp;
char c;
int n,j,l;
cin>>c;
ip.push_back(c);
op1 += ip + "\'->";
op2 += ip + "\'\'->";;
ip += "->";
cin>>n;
for(int i=0;i<n;i++)
cin>>temp;
sizes[i] = temp.size();
ip+=temp;
if(i!=n-1)
ip += "|";
char x = ip[3];
for(int i=0,k=3;i<n;i++)
if(x == ip[k])
if(ip[k+1] == '|')
op1 += "#";
ip.insert(k+1,1,ip[0]);
ip.insert(k+2,1,'\'');
k+=4;
else
ip.erase(k-1,sizes[i]+1);
else
{
while(ip[k++]!='|');
char y = op1[6];
for(int i=0,k=6;i<n-1;i++)
if(y == op1[k])
if(op1[k+1] == '|')
op2 += "#";
op1.insert(k+1,1,op1[0]);
op1.insert(k+2,2,'\'');
k+=5;
else
temp.clear();
for(int s=k+1;s<op1.length();s++)
temp.push_back(op1[s]);
op1.erase(k-1,temp.length()+2);
} }}
op2.erase(op2.size()-1);
cout<<op1<<endl;
cout<<op2<<endl;
return 0;
OUTPUT:
4 Enter Production 1 : i
Enter Production 2 : iL
Enter Production 4 :
iL+L
L->iL'|(L)
L'->#|LL''
L''->#|+L
8. Write a C program to check the validity of input string using Predictive Parser
"double",KEYWORD,"char",KEYWORD,"struct",KEYWORD,"return",KEYWORD,0,0
};
void Error_Message(char *m)
{
fprintf(stderr,"line %d, %s \n",lineno,m);
exit(1);
}
int look_up(char s[ ])
{
int k;
for(k=lastentry; k>0; k--)
if(strcmp(symtable[k].lexptr,s)==0)
return k;
return 0;
}
int insert(char s[ ],int tok)
{
int len;
len=strlen(s);
if(lastentry+1>=MAX)
Error_Message("Symbpl table is full");
if(lastchar+len+1>=MAX)
Error_Message("Lexemes array is full");
lastentry=lastentry+1;
symtable[lastentry].token=tok;
symtable[lastentry].lexptr=&lexemes[lastchar+1];
lastchar=lastchar+len+1;
strcpy(symtable[lastentry].lexptr,s);
return lastentry;
}
/*void Initialize()
{
struct entry *ptr;
for(ptr=keywords;ptr->token;ptr+1)
insert(ptr->lexptr,ptr->token);
}*/
int lexer()
{
int t;
int val,i=0;
while(1)
{
t=getchar();
if(t==' '||t=='\t');
else if(t=='\n')
lineno=lineno+1;
else if(isdigit(t))
{
ungetc(t,stdin);
scanf("%d",&tokenval);
return NUM;
}
else if(isalpha(t))
{
while(isalnum(t))
{
buffer[i]=t;
t=getchar();
i=i+1;
if(i>=SIZE)
Error_Message("Compiler error");
}
buffer[i]=EOS;
if(t!=EOF)
ungetc(t,stdin);
val=look_up(buffer);
if(val==0)
val=insert(buffer,ID);
tokenval=val;
return symtable[val].token;
}
else if(t==EOF)
return DONE;
else
{
tokenval=NONE;
return t;
}
}
}
void Match(int t)
{
if(lookahead==t)
lookahead=lexer();
else
Error_Message("Syntax error");
}
void display(int t,int tval)
{
if(t=='+'||t=='-'||t=='*'||t=='/') printf("\
nArithmetic Operator: %c",t);
else if(t==NUM)
printf("\n Number: %d",tval);
else if(t==ID)
printf("\n Identifier: %s",symtable[tval].lexptr);
else
printf("\n Token %d tokenval %d",t,tokenval);
}
void F()
{
//void E();
switch(lookahead)
{
case '(' :
Match('(');
E();
Match(')');
break;
case NUM :
display(NUM,tokenval);
Match(NUM);
break;
case ID :
display(ID,tokenval);
Match(ID);
break;
default :
Error_Message("Syntax error");
}
}
void T()
{
int t;
F();
while(1)
{
switch(lookahead)
{
case '*' :
t=lookahead;
Match(lookahead);
F();
display(t,NONE);
continue;
case '/' :
t=lookahead;
Match(lookahead);
display(t,NONE);
continue;
default :
return;
}
}
}
void E()
{
int t;
T();
while(1)
{
switch(lookahead)
{
case '+' :
t=lookahead;
Match(lookahead);
T();
display(t,NONE);
continue;
case '-' :
t=lookahead;
Match(lookahead);
T();
display(t,NONE);
continue;
default :
return;
}
}
}
void parser()
{
lookahead=lexer(); while(lookahead!=DONE)
{
E();
Match(';');
}
}
int main()
{
char ans[10];
printf("\n Program for recursive descent parsing "); printf("\n Enter the expression ");
printf("And place ; at the end\n"); printf("Press Ctrl-Z to terminate\n"); parser();
return 0;
}
SAMPLE OUTPUT:
Identifier: a
Identifier: b
Arithmetic Operator:
* Identifier: c
Arithmetic Operator:
+ 5*7;
Number: 5
Number: 7
Arithmetic Operator: *
*2;
line 5, Syntax error
9. Write a C program for Implementation of LR parsing algorithm to accept a
given input string.
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<stdbool.h>
void isproduct(char,char);
int ister(char);
int isnter(char);
int isstate(char);
void error();
void isreduce(char,char);
struct action
char row[6][5];
};
{"sf","emp","emp","se","emp","emp"},
{"emp","sg","emp","emp","emp","acc"},
{"emp","rc","sh","emp","rc","rc"},
{"emp","re","re","emp","re","re"},
{"sf","emp","emp","se","emp","emp"},
{"emp","rg","rg","emp","rg","rg"},
{"sf","emp","emp","se","emp","emp"},
{"sf","emp","emp","se","emp","emp"},
{"emp","sg","emp","emp","sl","emp"},
{"emp","rb","sh","emp","rb","rb"},
{"emp","rb","rd","emp","rd","rd"},
{"emp","rf","rf","emp","rf","rf"}
};
struct gotol
char r[3][4];
};
{"b","c","d"},
{"emp","emp","emp"},
{"emp","emp","emp"},
{"emp","emp","emp"},
{"i","c","d"},
{"emp","emp","emp"},
{"emp","j","d"},
{"emp","emp","k"},
{"emp","emp","emp"},
{"emp","emp","emp"},
};
char ter[6]={'i','+','*',')','(','$'};
char nter[3]={'E','T','F'};
char states[12]={'a','b','c','d','e','f','g','h','m','j','k','l'};
char stack[100];
int top=-1;
char temp[10];
struct grammar
{
char left;
char right[5];
};
{'E',"e+T"},
{'E',"T"},
{'T',"T*F"},
{'T',"F"},
{'F',"(E)"},
{'F',"i"},
};
void main()
char inp[80],x,p,dl[80],y,bl='a';
int i=0,j,k,l,n,m,c,len;
clrscr();
scanf("%s",inp);
len=strlen(inp);
inp[len]='$';
inp[len+1]='\0';
push(stack,&top,bl);
printt(stack,&top,inp,i);
do
x=inp[i];
p=stacktop(stack);
isproduct(x,p);
if(strcmp(temp,"emp")==0)
error();
if(strcmp(temp,"acc")==0)
break;
else
if(temp[0]=='s')
push(stack,&top,inp[i]);
push(stack,&top,temp[1]);
i++;
}
else
if(temp[0]=='r')
j=isstate(temp[1]);
strcpy(temp,rl[j-2].right);
dl[0]=rl[j-2].left;
dl[1]='\0';
n=strlen(temp);
for(k=0;k<2*n;k++)
pop(stack,&top);
for(m=0;dl[m]!='\0';m++)
push(stack,&top,dl[m]);
l=top;
y=stack[l-1];
isreduce(y,dl[0]);
for(m=0;temp[m]!='\0';m++)
push(stack,&top,temp[m]);
printt(stack,&top,inp,i);
}while(inp[i]!='\0');
if(strcmp(temp,"acc")==0)
else
getch();
}
void push(char *s,int *sp,char item)
if(*sp==100)
else
*sp=*sp+1;
s[*sp]=item;
}
char i;
i=s[top];
return i;
int k,l;
k=ister(x);
l=isstate(p);
strcpy(temp,A[l-1].row[k-1]);
int ister(char x)
int i;
for(i=0;i<6;i++)
if(x==ter[i])
return i+1;
return 0;
}
int isnter(char x)
int i;
for(i=0;i<3;i++)
if(x==nter[i])
return i+1;
return 0;
int isstate(char p)
int i;
for(i=0;i<12;i++)
if(p==states[i])
return i+1;
return 0;
void error()
exit(0);
{
int k,l;
k=isstate(x);
l=isnter(p);
strcpy(temp,G[k-1].r[l-1]);
}
char pop(char *s,int *sp)
char item;
if(*sp==-1)
else
item=s[*sp];
*sp=*sp-1;
return item;
int r;
printf("\n");
for(r=0;r<=*p;r++)
rep(t,r);
printf("\t\t\t");
for(r=i;inp[r]!='\0';r++)
printf("%c",inp[r]);
}
void rep(char t[],int r)
char c;
c=t[r];
switch(c)
break;
break;
break;
break;
break;
break;
Output:
10. Write a C program for Implementing of a shift reduce parser using stack
Data Structure to accept a given input string of a given grammer.
#include <stdio.h>
#include <string.h>
// Stack implementation
struct stack {
int top;
char items[MAX];
};
// Parsing function
void parse(char input[], char grammar[][10], int n)
{ struct stack s;
s.top = -1;
int i, j, k;
char c;
push(&s, '$'); // Pushing the end marker on the stack
push(&s, grammar[0][0]); // Pushing the start symbol on the stack
i = 0;
while (input[i] != '\0')
{ c = input[i];
if (c == s.items[s.top]) { // If top of stack is same as input symbol, pop from stack and
move to next input symbol
pop(&s);
i++;
} else if (s.items[s.top] >= 'A' && s.items[s.top] <= 'Z') { // If top of stack is a non-terminal
for (j = 0; j < n; j++) {
if (grammar[j][0] == s.items[s.top]) { // Find the production rule for the non-terminal
for (k = strlen(grammar[j])-1; k >= 3; k--) { // Push the production rule in reverse
order onto the stack
push(&s, grammar[j][k]);
}
}
}
if (s.items[s.top] >= 'A' && s.items[s.top] <= 'Z') { // If top of stack is still a non-
terminal, it cannot be reduced further
printf("Invalid input string\n");
return;
}
} else {
printf("Invalid input string\n");
return;
}
}
// Driver function
int main() {
char input[100];
printf("Enter the input string: ");
scanf("%s", input);
return 0;
}
11. Simulate the calculator using LEX and Yacc tool.
PROGRAM CODE:
LEX PART:
%
{
#include<stdio.h>
#include "y.tab.h"
%
}
%
%
[0 - 9] + {
yylval = atoi(yytext);
return NUMBER;
[\t];
[\n]
return 0;
.return yytext[0];
%
%
int yywrap()
{
return 1;
YACC PART:
%
{
#include<stdio.h>
int flag = 0;
%
}
%
token NUMBER
%
left
'+' '-'
%
left '*'
'/'
'%'
%
left '('
')'
%
%
ArithmeticExpression: E {
printf("\nResult=%d\n", $$);
return 0;
};
E: E '+'
E{
$$ = $1 + $3;
}
|
E '-'
E{
$$ = $1 - $3;
}
|
E '*'
E{
$$ = $1 * $3;
}
|
E '/'
E{
$$ = $1 / $3;
}
|
E '%'
E{
$$ = $1 % $3;
}
|
'('
E ')' {
$$ = $2;
}
|
NUMBER {
$$ = $1;
}
%
%
void main()
{
printf("\nEnter Any Arithmetic Expression which can have operations Addition,
Subtraction, Multiplication, Divison, Modulus and Round brackets:\n");
yyparse();
if (flag == 0)
void yyerror()
flag = 1;
Output :
12. Generate YACC specification for a few syntactic categories.
%
{
/* This LEX program returns the tokens for the expression */
#include “y.tab.h”
%
}
%
%“=”{
printf(“\n Operator is EQUAL”);
}“ + ”{
printf(“\n Operator is PLUS”);
}“ - “{
printf(“\n Operator is MINUS”);
}“
/” {printf(“\n Operator is DIVISION”);}“ * ”{
printf(“\n Operator is MULTIPLICATION”);
}
[a - z A - Z] * [0 - 9] * {
printf(“\n Identifier is % s”, yytext);
return ID;
}
return yytext[0];\
n
return 0; %
%
int yywrap() {
return 1;
}
%
{
#include
E: E’ + ’ID |
E’ - ’ID |
E’ * ’ID |
E’ / ’ID |
ID; %
%
extern FILE * yyin;
main() {
do {
yyparse();
} while (!feof(yyin));
}
yyerror(char * s) {}
Output:
Identifier is x
Operator is EQUAL
Identifier is a
Operator is PLUS
Identifier is b
b) Program to recognise a valid variable which starts with a
letter followed by any number of letters or digits.
%
{
/* This LEX program returns the tokens for the Expression */
#include "y.tab.h"
%
}%
%
"int " {
return INT;
}
"float" {
return FLOAT;
}
"double" {
return DOUBLE;
}
[a - zA - Z] * [0 - 9] * {
printf("\nIdentifier is %s", yytext);
return ID;
}
return yytext[0];\
n
return 0;
int yywrap() {
return 1;
}
%
{
#include
Output:
Identifier is a
Identifier is b[root@localhost]#
Source code :
#include<stdio.h>
#include<string.h>
void pm();
void plus();
void div();
int i, ch, j, l, addr = 100;
char ex[10], exp[10], exp1[10], exp2[10], id1[5], op[5],
id2[5]; void main() {
clrscr();
while (1) {
printf("\n1.assignment\n2.arithmetic\n3.relational\n4.Exit\nEnter the choice:");
scanf("%d", & ch);
switch (ch) {
case 1:
printf("\nEnter the expression with assignment operator:");
scanf("%s", exp);
l=
strlen(exp);
exp2[0] = '\0';
i = 0;
while (exp[i] != '=') {
i++;
}
strncat(exp2, exp,
i); strrev(exp);
exp1[0] = '\0';
strncat(exp1, exp, l - (i + 1));
strrev(exp1);
printf("Three address code:\ntemp=%s\n%s=temp\n", exp1, exp2);
break;
case 2:
printf("\nEnter the expression with arithmetic
operator:"); scanf("%s", ex);
strcpy(exp, ex);
l = strlen(exp);
exp1[0] = '\0';
case 3:
printf("Enter the expression with relational operator");
scanf("%s%s%s", & id1, & op, & id2);
if (((strcmp(op, "<") == 0) || (strcmp(op, ">") == 0) || (strcmp(op, "<=") == 0) || (strcmp(op,
">=") == 0) || (strcmp(op, "==") == 0) || (strcmp(op, "!=") == 0)) == 0)
printf("Expression is error");
else {
printf("\n%d\tif %s%s%s goto %d", addr, id1, op, id2, addr +
3); addr++;
printf("\n%d\t T:=0", addr);
addr++;
printf("\n%d\t goto %d", addr, addr +
2); addr++;
printf("\n%d\t T:=1", addr);
}
break;
case 4:
exit(0);
}
}
}
void pm() {
strrev(exp);
j = l - i - 1;
strncat(exp1, exp, j);
strrev(exp1);
printf("Three address code:\ntemp=%s\ntemp1=%c%ctemp\n", exp1, exp[j + 1], exp[j]);
}
void div() {
strncat(exp1, exp, i + 2);
printf("Three address code:\ntemp=%s\ntemp1=temp%c%c\n", exp1, exp[i + 2], exp[i + 3]);
}
void plus() {
strncat(exp1, exp, i + 2);
printf("Three address code:\ntemp=%s\ntemp1=temp%c%c\n", exp1, exp[i + 2], exp[i + 3]);
}
Output :
1. assignment
2. arithmetic
3. relational
4. Exit
Enter the choice:1
Enter the expression with assignment operator:
a=b
Three address code:
temp=b
a=temp
1.assignment
2.arithmetic
3.relational
4.Exit
Enter the choice:2
Enter the expression with arithmetic
operator: a+b-c
Three address code:
temp=a+b
temp1=temp-c
1.assignment
2.arithmetic
3.relational
4.Exit
Enter the choice:2
Enter the expression with arithmetic
operator: a-b/c
Three address code:
temp=b/c
temp1=a-temp
1.assignment
2.arithmetic
3.relational
4.Exit
Enter the choice:2
Enter the expression with arithmetic
operator: a*b-c
Three address code:
temp=a*b
temp1=temp-c
1.assignment
2.arithmetic
3.relational
4.Exit
Enter the choice:2
Enter the expression with arithmetic operator:a/b*c
Three address code:
temp=a/b
temp1=temp*c
1.assignment
2.arithmetic
3.relational
4.Exit
Enter the choice:3
Enter the expression with relational operator
a
<=
b
1.assignment
2.arithmetic
3.relational
4.Exit
Enter the choice:4