Compiler-Design
Compiler-Design
Compiler-Design
OBJECTIVE:
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 that identifiers can be arbitrarily long, you may restrict the
length to some reasonable value. Simulate the same in C language.
PROGRAM:
#include <string.h>
#include <ctype.h>
#include <stdio.h>
void keyword(char str[10]){
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("\n%s is a keyword", str);
else
printf("\n%s is an identifier", str);
}
main(){
FILE *f1, *f2, *f3;
char c, str[10], st1[10];
int num[100], lineno = 0, tokenvalue = 0, i = 0, j = 0, k = 0;
printf("\nEnter the c program"); /*gets(st1);*/
f1 = fopen("input", "w");
while ((c = getchar()) != EOF)
putc(c, f1);
fclose(f1);
f1 = fopen("input", "r");
f2 = fopen("identifier", "w");
f3 = fopen("specialchar", "w");
while ((c = getc(f1)) != EOF){
if (isdigit(c)){
tokenvalue = c - '0';
c = getc(f1);
while (isdigit(c){
tokenvalue *= 10 + c - '0';
c = getc(f1);
}
num[i++] = tokenvalue;
ungetc(c, f1);
}
else if (isalpha(c)){
putc(c, f2);
c = getc(f1);
while (isdigit(c) || isalpha(c) || c == '_' || c == '$'){
putc(c, f2);
c = getc(f1);
}
putc(' ', f2);
ungetc(c, f1);
}
else if (c == ' ' || c == '\t')
printf(" ");
else if (c == '\n')
lineno++;
else
putc(c, f3);
}
fclose(f2);
fclose(f3);
fclose(f1);
printf("\nThe no's in the program are");
for (j = 0; j < i; j++)
printf("%d", num[j]);
printf("\n");
f2 = fopen("identifier", "r");
k = 0;
printf("The keywords and identifiersare:");
while ((c = getc(f2)) != EOF){
if (c != ' ')
str[k++] = c;
else{
str[k] = '\0';
keyword(str);
k = 0;
}
}
fclose(f2);
f3 = fopen("specialchar", "r");
printf("\nSpecial characters are");
while ((c = getc(f3)) != EOF)
printf("%c", c);
printf("\n");
fclose(f3);
printf("Total no. of lines are:%d", lineno);
}
OUTPUT:
EXPERIMENT- 2
OBJECTIVE:
Write a C program to identify whether a given line is a comment or not.
PROGRAM:
#include <stdio.h>
#include <conio.h>
void main(){
char text[30];
int i = 2, a = 0;
printf("\nWrite a C Program to Identify Whether a Given Line is a Commentor Not.");
printf("\n\nEnter Text : ");
gets(text);
if (text[0] == '/'){
if (text[1] == '/'){
printf("\nIt is a Comment.");
}
else if (text[1] == '*'){
for (i = 2; i <= 30; i++) {
if (text[i] == '*' && text[i + 1] == '/') {
printf("\nIt is a Comment.");
a = 1;
break;
}
else {
continue;
}
}
if (a == 0) {
printf("\nIt is Not a Comment.");
}
else {
printf("\nIt is Not a Comment.");
}
}
}
else {
printf("\nIt is Not a Comment.");
}
getch();
}
OUTPUT:
EXPERIMENT- 3
OBJECTIVE:
Write a C program to recognize strings under 'a', 'a*b+', 'abb'.
PROGRAM:
#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++];
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:
EXPERIMENT- 4
OBJECTIVE:
Write a C program to test whether a given identifier is valid or not.
PROGRAM:
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
void main() {
char a[10];
int flag, i = 1;
printf("\n Enter an identifier:");
gets(a);
if (isalpha(a[0]))
flag = 1;
else
printf("\n Not a valid identifier");
while (a[i] != '\0') {
if (!isdigit(a[i]) && !isalpha(a[i])) {
flag = 0;
break;
}
i++;
}
if (flag == 1)
printf("\n Valid identifier");
getch();
}
OUTPUT:
EXPERIMENT- 5
OBJECTIVE:
Write a C program to simulate lexical analyzer for validating operators.
PROGRAM:
#include <stdio.h>
#include <conio.h>
void main() {
char s[5];
printf("\n Enter any operator:");
gets(s);
switch (s[0]) {
case '>':
if (s[1] == '=')
printf("\n Greater than or equal");
else
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();
}
OUTPUT:
EXPERIMENT- 6
OBJECTIVE:
Implement the lexical analyzer using JLex, flex or other lexical analyzer generating
tools.
PROGRAM:
/* program name is lexp.l */
%{
/* program to recognize a c program */
int COMMENT=0;
int cnt=0;
%}
identifier [a-zA-Z][a-zA-Z0-9]*
%%
#.* { printf("\n%s is a PREPROCESSOR DIRECTIVE",yytext);}
int |
float |
char |
double |
while |
for |
do |
if |
break |
continue |
void |
switch |
case |
long |
struct |
const |
typedef |
return |
else |
goto {printf("\n\t%s is a KEYWORD",yytext);}
"/*" {COMMENT = 1;}
"*/" {COMMENT = 0; cnt++;}
{identifier}\( {if(!COMMENT)printf("\n\nFUNCTION\n\t%s",yytext);}
\{ {if(!COMMENT) printf("\n BLOCK BEGINS");}
\} {if(!COMMENT) printf("\n 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\t%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)
{
if (argc > 1)
{
FILE *file;
file = fopen(argv[1],"r");
if(!file)
{
printf("could not open %s \n",argv[1]);
exit(0);
}
yyin = file;
}
yylex();
printf("\n\n Total No.Of comments are %d",cnt);
return 0;
}
int yywrap()
{
return 1;
}
OUTPUT:
EXPERIMENT- 7
OBJECTIVE:
Write a C program for implementing the functionalities of predictive parser for the mini
language specified in Note 1.
PROGRAM:
#include<stdio.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 num(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;
default: 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++)
printf("%s\n", prod[i]);
printf("\nPredictive parsing table is\n");
for(i = 0; i < 7; i++) {
k = strlen(first[i]);
for(j = 0; j < 10; j++)
if(first[i][j] != '@')
strcpy(table[num(prol[i][0]) + 1][num(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[num(prol[i][0]) + 1][num(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");
}
}
return 0;
}
OUTPUT:
EXPERIMENT- 8(a)
OBJECTIVE:
Write a C program for constructing of LL (1) parsing.
PROGRAM:
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
EXPERIMENT- 8(b)
OBJECTIVE:
Write a C program for constructing recursive descent parsing.
PROGRAM:
#include <stdio.h>
#include <string.h>
#define SUCCESS 1
#define FAILED 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() {
printf("Error in the input\n");
exit(0);
}
void isreduce(char x, char p) {
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)
printf("Stack is empty\n");
else {
}
item = s[*sp];
*sp = *sp - 1;
return item;
}
void printt(char *t, int *p, char inp[], int i) {
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) {
case 'a':
printf("0");
break;
case 'b':
printf("1");
break;
case 'c':
printf("2");
break;
case 'd':
printf("3");
break;
case 'e':
printf("4");
break;
case 'f':
printf("5");
break;
case 'g':
printf("6");
break;
case 'h':
printf("7");
break;
case 'm':
printf("8");
break;
case 'j':
printf("9");
break;
case 'k':
printf("10");
break;
case 'l':
printf("11");
break;
default:
printf("%c", t[r]);
break;
}
}
OUTPUT:
EXPERIMENT- 10(a)
OBJECTIVE:
Write a C program to implement operator precedence parsing.
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define STACK_SIZE 100
int isOperator(char ch) {
return (ch == '+' || ch == '-' || ch == '*' || ch == '/');
}
int operate(int a, char op, int b) {
switch(op) {
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
if (b != 0)
return a / b;
else {
printf("Error: Division by zero\n");
exit(EXIT_FAILURE);
}
default:
return 0;
}
}
int operatorPrecedenceParse(const char *expression) {
int stack[STACK_SIZE];
int top = -1;
int i = 0;
while (expression[i] != '\0') {
if (isdigit(expression[i])) {
int num = 0;
while (isdigit(expression[i])) {
num = num * 10 + (expression[i] - '0');
i++;
}
stack[++top] = num;
} else if (isOperator(expression[i])) {
while (top >= 0 && isOperator(stack[top]) &&
((expression[i] != '*' && expression[i] != '/') ||
(stack[top] != '+' && stack[top] != '-'))) {
int b = stack[top--];
int a = stack[top--];
stack[++top] = operate(a, expression[i], b);
}
stack[++top] = expression[i++];
} else {
printf("Invalid character in expression: %c\n", expression[i]);
exit(EXIT_FAILURE);
}
}
while (top > 0) {
int b = stack[top--];
char op = stack[top--];
int a = stack[top--];
stack[++top] = operate(a, op, b);
}
return stack[top];
}
int main() {
char expression[100];
printf("Enter an infix expression: ");
scanf("%s", expression);
int result = operatorPrecedenceParse(expression);
printf("Result: %d\n", result);
return 0;
}
OUTPUT:
EXPERIMENT- 10(b)
OBJECTIVE:
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
int result = 0;
int num = 0;
int i = 0;
if (expr[i] == '+') {
i++;
int nextNum = 0;
i++;
num *= nextNum;
i++;
return result;
int main() {
char expr[100];
scanf("%s", expr);
return 0;
}
OUTPUT: