KEMBAR78
Compiler Lab Report PDF | PDF | Software Engineering | Computer Programming
0% found this document useful (0 votes)
14 views41 pages

Compiler Lab Report PDF

The document contains multiple C programs that demonstrate various concepts in programming, including comment validation, string pattern recognition, identifier validation, lexical analysis, and grammar parsing. Each program is designed to handle specific tasks such as checking valid comments, recognizing string patterns, validating identifiers, performing lexical analysis, and computing FIRST and FOLLOW sets for grammar. The document provides complete code examples and user interaction for testing these functionalities.

Uploaded by

dkatwal254
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views41 pages

Compiler Lab Report PDF

The document contains multiple C programs that demonstrate various concepts in programming, including comment validation, string pattern recognition, identifier validation, lexical analysis, and grammar parsing. Each program is designed to handle specific tasks such as checking valid comments, recognizing string patterns, validating identifiers, performing lexical analysis, and computing FIRST and FOLLOW sets for grammar. The document provides complete code examples and user interaction for testing these functionalities.

Uploaded by

dkatwal254
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 41

1.

write a c program to test whether given entered string within valid comment section or
not

#include <stdio.h>

#include <string.h>

int main() {

char str[500];

char choice;

do {

printf("\nEnter a string: ");

fgets(str, sizeof(str), stdin);

str[strcspn(str, "\n")] = '\0';

int len = strlen(str);

// Check for single-line comment //

if (len >= 2 && str[0] == '/' && str[1] == '/') {

printf("Valid single-line comment.\n");

// Check for multi-line comment /* ... */

else if (len >= 4 && str[0] == '/' && str[1] == '*' && str[len-2] == '*' && str[len-1] == '/') {

printf("Valid multi-line comment.\n");

else {

printf("Not a valid comment.\n");

}
printf("Do you want to check another string? (y/n): ");

scanf(" %c", &choice);

getchar();

} while (choice == 'y' || choice == 'Y');

printf("Program ended.\n");

return 0;

Output:

2. Write a program to recognize strings under 'a*','a*b+','abb'

#include <stdio.h>

#include <string.h>

int isAStar(char str[]) {

for (int i = 0; str[i] != '\0'; i++)


if (str[i] != 'a') return 0;

return 1;

int isABPlus(char str[]) {

int i = 0;

while (str[i] == 'a') i++;

int bCount = 0;

while (str[i] == 'b') {

i++;

bCount++;

if (bCount >= 1 && str[i] == '\0') return 1;

return 0;

int isABB(char str[]) {

return strcmp(str, "abb") == 0;

int main() {

char str[100];

char choice;

do {

printf("\nEnter a string: ");


scanf("%s", str);

if (isAStar(str))

printf("String matches pattern: a*\n");

else if (isABPlus(str))

printf("String matches pattern: a*b+\n");

else if (isABB(str))

printf("String matches pattern: abb\n");

else

printf("String does not match any pattern.\n");

printf("Do you want to check another string? (y/n): ");

scanf(" %c", &choice);

} while (choice == 'y' || choice == 'Y');

printf("Program ended.\n");

return 0;

}
3. c program to test whether a given identifier is valid or not

#include <stdio.h>

#include <ctype.h>

#include <string.h>

const char *keywords[] = {

"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"

};

int isKeyword(char str[]) {

for (int i = 0; i < sizeof(keywords)/sizeof(keywords[0]); i++) {

if (strcmp(str, keywords[i]) == 0)

return 1;

return 0;

int isValidIdentifier(char str[]) {

int len = strlen(str);

if (len == 0) return 0;

if (!isalpha(str[0]) && str[0] != '_') return 0;

for (int i = 1; i < len; i++) {

if (!isalnum(str[i]) && str[i] != '_') return 0;

}
if (isKeyword(str)) return 0;

return 1;

int main() {

char str[100];

char choice;

do {

printf("\nEnter an identifier: ");

scanf("%s", str);

if (isValidIdentifier(str))

printf("'%s' is a valid identifier.\n", str);

else

printf("'%s' is NOT a valid identifier.\n", str);

printf("Do you want to check another identifier? (y/n): ");

scanf(" %c", &choice);

} while (choice == 'y' || choice == 'Y');

printf("Program ended.\n");

return 0;

}
4. write a c program for lexical analyzer

#include <stdio.h>

#include <ctype.h>

#include <string.h>

#include <stdlib.h>

char *keywords[] = {

"int", "float", "double", "char", "void", "if", "else", "while",

"for", "return", "do", "switch", "case", "break", "continue"

};

#define NUM_KEYWORDS (sizeof(keywords) / sizeof(keywords[0]))

int isKeyword(char *str) {

for (int i = 0; i < NUM_KEYWORDS; i++) {

if (strcmp(str, keywords[i]) == 0)

return 1;

return 0;

int isIdentifier(char *str) {


if (!isalpha(str[0]) && str[0] != '_')

return 0;

for (int i = 1; str[i]; i++) {

if (!isalnum(str[i]) && str[i] != '_')

return 0;

return 1;

void lexicalAnalyzer(FILE *fp) {

char ch, str[100];

int i, state = 0;

printf("TOKENS:\n");

printf("-------\n");

while ((ch = fgetc(fp)) != EOF) {

switch (state) {

case 0:

if (isalpha(ch) || ch == '_') {

str[0] = ch;

i = 1;

state = 1;

else if (isdigit(ch)) {

str[0] = ch;

i = 1;
state = 2;

else if (ch == '\"') {

state = 3; // String literal

printf("STRING: ");

else if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '=') {

printf("OPERATOR: %c\n", ch);

else if (ch == ';' || ch == ',' || ch == '(' || ch == ')' || ch == '{' || ch == '}' || ch == '[' ||


ch == ']') {

printf("PUNCTUATION: %c\n", ch);

else if (isspace(ch)) {

else {

printf("UNKNOWN: %c\n", ch);

break;

case 1:

if (isalnum(ch) || ch == '_') {

str[i++] = ch;

} else {

str[i] = '\0';

if (isKeyword(str)) {
printf("KEYWORD: %s\n", str);

} else if (isIdentifier(str)) {

printf("IDENTIFIER: %s\n", str);

} else {

printf("INVALID IDENTIFIER: %s\n", str);

state = 0;

ungetc(ch, fp);

break;

case 2:

if (isdigit(ch)) {

str[i++] = ch;

} else {

str[i] = '\0';

printf("CONSTANT: %s\n", str);

state = 0;

ungetc(ch, fp);

break;

case 3:

if (ch == '\"') {

printf("\"\n");

state = 0;
} else if (ch == '\\') {

printf("%c", ch);

ch = fgetc(fp);

printf("%c", ch);

} else {

printf("%c", ch);

break;

if (state == 1) {

str[i] = '\0';

if (isKeyword(str)) {

printf("KEYWORD: %s\n", str);

} else {

printf("IDENTIFIER: %s\n", str);

} else if (state == 2) {

str[i] = '\0';

printf("CONSTANT: %s\n", str);

} else if (state == 3) {

printf("\"\n");

printf("ERROR: Unterminated string\n");

}
int main() {

FILE *fp = fopen("input.txt", "r");

if (fp == NULL) {

printf("Error: Could not open input.txt\n");

return 1;

lexicalAnalyzer(fp);

fclose(fp);

return 0;

*create a file named input.txt with sample code

int main() {

int a = 10;

float b = 3.14;

a = a + 1;

return 0;

}
5. C program to implement first of a given grammar

#include <stdio.h>

#include <ctype.h>

#include <string.h>

#define MAX 20

char production[MAX][MAX], firstSet[MAX];

int n;

int m = 0;

void findFirst(char c);

void addToFirstSet(char c);

int main() {

int i;

char choice, c;

printf("Enter number of productions: ");


scanf("%d", &n);

printf("Enter the productions (E.g. E=E+T):\n");

for (i = 0; i < n; i++) {

scanf("%s", production[i]);

do {

m = 0;

printf("\nEnter the non-terminal to find FIRST: ");

scanf(" %c", &c);

findFirst(c);

printf("FIRST(%c) = { ", c);

for (i = 0; i < m; i++) {

printf("%c ", firstSet[i]);

printf("}\n");

printf("\nDo you want to continue? (y/n): ");

scanf(" %c", &choice);

} while (choice == 'y' || choice == 'Y');

return 0;

}
void findFirst(char c) {

int i, j;

if (!(isupper(c))) {

addToFirstSet(c);

return;

for (i = 0; i < n; i++) {

if (production[i][0] == c) {

if (production[i][2] == '#') {

// Epsilon production

addToFirstSet('#');

else if (!isupper(production[i][2])) {

// Terminal

addToFirstSet(production[i][2]);

else {

findFirst(production[i][2]);

}
void addToFirstSet(char c) {

int i;

for (i = 0; i < m; i++) {

if (firstSet[i] == c)

return;

firstSet[m++] = c;

6. c program to calculate Follow(A)

#include <stdio.h>

#include <string.h>

#include <ctype.h>

#define MAX 20

char production[MAX][MAX], followSet[MAX], firstSet[MAX];

int n;

int m = 0;

char startSymbol;
void findFirst(char c);

void findFollow(char c);

void addToFirstSet(char c);

void addToFollowSet(char c);

int main() {

int i;

char c, choice;

printf("Enter number of productions: ");

scanf("%d", &n);

printf("Enter the productions (e.g., E=E+T):\n");

for (i = 0; i < n; i++) {

scanf("%s", production[i]);

startSymbol = production[0][0]; // first LHS is start symbol

do {

m = 0;

printf("\nEnter the non-terminal to find FOLLOW: ");

scanf(" %c", &c);

findFollow(c);
printf("FOLLOW(%c) = { ", c);

for (i = 0; i < m; i++) {

printf("%c ", followSet[i]);

printf("}\n");

printf("\nDo you want to continue? (y/n): ");

scanf(" %c", &choice);

} while (choice == 'y' || choice == 'Y');

return 0;

void findFirst(char c) {

int i;

if (!isupper(c)) {

addToFirstSet(c);

return;

for (i = 0; i < n; i++) {

if (production[i][0] == c) {

if (production[i][2] == '#') {

addToFirstSet('#');

} else if (!isupper(production[i][2])) {

addToFirstSet(production[i][2]);

} else {

findFirst(production[i][2]);
}

void findFollow(char c) {

int i, j, k;

if (c == startSymbol) {

addToFollowSet('$'); // Rule 1

for (i = 0; i < n; i++) {

for (j = 2; j < strlen(production[i]); j++) {

if (production[i][j] == c) {

if (production[i][j + 1] != '\0') {

if (!isupper(production[i][j + 1])) {

addToFollowSet(production[i][j + 1]);

} else {

m = 0;

findFirst(production[i][j + 1]);

for (k = 0; k < m; k++) {

if (firstSet[k] != '#')

addToFollowSet(firstSet[k]);

else {

findFollow(production[i][0]); // Rule 3

}
}

} else {

// Case A -> aB

if (production[i][0] != c) {

findFollow(production[i][0]);

void addToFirstSet(char c) {

int i;

for (i = 0; i < m; i++) {

if (firstSet[i] == c) return;

firstSet[m++] = c;

void addToFollowSet(char c) {

int i;

for (i = 0; i < m; i++) {

if (followSet[i] == c) return;

followSet[m++] = c;
}

7. c program for constructing of LL(1) parsing

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <ctype.h>

#define MAX 50

char productions[MAX][MAX], nonTerminals[MAX], terminals[MAX];

int prodCount = 0, ntCount = 0, tCount = 0;

char table[MAX][MAX][MAX]; // LL(1) parsing table

// FIRST and FOLLOW sets

char firstSet[MAX][MAX], followSet[MAX][MAX];

int isIn(char *set, char c) {

for (int i = 0; set[i]; i++) if (set[i] == c) return 1;

return 0;

void addToSet(char *set, char c) {


if (!isIn(set, c)) {

int len = strlen(set);

set[len] = c;

set[len+1] = '\0';

void computeFirst(char symbol, char *result) {

if (!isupper(symbol)) { // terminal

addToSet(result, symbol);

return;

for (int i = 0; i < prodCount; i++) {

if (productions[i][0] == symbol) {

if (productions[i][2] == '#') {

addToSet(result, '#');

} else {

for (int j = 2; productions[i][j]; j++) {

char temp[MAX] = "";

computeFirst(productions[i][j], temp);

for (int k = 0; temp[k]; k++) {

if (temp[k] != '#')

addToSet(result, temp[k]);

if (!isIn(temp, '#')) break;

if (!productions[i][j+1])

addToSet(result, '#');
}

void computeFollow(char symbol, char *result) {

if (symbol == productions[0][0]) addToSet(result, '$'); // start symbol

for (int i = 0; i < prodCount; i++) {

for (int j = 2; productions[i][j]; j++) {

if (productions[i][j] == symbol) {

if (productions[i][j+1]) {

char temp[MAX] = "";

computeFirst(productions[i][j+1], temp);

for (int k = 0; temp[k]; k++) {

if (temp[k] != '#')

addToSet(result, temp[k]);

if (isIn(temp, '#'))

computeFollow(productions[i][0], result);

} else if (productions[i][j] != productions[i][0]) {

computeFollow(productions[i][0], result);

}
}

void buildTable() {

for (int i = 0; i < ntCount; i++)

for (int j = 0; j < tCount; j++)

strcpy(table[i][j], " ");

for (int i = 0; i < prodCount; i++) {

char A = productions[i][0];

char rhs[MAX];

strcpy(rhs, productions[i] + 2);

char first[MAX] = "";

computeFirst(rhs[0], first);

int row = strchr(nonTerminals, A) - nonTerminals;

for (int k = 0; first[k]; k++) {

if (first[k] != '#') {

char *ptr = strchr(terminals, first[k]);

if (ptr) {

int col = ptr - terminals;

strcpy(table[row][col], productions[i]);

} else {

char follow[MAX] = "";

computeFollow(A, follow);
for (int m = 0; follow[m]; m++) {

char *ptr = strchr(terminals, follow[m]);

if (ptr) {

int col = ptr - terminals;

strcpy(table[row][col], productions[i]);

void printTable() {

printf("\nLL(1) Parsing Table:\n\t");

for (int j = 0; j < tCount; j++) printf("%c\t", terminals[j]);

printf("\n");

for (int i = 0; i < ntCount; i++) {

printf("%c\t", nonTerminals[i]);

for (int j = 0; j < tCount; j++) {

printf("%s\t", table[i][j]);

printf("\n");

int parseString(char *input) {

char stack[MAX] = "$";


stack[1] = productions[0][0];

stack[2] = '\0';

int top = 1; // points to stack top

printf("\nParsing steps:\n");

int ip = 0;

while (1) {

printf("Stack: %s | Input: %s | ", stack, input+ip);

char X = stack[top];

char a = input[ip];

if (X == '$' && a == '$') {

printf("Accept\n");

return 1;

} else if (!isupper(X)) { // terminal

if (X == a) {

printf("Match %c\n", a);

top--; stack[top+1] = '\0';

ip++;

} else {

printf("Error (expected %c, got %c)\n", X, a);

return 0;

} else {
char *rowPtr = strchr(nonTerminals, X);

char *colPtr = strchr(terminals, a);

if (!rowPtr || !colPtr) {

printf("Error (no rule for %c,%c)\n", X, a);

return 0;

int row = rowPtr - nonTerminals;

int col = colPtr - terminals;

if (strcmp(table[row][col], " ") == 0) {

printf("Error (no rule for %c,%c)\n", X, a);

return 0;

} else {

printf("Output %s\n", table[row][col]);

top--; stack[top+1] = '\0';

char rhs[MAX];

strcpy(rhs, table[row][col] + 2);

if (!(rhs[0] == '#' && rhs[1] == '\0')) {

int len = strlen(rhs);

for (int k = len-1; k >= 0; k--) {

top++;

stack[top] = rhs[k];

stack[top+1] = '\0';

}
}

int main() {

printf("Enter number of productions: ");

scanf("%d", &prodCount);

getchar();

for (int i = 0; i < prodCount; i++) {

printf("Enter production %d: ", i+1);

scanf("%s", productions[i]);

if (!isIn(nonTerminals, productions[i][0])) {

nonTerminals[ntCount++] = productions[i][0];

nonTerminals[ntCount] = '\0';

for (int j = 2; productions[i][j]; j++) {

if (!isupper(productions[i][j]) && productions[i][j] != '#') {

if (!isIn(terminals, productions[i][j])) {

terminals[tCount++] = productions[i][j];

terminals[tCount] = '\0';

}
}

terminals[tCount++] = '$'; terminals[tCount] = '\0';

buildTable();

printTable();

char input[MAX];

printf("\nEnter a string to parse (end with $): ");

scanf("%s", input);

if (parseString(input))

printf("\nString accepted.\n");

else

printf("\nString rejected.\n");

return 0;

}
8. c program to implement shift reducer parser

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#define MAX 100

char input[MAX];

char stack[MAX];

int top = -1;

int ip = 0;

void push(char c) {

stack[++top] = c;

stack[top+1] = '\0';

}
void pop(int n) {

top -= n;

if (top < -1) top = -1;

stack[top+1] = '\0';

void printStep(const char *action) {

printf("Stack: %-20s Input: %-20s Action: %s\n", stack, input + ip, action);

int reduce() {

// Rule: E ? id

if (top >= 1 && stack[top] == 'd' && stack[top-1] == 'i') {

pop(2);

push('E');

printStep("Reduce: id ? E");

return 1;

// Rule: E ? (E)

if (top >= 2 && stack[top] == ')' && stack[top-2] == '(' && stack[top-1] == 'E') {

pop(3);

push('E');

printStep("Reduce: (E) ? E");

return 1;

// Rule: E ? E+E
if (top >= 2 && stack[top] == 'E' && stack[top-2] == 'E' && stack[top-1] == '+') {

pop(3);

push('E');

printStep("Reduce: E+E ? E");

return 1;

// Rule: E ? E*E

if (top >= 2 && stack[top] == 'E' && stack[top-2] == 'E' && stack[top-1] == '*') {

pop(3);

push('E');

printStep("Reduce: E*E ? E");

return 1;

return 0;

int main() {

printf("Enter the input string (use id for identifiers, end with $): ");

scanf("%s", input);

printf("\nSHIFT-REDUCE Parsing Process:\n");

while (input[ip] != '\0') {

push(input[ip++]);

printStep("Shift");
while (reduce());

if (top == 0 && stack[0] == 'E') {

printf("\nString Accepted!\n");

} else {

printf("\nString Rejected!\n");

return 0;

9. c program for intermediate code generation

#include <stdio.h>

#include <string.h>

#include <ctype.h>

int tempCount = 1;

char *newTemp() {

static char buffer[10];

sprintf(buffer, "t%d", tempCount++);

return buffer;
}

int precedence(char op) {

if (op == '*' || op == '/')

return 2;

if (op == '+' || op == '-')

return 1;

return 0;

void infixToPostfix(char infix[], char postfix[]) {

char stack[50];

int top = -1, k = 0;

for (int i = 0; i < strlen(infix); i++) {

char ch = infix[i];

if (isalnum(ch)) {

postfix[k++] = ch;

} else if (ch == '(') {

stack[++top] = ch;

} else if (ch == ')') {

while (top != -1 && stack[top] != '(')

postfix[k++] = stack[top--];

top--; // Pop '('

} else { // Operator

while (top != -1 && precedence(stack[top]) >= precedence(ch))

postfix[k++] = stack[top--];

stack[++top] = ch;

}
}

while (top != -1)

postfix[k++] = stack[top--];

postfix[k] = '\0';

void generateTAC(char postfix[]) {

char stack[50][10];

int top = -1;

for (int i = 0; i < strlen(postfix); i++) {

char ch = postfix[i];

if (isalnum(ch)) {

char op[2] = {ch, '\0'};

strcpy(stack[++top], op);

} else {

char op2[10], op1[10], result[10];

strcpy(op2, stack[top--]);

strcpy(op1, stack[top--]);

strcpy(result, newTemp());

printf("%s = %s %c %s\n", result, op1, ch, op2);

strcpy(stack[++top], result);

printf("Result stored in: %s\n", stack[top]);


}

int main() {

char infix[50], postfix[50];

printf("Enter an arithmetic expression (without spaces): ");

scanf("%s", infix);

infixToPostfix(infix, postfix);

printf("\nPostfix Expression: %s\n", postfix);

printf("\nThree Address Code (TAC):\n");

generateTAC(postfix);

return 0;

10. c program for final code generation

#include <stdio.h>
#include <string.h>

#include <ctype.h>

int tempCount = 1;

char *newTemp() {

static char buffer[10];

sprintf(buffer, "t%d", tempCount++);

return buffer;

int precedence(char op) {

if (op == '*' || op == '/') return 2;

if (op == '+' || op == '-') return 1;

return 0;

void infixToPostfix(char infix[], char postfix[]) {

char stack[50];

int top = -1, k = 0;

for (int i = 0; i < strlen(infix); i++) {

char ch = infix[i];

if (isalnum(ch)) {

postfix[k++] = ch;

} else if (ch == '(') {

stack[++top] = ch;

} else if (ch == ')') {

while (top != -1 && stack[top] != '(')


postfix[k++] = stack[top--];

top--;

} else {

while (top != -1 && precedence(stack[top]) >= precedence(ch))

postfix[k++] = stack[top--];

stack[++top] = ch;

while (top != -1)

postfix[k++] = stack[top--];

postfix[k] = '\0';

void generateTAC(char postfix[], char tac[][50], int *tacLines) {

char stack[50][10];

int top = -1;

for (int i = 0; i < strlen(postfix); i++) {

char ch = postfix[i];

if (isalnum(ch)) {

char op[2] = {ch, '\0'};

strcpy(stack[++top], op);

} else {

char op2[10], op1[10], temp[10];

strcpy(op2, stack[top--]);
strcpy(op1, stack[top--]);

strcpy(temp, newTemp());

sprintf(tac[*tacLines], "%s = %s %c %s", temp, op1, ch, op2);

(*tacLines)++;

strcpy(stack[++top], temp);

void generateFinalCode(char tac[][50], int tacLines) {

printf("\nFinal Code (Assembly-like):\n");

for (int i = 0; i < tacLines; i++) {

char lhs[10], op1[10], op2[10], optr;

sscanf(tac[i], "%s = %s %c %s", lhs, op1, &optr, op2);

printf("MOV R0, %s\n", op1);

switch(optr) {

case '+': printf("ADD R0, %s\n", op2); break;

case '-': printf("SUB R0, %s\n", op2); break;

case '*': printf("MUL R0, %s\n", op2); break;

case '/': printf("DIV R0, %s\n", op2); break;

printf("MOV %s, R0\n\n", lhs);

}
int main() {

char infix[50], postfix[50];

char tac[50][50];

int tacLines = 0;

printf("Enter arithmetic expression (e.g., a+b*c-d): ");

scanf("%s", infix);

infixToPostfix(infix, postfix);

printf("Postfix Expression: %s\n", postfix);

generateTAC(postfix, tac, &tacLines);

printf("\nThree Address Code (TAC):\n");

for (int i = 0; i < tacLines; i++)

printf("%s\n", tac[i]);

generateFinalCode(tac, tacLines);

return 0;

You might also like