0% found this document useful (0 votes)
3 views

ECS 653 (Programs)

The document contains five programs demonstrating various aspects of compiler design, including a lexical analyzer for IF statements and arithmetic expressions, NFA construction from regular expressions, DFA construction from NFA, and a shift-reduce parsing algorithm. Each program is implemented in C and includes functions for handling tokens, transitions, and parsing actions. The programs illustrate fundamental concepts in automata theory and parsing techniques.

Uploaded by

abhishekkri9988
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)
3 views

ECS 653 (Programs)

The document contains five programs demonstrating various aspects of compiler design, including a lexical analyzer for IF statements and arithmetic expressions, NFA construction from regular expressions, DFA construction from NFA, and a shift-reduce parsing algorithm. Each program is implemented in C and includes functions for handling tokens, transitions, and parsing actions. The programs illustrate fundamental concepts in automata theory and parsing techniques.

Uploaded by

abhishekkri9988
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/ 27

`Program 1:

Implementation of LEXICAL ANALYZER for IF STATEMENT


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

void checkKeyword(char *word) {


if (strcmp(word, "if") == 0) {
printf("Keyword: %s\n", word);
} else {
printf("Identifier: %s\n", word);
}
}

void lexicalAnalyzer(char *code) {


char word[100];
int i = 0, j = 0;

while (code[i] != '\0') {


if (isalpha(code[i])) {
word[j++] = code[i];
} else {
if (j != 0) {
word[j] = '\0';
checkKeyword(word);
j = 0;
}

// Single character tokens


if (code[i] == ' ' || code[i] == '\n' || code[i] == '\t') {
// Ignore whitespace

1
} else if (code[i] == '>' || code[i] == '<' || code[i] == '=' || code[i] == '!') {
if (code[i+1] == '=') {
printf("Operator: %c=\n", code[i]);
i++;
} else {
printf("Operator: %c\n", code[i]);
}
} else if (code[i] == '(' || code[i] == ')' || code[i] == '{' || code[i] == '}' || code[i] == ';') {
printf("Punctuation: %c\n", code[i]);
} else if (code[i] == '+' || code[i] == '-' || code[i] == '*' || code[i] == '/') {
printf("Operator: %c\n", code[i]);
}
}
i++;
}

// If any identifier is left


if (j != 0) {
word[j] = '\0';
checkKeyword(word);
}
}

int main() {
char code[200];

printf("Enter the IF statement:\n");


fgets(code, sizeof(code), stdin);

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


lexicalAnalyzer(code);

2
return 0;
}

Program 2:
Implementation of LEXICAL ANALYZER for ARITHMETIC
EXPRESSION
#include <stdio.h>
#include <ctype.h>
#include <string.h>

void analyze(char *expr) {


int i = 0;
char token[100];
int j = 0;

while (expr[i] != '\0') {


// Skip whitespace
if (expr[i] == ' ' || expr[i] == '\n' || expr[i] == '\t') {
i++;

3
continue;
}

// If it's a letter → start of an identifier


if (isalpha(expr[i])) {
j = 0;
while (isalnum(expr[i])) {
token[j++] = expr[i++];
}
token[j] = '\0';
printf("Identifier: %s\n", token);
}

// If it's a digit → start of a number


else if (isdigit(expr[i])) {
j = 0;
while (isdigit(expr[i])) {
token[j++] = expr[i++];
}
token[j] = '\0';
printf("Number: %s\n", token);
}

// If it's an operator or punctuation


else {
char ch = expr[i];
switch (ch) {
case '+': case '-': case '*': case '/': case '=':
printf("Operator: %c\n", ch);
break;
case '(': case ')': case ';':
printf("Punctuation: %c\n", ch);

4
break;
default:
printf("Unknown symbol: %c\n", ch);
}
i++;
}
}
}

int main() {
char input[200];

printf("Enter an arithmetic expression:\n");


fgets(input, sizeof(input), stdin);

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


analyze(input);

return 0;
}

5
Program 3: Construction of NFA from REGULAR
EXPRESSION
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 100

typedef struct State {


int id;
struct State *next1, *next2;
char symbol;
} State;

typedef struct {
State *start;
State *end;
} NFA;

int stateCount = 0;

State* createState(char symbol) {


State *s = (State*)malloc(sizeof(State));
s->id = stateCount++;
s->symbol = symbol;
s->next1 = s->next2 = NULL;
return s;
}

NFA createBasicNFA(char symbol) {


NFA nfa;
State *start = createState('\0');

6
State *end = createState('\0');
start->symbol = symbol;
start->next1 = end;
nfa.start = start;
nfa.end = end;
return nfa;
}

NFA concat(NFA nfa1, NFA nfa2) {


nfa1.end->symbol = '\0'; // ε transition
nfa1.end->next1 = nfa2.start;
NFA result = { nfa1.start, nfa2.end };
return result;
}

NFA alternate(NFA nfa1, NFA nfa2) {


State *start = createState('\0');
State *end = createState('\0');
start->next1 = nfa1.start;
start->next2 = nfa2.start;
nfa1.end->symbol = '\0';
nfa2.end->symbol = '\0';
nfa1.end->next1 = end;
nfa2.end->next1 = end;
NFA result = { start, end };
return result;
}

NFA kleeneStar(NFA nfa) {


State *start = createState('\0');
State *end = createState('\0');
start->next1 = nfa.start;

7
start->next2 = end;
nfa.end->symbol = '\0';
nfa.end->next1 = nfa.start;
nfa.end->next2 = end;
NFA result = { start, end };
return result;
}

NFA stack[MAX];
int top = -1;

void push(NFA nfa) {


stack[++top] = nfa;
}

NFA pop() {
return stack[top--];
}

void printNFA(State *state, int *visited) {


if (visited[state->id]) return;
visited[state->id] = 1;

if (state->next1) {
printf("State %d --[%c]--> State %d\n", state->id, state->symbol ? state->symbol : 'ε', state-
>next1->id);
printNFA(state->next1, visited);
}
if (state->next2) {
printf("State %d --[%c]--> State %d\n", state->id, state->symbol ? state->symbol : 'ε', state-
>next2->id);
printNFA(state->next2, visited);
}

8
}

int main() {
char postfix[100];
printf("Enter Regular Expression in Postfix: ");
scanf("%s", postfix);

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


char c = postfix[i];
if (c == '*') {
NFA nfa = pop();
push(kleeneStar(nfa));
} else if (c == '.') {
NFA nfa2 = pop();
NFA nfa1 = pop();
push(concat(nfa1, nfa2));
} else if (c == '|') {
NFA nfa2 = pop();
NFA nfa1 = pop();
push(alternate(nfa1, nfa2));
} else {
push(createBasicNFA(c));
}
}

NFA finalNFA = pop();

int visited[MAX] = {0};


printf("\n--- NFA Transitions ---\n");
printNFA(finalNFA.start, visited);

printf("Start State: %d\n", finalNFA.start->id);

9
printf("Final State: %d\n", finalNFA.end->id);

return 0;
}

Program 4:
Construction of DFA from NFA
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 20
#define SYMBOLS 2 // for 'a' and 'b'

char symbols[] = {'a', 'b'};

int nfa[MAX][SYMBOLS][MAX]; // nfa[state][symbol][next_state]


int nfa_epsilon[MAX][MAX]; // epsilon transitions

10
int nfa_states = 0;
int dfa_states = 0;

typedef struct {
int states[MAX];
int count;
} StateSet;

int isStateInSet(StateSet set, int state) {


for (int i = 0; i < set.count; i++)
if (set.states[i] == state) return 1;
return 0;
}

void addState(StateSet *set, int state) {


if (!isStateInSet(*set, state))
set->states[set->count++] = state;
}

void printSet(StateSet set) {


printf("{ ");
for (int i = 0; i < set.count; i++)
printf("q%d ", set.states[i]);
printf("}");
}

StateSet epsilonClosure(StateSet set) {


StateSet closure = set;
int changed = 1;
while (changed) {
changed = 0;
for (int i = 0; i < closure.count; i++) {

11
int s = closure.states[i];
for (int j = 0; j < nfa_states; j++) {
if (nfa_epsilon[s][j] && !isStateInSet(closure, j)) {
addState(&closure, j);
changed = 1;
}
}
}
}
return closure;
}

StateSet move(StateSet set, int symbol_index) {


StateSet result = { .count = 0 };
for (int i = 0; i < set.count; i++) {
int s = set.states[i];
for (int j = 0; j < nfa_states; j++) {
if (nfa[s][symbol_index][j]) {
addState(&result, j);
}
}
}
return result;
}

int areSetsEqual(StateSet a, StateSet b) {


if (a.count != b.count) return 0;
for (int i = 0; i < a.count; i++) {
if (!isStateInSet(b, a.states[i])) return 0;
}
return 1;
}

12
int findSetIndex(StateSet dfa[], int count, StateSet set) {
for (int i = 0; i < count; i++) {
if (areSetsEqual(dfa[i], set)) return i;
}
return -1;
}

void constructDFA() {
StateSet dfa[MAX];
int dfa_trans[MAX][SYMBOLS];
int marked[MAX] = {0};
int dfa_count = 0;

StateSet start = { .count = 1, .states = {0} };


dfa[0] = epsilonClosure(start);
dfa_count++;

int i = 0;
while (i < dfa_count) {
marked[i] = 1;
for (int s = 0; s < SYMBOLS; s++) {
StateSet temp = move(dfa[i], s);
StateSet closure = epsilonClosure(temp);
int idx = findSetIndex(dfa, dfa_count, closure);
if (idx == -1 && closure.count > 0) {
dfa[dfa_count] = closure;
dfa_trans[i][s] = dfa_count;
dfa_count++;
} else {
dfa_trans[i][s] = idx;
}

13
}
i++;
}

printf("\nDFA Transition Table:\n");


printf("State\t");
for (int s = 0; s < SYMBOLS; s++)
printf("%c\t", symbols[s]);
printf("\n");

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


printSet(dfa[i]);
printf("\t");
for (int s = 0; s < SYMBOLS; s++) {
if (dfa_trans[i][s] == -1)
printf("-\t");
else {
printf("S%d\t", dfa_trans[i][s]);
}
}
printf("\n");
}
}

int main() {
printf("Enter number of NFA states: ");
scanf("%d", &nfa_states);

printf("Enter transitions for NFA (for each state and input symbol a/b):\n");
for (int i = 0; i < nfa_states; i++) {
for (int s = 0; s < SYMBOLS; s++) {
int k, t;

14
printf("From q%d on '%c', number of transitions: ", i, symbols[s]);
scanf("%d", &k);
printf("Enter destination states: ");
for (int j = 0; j < k; j++) {
scanf("%d", &t);
nfa[i][s][t] = 1;
}
}
}

printf("Enter ε-transitions (from qx to qy): Enter -1 -1 to end\n");


while (1) {
int from, to;
scanf("%d %d", &from, &to);
if (from == -1 && to == -1) break;
nfa_epsilon[from][to] = 1;
}

constructDFA();
return 0;
}

15
Input:

Output:

Program 5:
Implementation of SHIFT REDUCE PARSING ALGORITHM
#include <stdio.h>
#include <string.h>

16
char input[100];
char stack[100];
int top = -1;
int i = 0;

void push(char symbol) {


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

void pop() {
if (top >= 0)
top--;
stack[top + 1] = '\0';
}

void printStack() {
for (int j = 0; j <= top; j++)
printf("%c", stack[j]);
}

void reduce() {
if (top >= 2) {
// E → E+E or E*E
if ((stack[top] == 'E') &&
(stack[top - 1] == '+' || stack[top - 1] == '*') &&
(stack[top - 2] == 'E')) {
pop();
pop();
pop();
push('E');
printf("REDUCE E → E%cE\n", stack[top]);

17
}
}
// E → (E)
if (top >= 2 && stack[top] == ')' && stack[top - 1] == 'E' && stack[top - 2] == '(') {
pop();
pop();
pop();
push('E');
printf("REDUCE E → (E)\n");
}

// E → id
if (top >= 1 && stack[top] == 'd' && stack[top - 1] == 'i') {
pop(); // d
pop(); // i
push('E');
printf("REDUCE E → id\n");
}
}

void shift() {
printf("SHIFT: %c\n", input[i]);
push(input[i]);
i++;
}

int main() {
printf("Enter the input string (e.g., id+id*id): ");
scanf("%s", input);

strcat(input, "$"); // $ is end marker

18
printf("\nSTACK\t\tINPUT\t\tACTION\n");
printf("-----\t\t-----\t\t------\n");

while (i < strlen(input)) {


printStack();
printf("\t\t%s\t\t", &input[i]);
shift();
reduce(); // Try reducing after every shift
printf("\n");
}

// Final reductions (if possible)


while (top != 0 || stack[top] != 'E') {
printStack();
printf("\t\t%s\t\t", &input[i]);
reduce();
printf("\n");
}

// Final check
if (stack[0] == 'E' && stack[1] == '\0')
printf("Parsing successful: input accepted.\n");
else
printf("Parsing failed: input rejected.\n");

return 0;
}

Input:

19
Output:

Program 6:
Implementation of OPERATOR PRECEDENCE PARSER
#include <stdio.h>
#include <string.h>

char stack[20], input[20];


int top = 0, i = 0;

int getPrecedence(char symbol) {


switch (symbol) {
case '+': return 1;
case '*': return 2;
case 'i': return 3;
default: return 0;
}
}

20
void shift() {
stack[++top] = input[i++];
stack[top + 1] = '\0';
}

void reduce() {
if (stack[top] == 'i') {
stack[top] = 'E'; // id to E
} else if (stack[top] == 'E' && (stack[top - 1] == '+' || stack[top - 1] == '*') && stack[top - 2] == 'E')
{
top -= 2;
stack[top] = 'E'; // E+E or E*E to E
}
}

int main() {
printf("Enter the input (e.g., i+i*i): ");
scanf("%s", input);
strcat(input, "$");

stack[0] = '$';
top = 0;

printf("\nStack\tInput\tAction\n");
while (i < strlen(input)) {
printf("%s\t%s\t", stack, &input[i]);

if (getPrecedence(stack[top]) >= getPrecedence(input[i])) {


reduce();
printf("Reduce\n");
} else {

21
shift();
printf("Shift\n");
}
}

printf("\nFinal stack: %s\n", stack);


if (strcmp(stack, "$E") == 0)
printf("Accepted\n");
else
printf("Rejected\n");
return 0;
}

Input:

Output:

Program 7:
Implementation of RECURSIVE DESCENT PARSER

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

char input[100];
int i = 0;

void E();
void EPrime();
void T();
void TPrime();
void F();

void match(char expected) {


if (input[i] == expected)
i++;
else {
printf("Error at '%c'\n", input[i]);
exit(1);
}
}

void E() {
T();
EPrime();
}

void EPrime() {
if (input[i] == '+') {
i++;
T();
EPrime();
}

23
}

void T() {
F();
TPrime();
}

void TPrime() {
if (input[i] == '*') {
i++;
F();
TPrime();
}
}

void F() {
if (input[i] == '(') {
i++;
E();
match(')');
} else if (input[i] == 'i') {
i++;
} else {
printf("Invalid symbol '%c'\n", input[i]);
exit(1);
}
}

int main() {
printf("Enter the expression: ");
scanf("%s", input);
E();

24
if (input[i] == '\0')
printf("Accepted\n");
else
printf("Rejected at %c\n", input[i]);
return 0;
}

Program 8:
Implementation of CODE OPTIMIZATION TECHNIQUES
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
char expr[100];
int a, b, res;
char op;

printf("Enter a simple expression (e.g., 3+5): ");


scanf("%s", expr);

sscanf(expr, "%d%c%d", &a, &op, &b);

switch (op) {
case '+': res = a + b; break;
case '*': res = a * b; break;
case '-': res = a - b; break;
case '/': res = a / b; break;
default: printf("Unsupported op\n"); exit(1);

25
}

printf("Original: %s\n", expr);


printf("Optimized (constant folding): %d\n", res);

// Strength reduction: x * 2 => x + x


if (op == '*' && b == 2)
printf("Optimized (strength reduction): %d + %d = %d\n", a, a, a + a);

return 0;
}

Program 9:
Implementation of CODE GENERATOR
#include <stdio.h>
int main() {
printf("Expression: a = b + c * d\n\n");
// Three Address Code
printf("=== Three Address Code ===\n");
printf("t1 = c * d\n");
printf("t2 = b + t1\n");
printf("a = t2\n\n");
// Postfix Code
printf("=== Postfix Code ===\n");
printf("b c d * + a =\n\n");
// Intermediate Code (Quadruples)
printf("=== Intermediate Code (Quadruples) ===\n");

26
printf("Op\tArg1\tArg2\tResult\n");
printf("*,\tc,\td,\tt1\n");
printf("+,\tb,\tt1,\tt2\n");
printf("=,\tt2,\t-,\ta\n\n");
// Assembly-like Code
printf("=== Assembly-like Code ===\n");
printf("MOV R1, c\n");
printf("MUL R1, d\n");
printf("MOV R2, b\n");
printf("ADD R2, R1\n");
printf("MOV a, R2\n");
return 0;
}

27

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy