Professional Documents
Culture Documents
Compiler Design
(BTCS 604-18)
1
INDEX
2
Experiment No. 1
AIM: Design a lexical analyzer for given language and the lexical analyzer should
ignore redundant spaces, tabs and new lines. It should also ignore comments.
Although the syntax specification states thatidentifiers can be arbitrarily long, you
may restrict the length to some reasonable value. Simulate the samein C language.
CODE:-
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
bool isDelimiter(char ch)
{
if (ch == ' ' || ch == '+' || ch == '-' || ch == '*' ||
ch == '/' || ch == ',' || ch == ';' || ch == '>' ||
ch == '<' || ch == '=' || ch == '(' || ch == ')' ||
ch == '[' || ch == ']' || ch == '{' || ch == '}')
return (true);
return (false);
}
bool isOperator(char ch)
{ if (ch == '+' || ch == '-' || ch == '*'
|| ch == '/' || ch == '>' || ch == '<' ||
ch == '=')
return (true);
return (false);
}
3
bool isKeyword(char* str)
{ if (!strcmp(str, "if") || !strcmp(str, "else") ||
!strcmp(str, "while") || !strcmp(str, "do") ||
!strcmp(str, "break") ||
!strcmp(str, "continue") || !strcmp(str, "int")
|| !strcmp(str, "double") || !strcmp(str, "float")
|| !strcmp(str, "return") || !strcmp(str, "char")
|| !strcmp(str, "case") || !strcmp(str, "char")
|| !strcmp(str, "sizeof") || !strcmp(str, "long")
|| !strcmp(str, "short") || !strcmp(str, "typedef")
|| !strcmp(str, "switch") || !strcmp(str, "unsigned")
|| !strcmp(str, "void") || !strcmp(str, "static") || !strcmp(str, "struct") ||
!strcmp(str, "goto"))
return (true);
return (false);
}
bool isInteger(char* str)
{
int i, len = strlen(str);
if (len == 0)
return (false);
for (i = 0; i < len; i++){
if (str[i] != '0'&& str[i] != '1'&& str[i] != '2'&& str[i] != '3'&& str[i] !=
'4'&& str[i] != '5'&& str[i] != '6'&& str[i] != '7'&& str[i] != '8'&& str[i] !=
'9' || (str[i] == '-'&& i > 0))
return (false);
}return (true);
}
bool isRealNumber(char* str)
{
int i, len = strlen(str);
bool hasDecimal = false;
if (len == 0)
return (false);
for (i = 0; i < len; i++)
{
if (str[i] != '0'&& str[i] != '1'&& str[i] != '2'&& str[i] != '3'&& str[i] !=
'4'&& str[i] != '5'&& str[i] != '6'&& str[i] != '7'&& str[i] != '8'
&& str[i] != '9'&& str[i] != '.' || (str[i] == '-'&& i > 0))
4
return (false);
if (str[i] == '.')
hasDecimal = true;
}
return (hasDecimal);
}
char* subString(char* str, int left, int right)
{
int i;
char* subStr = (char*)malloc( sizeof(char) * (right - left + 2));
for (i = left; i <= right; i++)
subStr[i - left] = str[i];
subStr[right - left + 1] = '\0';
return (subStr);
}
void parse(char* str)
{
int left = 0, right = 0;
int len = strlen(str);
while (right <= len && left <= right) {
if (isDelimiter(str[right]) == false)
right++;
if (isDelimiter(str[right]) == true && left == right){
if (isOperator(str[right]) == true)
printf("'%c' IS AN OPERATOR\n", str[right]);
right++;
left = right;
}
else if (isDelimiter(str[right]) == true && left != right || (right == len &&
left != right))
{
char* subStr = subString(str, left, right - 1);
if (isKeyword(subStr) == true)
printf("'%s' IS A KEYWORD\n", subStr);
else if (isInteger(subStr) == true)
printf("'%s' IS AN INTEGER\n", subStr);
else if (isRealNumber(subStr) == true)
printf("'%s' IS A REAL NUMBER\n", subStr);
else if (validIdentifier(subStr) == true && isDelimiter(str[right - 1]) ==
false)
5
printf("'%s' IS A VALID IDENTIFIER\n", subStr);
else if (validIdentifier(subStr) == false && isDelimiter(str[right - 1]) ==
false)
printf("'%s' IS NOT A VALID IDENTIFIER\n", subStr);
left = right;
}}
return;
}
int main()
{
char str[100] = "int z = q + 20;
"; parse(str);
return (0);
}
OUTPUT:-
6
Experiment No. 2
CODE:
#include<stdio.h>
#include<conio.h>
void main()
{
char text[30]; int
i = 2, a = 0;
clrscr();
OUTPUT:-
8
Experiment No. 3
AIM:- Write a C program to recognize strings under 'a', 'a*b+', 'abb'.
CODE:-
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
void main()
{
char s[20],c;
int
state=0,i=0;
printf("\n Enter a string:");
gets(s);
while(s[i]!='\0')
{ switch(state)
{ case 0: c=s[i++];
if(c=='a') state=1;
else if(c=='b') state=2;
else state=6;
break;
case 1: c=s[i++];
if(c=='a') state=3;
else if(c=='b') state=4;
else state=6;
break;
case 2: c=s[i++];
if(c=='a') state=6;
else if(c=='b') state=2;
else state=6;
break;
case 3: c=s[i++];
if(c=='a') state=3;
else if(c=='b') state=2;
else state=6;
break;
case 4: c=s[i++];
9
if(c=='a') state=6;
else if(c=='b') state=5;
else state=6;
break;
case 5: c=s[i++];
if(c=='a') state=6;
else if(c=='b') state=2;
else state=6;
break;
case 6: printf("\n %s is not recognised.",s);
exit(0);} }
if(state==1) printf("\n %s is accepted under rule 'a'",s);
else if((state==2)||(state==4)) printf("\n %s is accepted under rule
'a*b+'",s);
else if(state==5) printf("\n %s is accepted under rule 'abb'",s);
getch();}
OUTPUT:-
10
Experiment No. 4
AIM:- Write a C program to test whether a given identifier is valid or not..
CODE:-
#include<stdio.h>
#include<ctype.h>
void main()
{
char a[10];
int flag, i=1;
printf("Enter an identifier: ");
gets(a);
if(isalpha(a[0]))
flag=1;
else
printf("\nNot a valid identifier");
while(a[i]!='\0'){ if(!isdigit(a[i])&&!
isalpha(a[i]))
{
flag=0;
break;
} i+
+;
}
if(flag==1)
printf("\nValid identifier");
getch();
}
OUTPUT:-
11
Experiment No. 5
AIM:- Write a C program to simulate lexical analyzer for validating operators.
CODE:-
#include<stdio.h>
void main()
{
char s[5];
printf("\nEnter any operator: ");
gets(s);
switch(s[0])
{ case'>':
if(s[1]=='=')
printf("\nGreater than or equal");
else
printf("\nGreater than");
break;
case'<': if(s[1]=='=') printf("\
nLess 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("\nBit Not");
break;
case'&': if(s[1]=='&')
printf("\nLogical AND");
else
printf("\n Bitwise AND");
break;
case'|': if(s[1]=='|')
12
printf("\nLogical OR");
else
printf("\nBitwise OR");
break;
case'+': printf("\nAddition");
break;
case'-': printf("\nSubstraction");
break;
case'*': printf("\nMultiplication");
break;
case'/': printf("\nDivision");
break;
case'%': printf("Modulus");
break;
default: printf("\nNot a operator");
}}
OUTPUT:-
13
Experiment No. 6
CODE:
#include <iostream>
using namespace std;
int main() {
char str[100];
int vowels;
vowels = 0;
cout<<"Enter a line of string: ";
cin.getline(str,100);
for (int i = 0; str[i] != '\0'; ++i) {
if
(str[i]=='a'||str[i]=='e'||str[i]=='i'||str[i]=='o'||str[i]=='u'||str[i]=='A'||str[i]=='E'
||str[i]=='I'||str[i]=='O'||str[i]=='U')
{
++vowels;
}
}
cout<<"Vowels: "<<vowels;
return 0;
}
OUTPUT:
14
Experiment No. 7
AIM: Implement the lexical analyzer using JLex, flex or other lexical analyzer
generating tools.
CODE:
#include<string.h>
#include<conio.h>
#include<ctype.h>
#include<stdio.h>
int main()
{
FILE *f1;
char c,str[10];
int lineno=1,num=0,i=0;
printf("\nEnter the c program\n");
f1=fopen("input.txt","w");
while((c=getchar())!=EOF)
putc(c,f1);
fclose(f1);
f1=fopen("input.txt","r");
while((c=getc(f1))!=EOF)
{
if(isdigit(c))
{
num=c-48;
c=getc(f1);
while(isdigit(c))
{
num=num*10+(c-48);
c=getc(f1);
}
printf("%d is a number \n",num);
ungetc(c,f1);
}
else if(isalpha(c))
{
str[i++]=c;
Riya (1815775)
c=getc(f1);
15
while(isdigit(c)||isalpha(c)||c=='_'||c=='$')
{
str[i++]=c;
c=getc(f1);
}
str[i++]='\0';
if(strcmp("for",str)==0||strcmp("while",str)==0||strcmp("do",str)==0||
strcmp("int",str)==0||strcmp("float",str)==0||strcmp("char",str)==0||
strcmp("double",str)==0||strcmp("static",str)==0||
strcmp("switch",str)==0||strcmp("case",str)==0)
printf("%s is a keyword\n",str);
else
printf("%s is a identifier\n",str);
ungetc(c,f1);
i=0;
}
else if(c==' '||c=='\t')
printf("\n");
else if(c=='\n')
lineno++;
else
printf("%c is a special symbol\n",c);
}
printf("Total no. of lines are: %d\n",lineno);
fclose(f1);
getch();
return 0;
}
16
OUTPUT:
17
Experiment No. 8
CODE:
#include<stdio.h>
#include<conio.h>
#include<string.h>
char prol[7][10]={"S","A","A","B","B","C","C"};
char pror[7][10]={"A","Bb","Cd","aB","@","Cc","@"};
char prod[7][10]={"S->A","A->Bb","A->Cd","B->aB","B->@","C->Cc","C->@"};
char first[7][10]={"abcd","ab","cd","a@","@","c@","@"}; char follow[7]
[10]={"$","$","$","a$","b$","c$","d$"};
char table[5][6][10];
int numr(char c)
{
switch(c){
case 'S': return 0;
case 'A': return 1;
case 'B': return 2;
case 'C': return 3;
case 'a': return 0;
case 'b': return 1;
case 'c': return 2;
case 'd': return 3;
case '$': return 4;
}
return(2);
}
int main()
{
int i,j,k;
for(i=0;i<5;i++)
for(j=0;j<6;j++)
strcpy(table[i][j]," ");
printf("\nThe following is the predictive parsing table for the following grammar:\n");
for(i=0;i<7;i++)
18
printf("%s\n",prod[i]);
printf("\nPredictive parsing table is\n");
fflush(stdin);
for(i=0;i<7;i++){
k=strlen(first[i]);
for(j=0;j<10;j++)
if(first[i][j]!='@')
strcpy(table[numr(prol[i][0])+1][numr(first[i][j])+1],prod[i]);
}
for(i=0;i<7;i++){
if(strlen(pror[i])==1)
{
if(pror[i][0]=='@')
{
k=strlen(follow[i]);
for(j=0;j<k;j++)
strcpy(table[numr(prol[i][0])+1][numr(follow[i][j])+1],prod[i]);
}
}
}
strcpy(table[0][0]," ");
strcpy(table[0][1],"a");
strcpy(table[0][2],"b");
strcpy(table[0][3],"c");
strcpy(table[0][4],"d");
strcpy(table[0][5],"$");
strcpy(table[1][0],"S");
strcpy(table[2][0],"A");
strcpy(table[3][0],"B");
strcpy(table[4][0],"C");
printf("\n--------------------------------------------------------\n");
for(i=0;i<5;i++)
for(j=0;j<6;j++){
printf("%-10s",table[i][j]);
if(j==5)
printf("\n--------------------------------------------------------\n");
}
getch();
}
19
OUTPUT:
20