Aashish COMPILER
Aashish COMPILER
1st Semester
Session 2024-2026
Compiler Design
(20MCA21C2)
This is to certify that Aashish S/O Anil Kumar has submitted a practical file for
fulfilment of MCA 1st semester lab course for Compiler Design.
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
bool isOperator(char c) {
char operators[] = "+-*/%=<>&|!^";
for (int i = 0; operators[i] != '\0'; i++) {
if (c == operators[i]) {
return true;
}
}
return false;
}
bool isKeyword(char* word) {
char keywords[][32] = {
"auto", "break", "case", "char", "const", "continue", "default",
"do", "double", "else", "enum", "extern", "float", "for", "goto",
"if", "int", "long", "register", "return", "short", "signed",
"sizeof", "static", "struct", "switch", "typedef", "union",
"unsigned", "void", "volatile", "while"
};
for (int i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) {
if (strcmp(word, keywords[i]) == 0) {
return true;
}
}
return false;
}
int main() {
char expression[1000];
printf("Enter an expression: ");
fgets(expression, sizeof(expression), stdin);
int operatorCount = 0;
int identifierCount = 0;
int keywordCount = 0;
int constantCount = 0;
char* token = expression;
while (*token) {
if (isOperator(*token)) {
operatorCount++;
token++;
} else if (isalpha(*token) || *token == '_') {
// Check if it's a keyword or identifier
char word[32];
int wordIndex = 0;
while (isalnum(*token) || *token == '_') {
word[wordIndex++] = *token;
token++;
}
word[wordIndex] = '\0';
if (isKeyword(word)) {
keywordCount++;
}
else {
identifierCount++;
}
}
else if (isdigit(*token) || (*token == '-' && isdigit(*(token + 1)))) {
// Check if it's a constant
while (isdigit(*token) || *token == '.' || *token == 'e' || *token == 'E' || (*token == '-' &&
(isdigit(*(token + 1)) || tolower(*(token + 1)) == 'e'))) {
token++;
}
constantCount++;
}
else {
token++;
}
}
printf("Operators: %d\n", operatorCount);
printf("Identifiers: %d\n",
identifierCount);
printf("Keywords: %d\n",
keywordCount);
printf("Constants: %d\n",
constantCount);
return 0;
}
Output:
EXPERIMENT 2
#include <stdio.h>
#include <string.h>
#include<stdio.h>
#include<string.h>
int axn[][6][2]={ {{100,5},{-1,-1},{-1,-1},{100,4},{-1,-1},{-1,-1}}, {{-1,-1},{100,6},{-1,-1},{-
1,-1},{-1,-1},{102,102}},
{{-1,-1},{101,2},{100,7},{-1,-1},{101,2},{101,2}}, {{-1,-1},{101,4},{101,4},{-1,-
1},{101,4},{101,4}},
{{100,5},{-1,-1},{-1,-1},{100,4},{-1,-1},{-1,-1}}, {{-1,-1},{101,6},{101,6},{-1,-
1},{101,6},{101,6}},
{{100,5},{-1,-1},{-1,-1},{100,4},{-1,-1},{-1,-1}}, {{100,5},{-1,-1},{-1,-1},{100,4},{-1,-1},{-
1,-1}},
{{-1,-1},{100,6},{-1,-1},{-1,-1},{100,1},{-1,-1}}, {{-1,-1},{101,1},{100,7},{-1,-
1},{101,1},{101,1}},
{{-1,-1},{101,3},{101,3},{-1,-1},{101,3},{101,3}}, {{-1,-1},{101,5},{101,5},{-1,-
1},{101,5},{101,5}}
};//Axn Table
int gotot[12][3]={1,2,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,8,2,3,-1,-1,-1,-1,9,3,-1,-1,10,-1,-1,-1,-1,-1,-1,-1,-
1,-1,-1,-1,-1}; //GoTo table
int a[10];
char b[10];
int top=-1,btop=-1,i;
void push(int k){
if(top<9)
a[++top]=k;
}
void pushb(char k){
if(btop<9)
b[++btop]=k;
}
char TOS(){
return a[top];
}
void pop(){
if(top>=0)
top--;
}
void popb(){
if(btop>=0)
b[btop--]='\0';
}
void display(){
for(i=0;i<=top;i++)
printf("%d%c",a[i],b[i]);
}
void display1(char p[],int m) {
int l;
printf("\t\t");
for(l=m;p[l]!='\0';l++)
printf("%c",p[l]);
printf("\n");
}
void error(){
printf("Syntax Error");}
void reduce(int p){
int len,k,ad;
char src,*dest;
switch(p){
case 1:dest="E+T";
src='E';
break;
case 2:dest="T";
src='E';
break;
case 3:dest="T*F";
src='T';
break;
case 4:dest="F";
src='T';
break;
case 5:dest="(E)";
src='F';
break;
case 6:dest="i";
src='F';
break;
default:dest="\0";
src='\0';
break; }
for(k=0;k<strlen(dest);k++){
pop();
popb();
}
pushb(src);
switch(src)
{
case 'E':ad=0;
break;
case 'T':ad=1;
break;
case 'F':ad=2;
break;
default: ad=-1;
break; }
push(gotot[TOS()][ad]);}
int main(){
int j,st,ic;
char ip[20]="\0",an;
printf("Enter any String\n");
scanf("%s",ip);
push(0);
display();
printf("\t%s\n",ip);
for(j=0;ip[j]!='\0';)
{
st=TOS();
an=ip[j];
if(an>='a'&&an<='z') ic=0;
else if(an=='+') ic=1;
else if(an=='*') ic=2;
else if(an=='(') ic=3;
else if(an==')') ic=4;
else if(an=='$') ic=5;
else {
error();
break;
}
if (axn[st][ic][0] == 100) {
pushb(an);
push(axn[st][ic][1]);
display();
j++;
display1(ip, j);
} else if (axn[st][ic][0] == 101) {
reduce(axn[st][ic][1]);
display();
display1(ip, j);
} else if (axn[st][ic][1] == 102) {
printf("Given String is accepted \n");
break;
}
else{
printf("Given String is rejected");
break; }}
return 0;
}
EXPERIMENT-5
Design LALR bottom-up parser for the given language.
<parser.l>
%{
#include<stdio.h>
#include "y.tab.h"
%}
%%
[0-9]+ {yylval.dval=atof(yytext);
return DIGIT;
%%
<parser.y>
%{
#include<stdio.h>
%}
%union
{
double dval;
}
%token <dval> DIGIT
%%
line: expr '\n' {
printf("%g\n",$1);
}
;
expr: expr '+' term {$$=$1 + $3 ;}
| term
;
term: term '*' factor {$$=$1 * $3 ;}
| factor
;
factor: '(' expr ')' {$$=$2 ;}
| DIGIT
;
%%
int main()
{
yyparse();
}
yyerror(char *s)
{
printf("%s",s);
}
Output :
$lex parser.l
$yacc –d parser.y
$cc lex.yy.c y.tab.c –ll –lm
$./a.out
2+3
EXPERIMENT 6
#include <stdio.h>
#include <stdlib.h>
// Structure to represent a state in the NFA
typedef struct State {
int label; // State label
struct State *transitions[2]; // Array to store transitions (0 and 1)
} State;
// Structure to represent an NFA
typedef struct NFA {
State *start; // Initial state
State *accept; // Accepting state
} NFA;
// Function to create a new state
State *createState(int label) {
State *newState = (State *)malloc(sizeof(State));
newState->label = label;
newState->transitions[0] = newState->transitions[1] = NULL;
return newState;
}
// Function to create an NFA for a character
NFA *createCharNFA(char c) {
NFA *nfa = (NFA *)malloc(sizeof(NFA));
nfa->start = createState(0);
nfa->accept = createState(1);
nfa->start->transitions[c - 'a'] = nfa->accept;
printf("NFA for '%c':\n", c);
printf("(q%d) --%c--> (q%d)\n", nfa->start->label, c, nfa->accept->label);
return nfa;
}
// Function to create an NFA for concatenation (X.Y)
NFA *concatenateNFA(NFA *nfa1, NFA *nfa2) {
nfa1->accept->transitions[0] = nfa2->start;free(nfa2);
printf("Concatenation NFA:\n");
printf("(q%d) --ε--> (q%d) --ε--> (q%d)\n", nfa1->start->label, nfa1->accept->label, nfa1-
>accept->transitions[0]>label);
return nfa1;
}
// Function to create an NFA for union (X|Y)
NFA *unionNFA(NFA *nfa1, NFA *nfa2) {
NFA *nfa = (NFA *)malloc(sizeof(NFA));
nfa->start = createState(0);
nfa->accept = createState(1);
nfa->start->transitions[0] = nfa1->start;
nfa->start->transitions[1] = nfa2->start;
nfa1->accept->transitions[0] = nfa->accept;
nfa2->accept->transitions[0] = nfa->accept;
free(nfa1);
free(nfa2);
printf("\n\nUnion NFA:\n");
printf(" a\n(q%d)---a---> (q%d)\n", nfa->start->label, nfa1->start->label);
printf(" | b\n");
printf("|\n");
printf(" aa\n");
printf("||\n");
printf("(q%d) ---a---> (q%d)\n\n\n", nfa1->accept->transitions[0]->label, nfa->accept->label);
return nfa;
}
// Function to create an NFA for Kleene star (X*)
NFA *kleeneStarNFA(NFA *nfa) {
nfa->start->transitions[1] = nfa->accept;
nfa->accept->transitions[0] = nfa->start;
printf("\nKleene Star NFA:\n");
printf(" a\n");
printf("(q%d) ---a---> (q%d) ---a---> (q%d)\n", nfa->start->label, nfa->accept->transitions[0]-
>label, nfa->accept>label);
printf(" ^ |\n");
return nfa;
}
// Function to simulate the NFA for an input string
int simulateNFA(NFA *nfa, const char *input) {
State *currentState = nfa->start;
int i = 0;
while (input[i] != '\0') {
char currentSymbol = input[i];
if (currentSymbol == 'a') {
currentState = currentState->transitions[0];
} else if (currentSymbol == 'b') {
currentState = currentState->transitions[1];
} else {
fprintf(stderr, "Invalid input symbol: %c\n", currentSymbol);
return 0;
}
if (currentState == NULL) {
fprintf(stderr, "Invalid transition for symbol: %c\n", currentSymbol);
return 0;
}
i++;
}
if (currentState == nfa->accept) {
printf("Input string \"%s\" accepted!\n", input);
return 1;
} else {
printf("Input string \"%s\" rejected!\n", input);
return 0;
}
}
int main() {
// Construct NFA for 'ab|c*'
NFA *nfaA = createCharNFA('a');
NFA *nfaB = createCharNFA('b');
NFA *nfaC = kleeneStarNFA(createCharNFA('c'));
NFA *nfaUnion = unionNFA(nfaA, nfaB);
NFA *nfaConcatenate = concatenateNFA(nfaUnion, nfaC);
// Simulate the NFA for input strings
simulateNFA(nfaConcatenate, "ab");
simulateNFA(nfaConcatenate, "ac");
simulateNFA(nfaConcatenate, "abcc");
simulateNFA(nfaConcatenate, "cc");
// Clean up
free(nfaConcatenate);
return 0;
}
Output