0% found this document useful (0 votes)
13 views9 pages

Compiler Design

The document contains code for a predictive parser implemented in C, which processes input strings based on defined grammar rules. It includes functions for stack operations, parsing logic, and handling different grammar productions using a parsing table. The document also features examples of input strings and their expected acceptance or rejection by the parser.

Uploaded by

Swayam pani
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)
13 views9 pages

Compiler Design

The document contains code for a predictive parser implemented in C, which processes input strings based on defined grammar rules. It includes functions for stack operations, parsing logic, and handling different grammar productions using a parsing table. The document also features examples of input strings and their expected acceptance or rejection by the parser.

Uploaded by

Swayam pani
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/ 9

COMPILER DESIGN

Exercise 4

23BCE1526
SWAYAM PANI

Q1.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define ID 0
#define PLUS 1
#define MUL 2
#define LPAREN 3
#define RPAREN 4
#define END 5

#define E 0
#define E1 1
#define T 2
#define T1 3
#define F 4

const char *table[5][6] = {


/* id + * ( ) $ */
/*E*/ { "TQ", "", "", "TQ", "", "" },
/*Q*/ { "", "+TQ", "", "", "ε", "ε" },
/*T*/ { "FR", "", "", "FR", "", "" },
/*R*/ { "", "ε", "*FR", "", "ε", "ε" },
/*F*/ { "i", "", "", "(E)", "", "" }
};

typedef struct {
char data[1000];
int top;
} Stack;

void push(Stack *s, char c) {


s->data[++(s->top)] = c;
}

char pop(Stack *s) {


if (s->top == -1) return '\0';
return s->data[(s->top)--];
}

char peek(Stack *s) {


if (s->top == -1) return '\0';
return s->data[s->top];
}
int term_index(char c) {
if (c == 'i') return ID;
if (c == '+') return PLUS;
if (c == '*') return MUL;
if (c == '(') return LPAREN;
if (c == ')') return RPAREN;
if (c == '$') return END;
return -1;
}

int nonterm_index(char c) {
if (c == 'E') return E;
if (c == 'Q') return E1; // using Q for E'
if (c == 'T') return T;
if (c == 'R') return T1; // using R for T'
if (c == 'F') return F;
return -1;
}

int predictive_parse(const char *input) {


Stack stack;
stack.top = -1;

push(&stack, '$');
push(&stack, 'E');

int ip = 0;

while (1) {
char X = peek(&stack);
char a = input[ip];

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


return 1; // ACCEPT
}

if (isupper(X)) {
int row = nonterm_index(X);
int col = term_index(a);
if (row == -1 || col == -1) return 0;

const char *prod = table[row][col];


if (prod[0] == '\0') {
return 0; // no production => error
}

pop(&stack);

if (strcmp(prod, "ε") != 0) {

for (int i = strlen(prod) - 1; i >= 0; i--) {


push(&stack, prod[i]);
}
}
}
else { // Terminal
if (X == a) {
pop(&stack);
ip++;
} else {
return 0; // mismatch
}
}
}
}

int main() {
char input[100];

printf("Enter input string (use 'i' for id). Example: i+i*i+i\n");


scanf("%s", input);

strcat(input, "$");

if (predictive_parse(input))
printf("ACCEPTED\n");
else
printf("REJECTED\n");

return 0;
}

Output:
Q2
Code:
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define MAXSTACK 1000


#define MAXINPUT 1000

enum {NT_S = 0, NT_L = 1, NT_P = 2};

int term_index(char c) {
if (c == '(') return 0;
if (c == 'a') return 1;
if (c == ',') return 2;
if (c == ')') return 3;
if (c == '$') return 4;
return -1;
}

const char *table[3][5] = {


// '(' 'a' ',' ')' '$'
{ "(L)", "a", "", "", "" }, // S
{ "SP", "SP", "", "", "" }, // L (S P where P = L')
{ "", "", ",SP", "ε", "" } // P (L')
};

typedef struct {
char data[MAXSTACK];
int top;
} Stack;

void init(Stack *s) { s->top = -1; }


int empty(Stack *s) { return s->top == -1; }
void push(Stack *s, char c) { if (s->top < MAXSTACK-1) s->data[++(s->top)] = c; }
char pop(Stack *s) { if (s->top == -1) return '\0'; return s->data[(s->top)--]; }
char peek(Stack *s) { if (s->top == -1) return '\0'; return s->data[s->top]; }

void print_stack(Stack *s) {


// print top -> ... -> bottom
printf("Stack(top->...): ");
for (int i = s->top; i >= 0; --i) putchar(s->data[i]);
}

void normalize_input(const char *raw, char *out) {


int j = 0;
for (int i = 0; raw[i] != '\0'; ++i) {
char c = raw[i];
if (isspace((unsigned char)c)) continue;

if (c == 'a' || c == '(' || c == ')' || c == ',') {


out[j++] = c;
} else {

out[j++] = c;
}
}
out[j] = '\0';
}

int nonterm_row(char c) {
if (c == 'S') return NT_S;
if (c == 'L') return NT_L;
if (c == 'P') return NT_P;
return -1;
}

int predictive_parse(const char *input_raw) {


char in_norm[MAXINPUT];
normalize_input(input_raw, in_norm);

char input[MAXINPUT];
strcpy(input, in_norm);
strcat(input, "$");

Stack st;
init(&st);
push(&st, '$');
push(&st, 'S'); // start symbol

int ip = 0;

printf("Parsing input: %s\n", input);


printf("-----------------------------------------\n");
printf("Step | ");
printf("Stack | ");
printf("Input | ");
printf("Action\n");
printf("-----------------------------------------\n");

int step = 0;
while (1) {
step++;
printf("%4d | ", step);
print_stack(&st);
printf(" | %s", &input[ip]);

int cur_len = 0;
printf(" | ");

char X = peek(&st);
char a = input[ip];

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


printf("Both $ -> ACCEPT\n");
return 1;
}
if (X == 'S' || X == 'L' || X == 'P') {
int row = nonterm_row(X);
int col = term_index(a);
if (col == -1) {
printf("ERROR: unexpected input symbol '%c'\n", a);
return 0;
}
const char *prod = table[row][col];
if (prod == NULL || strlen(prod) == 0) {
printf("ERROR: no production for (%c, %c)\n", X, a);
return 0;
}

pop(&st); // remove non-terminal

if (strcmp(prod, "ε") != 0) {

for (int i = strlen(prod) - 1; i >= 0; --i) {


push(&st, prod[i]);
}
printf("%c -> %s\n", X, prod);
} else {
// epsilon production
printf("%c -> ε\n", X);
}
} else {

if (X == a) {
pop(&st);
ip++;
printf("match '%c'\n", a);
} else {
printf("ERROR: terminal mismatch: stack has '%c' but input has '%c'\n", X, a);
return 0;
}
}
}
}

int main() {
char line[512];

printf("Enter input string (allowed tokens: a ( ) , ). Example: (a,(a,a)) \n");


if (!fgets(line, sizeof(line), stdin)) return 0;
// strip newline
line[strcspn(line, "\n")] = '\0';

int res = predictive_parse(line);


printf("-----------------------------------------\n");
if (res) printf("Result: ACCEPTED\n");
else printf("Result: REJECTED\n");

return 0;
}
Output:
Q3.
Code:
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define MAXSTACK 1000

typedef struct {
char data[MAXSTACK];
int top;
} Stack;

void init(Stack *s) { s->top = -1; }


int empty(Stack *s) { return s->top == -1; }
void push(Stack *s, char c) { if (s->top < MAXSTACK-1) s->data[++(s->top)] = c; }
char pop(Stack *s) { if (s->top == -1) return '\0'; return s->data[(s->top)--]; }
char peek(Stack *s) { if (s->top == -1) return '\0'; return s->data[s->top]; }

int predictive_parse(const char *input) {


Stack st;
init(&st);
push(&st, '$');
push(&st, 'S');

int ip = 0;
char a = input[ip];

while (!empty(&st)) {
char X = peek(&st);

if (X == '$' && a == '$') return 1;

if (X == 'S') {
if (a == 'a') { // could be AB or D a
pop(&st);
// To handle "ab" lookahead
if (input[ip+1] == 'b') { // A -> ab case
push(&st, 'B'); push(&st, 'A');
} else { // "D a" case
push(&st, 'a'); push(&st, 'D');
}
} else if (a == 'c') {
pop(&st); push(&st, 'B'); push(&st, 'A');
} else if (a == 'f') {
pop(&st); push(&st, 'a'); push(&st, 'D');
} else return 0;
}
else if (X == 'A') {
if (a == 'a' && input[ip+1] == 'b') {
pop(&st); push(&st, 'b'); push(&st, 'a');
} else if (a == 'c') {
pop(&st); push(&st, 'c');
} else return 0;
}
else if (X == 'B') {
if (a == 'd') {
pop(&st); push(&st, 'C'); push(&st, 'd');
} else return 0;
}
else if (X == 'C') {
if (a == 'e') {
pop(&st); push(&st, 'C'); push(&st, 'e');
} else { pop(&st); } // ε
}
else if (X == 'D') {
if (a == 'f') {
pop(&st); push(&st, 'D'); push(&st, 'f');
} else { pop(&st); } // ε
}
else { // terminal
if (X == a) {
pop(&st); ip++; a = input[ip];
} else return 0;
}
}
return 0;
}

int main() {
char str1[] = "abdee$";
char str2[] = "efffba$";

printf("Testing abdee: %s\n", predictive_parse(str1) ? "ACCEPTED" : "REJECTED");


printf("Testing efffba: %s\n", predictive_parse(str2) ? "ACCEPTED" : "REJECTED");

return 0;
}

Output:

You might also like