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

Cd final manual

The document outlines multiple experiments related to programming in C, focusing on lexical analysis, parsing techniques, and grammar computations. Each experiment includes an aim, description, and a sample program demonstrating the implementation of concepts like token identification, lexical analyzers, recursive descent parsing, and computing First and Follow sets. The document serves as a comprehensive guide for students learning about compiler construction and parsing methodologies.
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

Cd final manual

The document outlines multiple experiments related to programming in C, focusing on lexical analysis, parsing techniques, and grammar computations. Each experiment includes an aim, description, and a sample program demonstrating the implementation of concepts like token identification, lexical analyzers, recursive descent parsing, and computing First and Follow sets. The document serves as a comprehensive guide for students learning about compiler construction and parsing methodologies.
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/ 34

DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

EXPERIMENT-1
Write a C program to identify different types of Tokens in a given Program.
AIM:
Write a C program to identify different types of Tokens in a given Program.
DESCRIPTION:
In a C program, tokens can be categorized into keywords, identifiers, constants, operators, and
special symbols. Utilizing the `ctype.h` library for character classification, you can scan through
the input to identify and print the respective token types. Keywords, like "if" or "while," are
recognized by string comparison. Identifiers, numbers, and operators can be identified using
functions like `isalpha()`, `isdigit()`, and specific character checks. Special symbols, such as
parentheses or semicolons, are identified individually. The program employs a straightforward
approach, offering a foundational understanding of token recognition in a C program.

PROGRAM:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main() {
char program[1000];
printf("Enter a program:\n");
fgets(program, sizeof(program), stdin);
char *token = strtok(program, "\t\n(){};,\n ");
while (token != NULL) {
if (isdigit(token[0])) {
printf("Number: %s\n", token);
} else if (isalpha(token[0]) || token[0] == '_') {
if (strcmp(token, "int") == 0 || strcmp(token, "float") == 0 || strcmp(token, "char") == 0) {
printf("Keyword: %s\n", token);
} else {
printf("Identifier: %s\n", token);
}

Page 1
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

} else {
printf("Operator/Separator: %s\n", token);
}
token = strtok(NULL, "\t\n(){};, ");
}
return 0;
}
OUTPUT:

Page 2
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

EXPERIMENT-2
Write a Lex Program to implement a Lexical Analyzer using Lex tool.
AIM:
Write a Lex Program to implement a Lexical Analyzer using Lex tool.
DESCRIPTION:
Create a Lex program to build a Lexical Analyzer. Define token patterns using regular
expressions to recognize keywords, identifiers, numbers, and operators. Associate actions with
patterns to output corresponding tokens. Utilize the Lex-generated C code to compile the
analyzer. Employ the Lex tool's efficiency in handling pattern recognition and tokenization.
Implement error handling mechanisms for unrecognized input. The analyzer scans the input
source code, breaking it into tokens for further processing. This Lex-based approach streamlines
lexical analysis, a crucial phase in compiler construction. Execute the Lex program to generate a
C code that serves as the foundation for the Lexical Analyzer's functionality.

PROGRAM:
%{
int COMMENT=0;
%}
identifier [a-zA-Z][a-zA-Z0-9]*
%%
#.* {printf("\n%s is a preprocessor directive",yytext);}
int | float | char | double | while | for | struct | typedef | do | if | break | continue | void | switch |
return | else | goto
{printf("\n\t%s is a keyword",yytext);}
"/*" {COMMENT=1;}{printf("\n\t %s is a COMMENT",yytext);}
{identifier}\( {if(!COMMENT)printf("\nFUNCTION \n\t%s",yytext);}
\{ {if(!COMMENT)printf("\n BLOCK BEGINS");}
\} {if(!COMMENT)printf("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 %s is a NUMBER ",yytext);}
\)(\:)? {if(!COMMENT)printf("\n\t");ECHO;printf("\n");}

Page 3
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

\( 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)
{
FILE *file;
file=fopen("var.c","r");
if(!file)
{
printf("could not open the file");
exit(0);
}
yyin=file;
yylex();
printf("\n");
return(0);
}
int yywrap()
{
return(1);
}
INPUT:
#include<stdio.h>
#include<conio.h>
void main()
{
int a,b,c;

Page 4
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

a=1;
b=2;
c=a+b;
printf("Sum:%d",c);
}
OUTPUT:
#include<stdio.h> is a preprocessor directive
#include<conio.h> is a preprocessor directive
void is a keyword
FUNCTION main()
BLOCK BEGINS
int is a keyword
a is an IDENTIFIER
b is an IDENTIFIER
c is an IDENTIFIER
a is an IDENTIFIER
= is an ASSIGNMENT OPERATOR
1 is a NUMBER
b is an IDENTIFIER
= is an ASSIGNMENT OPERATOR
2 is a NUMBER
c is an IDENTIFIER
= is an ASSIGNMENT OPERATOR
a is an IDENTIFIER
+ is an ASSIGNMENT OPERATOR
b is an IDENTIFIER
printf is an IDENTIFIER
"Sum:%d" is a STRING
BLOCK ENDS

Page 5
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

EXPERIMENT-3
Write a C program to Simulate Lexical Analyzer to validating a given input String.
AIM:
Write a C program to Simulate Lexical Analyzer to validating a given input String.
DESCRIPTION:
In C, simulate a Lexical Analyzer to validate an input string. Define regular expressions
corresponding to token patterns such as keywords and identifiers. Employ a state machine to
transition through different token states. Utilize the `yylex()` function to initiate the lexical
analysis. Output the recognized tokens or an error message based on the analysis. The simulation
involves tokenizing the input string and confirming its adherence to the defined grammar. By
mimicking Lex's functionality in C, this program acts as a simple yet effective tool for validating
input strings against lexical rules. Execute the program to observe the lexical analysis results for
a given input string.
PROGRAM:
#include<stdio.h>
#include<string.h>
void main(){
char a[80];
int i, flag=0;
printf("\nEnter String:");
fgets(a,sizeof(a),stdin);
a[strcspn(a,"\n")]='\0';
if (strlen(a)>255){
flag=1;
}else if ((a[0]>='a'&&a[0]<='z')||(a[0]>='A'&&a[0]<='Z')){
if (a[1]=='+'||a[1]=='-'||a[1]=='*'||a[1]=='/'||a[1]=='%'){
if ((a[2]>='a'&&a[2]<='z')||(a[2]>='A'&&a[2]<='Z')||a[2]=="_"){
flag=0;

Page 6
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

}
}else{
flag=1;
}
if (flag==0){
printf("\n%s is a valid Operator...",a);
}else{
printf("\n%s is an invalid Operator...",a);
}
}

OUTPUT:

Page 7
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

EXPERIMENT-4
Write a C program to implement the Brute force technique of Top down Parsing.
AIM:
Write a C program to implement the Brute force technique of Top down Parsing.
DESCRIPTION:
Create a C program to implement the brute-force technique of top-down parsing. Use recursive
functions to mimic the production rules of the grammar. Apply a trial-and-error approach,
attempting various rule combinations until a match is found. Implement error-handling
mechanisms for parsing failures. Develop functions for each non-terminal symbol in the
grammar. Utilize backtracking to explore alternative parsing paths. This approach provides a
straightforward but exhaustive method for parsing input based on a given grammar. Execute the
program to observe the brute-force top-down parsing in action, handling diverse input scenarios.

PROGRAM:
#include <stdio.h>
#include <ctype.h>
int parseExpression(char *expr, int *index) {
int result = parseOperand(expr, index);
while (expr[*index] == '+' || expr[*index] == '-') {
char op = expr[(*index)++];
int operand = parseOperand(expr, index);
if (op == '+')
result += operand;
else if (op == '-')
result -= operand;
}
return result;
}

int parseOperand(char *expr, int *index) {


int operand = 0;

Page 8
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

while (isdigit(expr[*index])) {
operand = operand * 10 + (expr[(*index)++] - '0');
}
return operand;
}
int main() {
char expr[100];
printf("Enter an arithmetic expression: ");
scanf("%s", expr);
int index = 0;
int result = parseExpression(expr, &index);
printf("Parsed expression steps and result:\n");
printf("Step 1: Expression: %s\n", expr);
printf("Step 2: Parsing and evaluating the expression...\n");
printf("Step 3: Result: %d\n", result);
return 0;
}
OUTPUT:

Page 9
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

EXPERIMENT-5
Write a C program to implement a Recursive Descent Parser.
AIM:
Write a C program to implement a Recursive Descent Parser.
DESCRIPTION:
A Recursive Descent Parser is a top-down parsing technique where each non-terminal in the
grammar is associated with a parsing function. These functions recursively call each other to
traverse and validate the input based on the grammar rules. The main function initiates the
parsing process, and each parsing function corresponds to a non-terminal in the grammar. The
parser typically matches tokens, handles production rules, and performs error checking.
Recursive Descent Parsers are easy to implement but may require careful consideration to avoid
left recursion and ambiguity. They are widely used in simple language processors and compilers.
PROGRAM:
#include <stdio.h>
#include <stdbool.h>
char input[100];
int index = 0;
void match(char c) {
if (input[index] == c) {
printf("Matched %c\n", c);
index++;
} else {
printf("Error: Expected %c, but found %c\n", c, input[index]);
}
}
void F();
void T();

void E();
void F() {
printf("F -> ");

Page 10
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

if (input[index] == 'a') {
printf("'a'\n");
match('a');
} else if (input[index] == '(') {
printf("'('\n");
match('(');
E();
printf("F -> ')'\n");
match(')');
} else {
printf("Error: Invalid token %c\n", input[index]);
}
}
void T() {
printf("T -> ");
F();
if (input[index] == '*') {
printf("T -> '*'\n");
match('*');
F();
}
}
void E() {
printf("E -> ");

T();
if (input[index] == '+') {
printf("E -> '+'\n");
match('+');

Page 11
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

T();
}
}
int main() {
printf("Enter an expression: ");
scanf("%s", input);
E();
if (input[index] == '\0')
printf("Parsing successful: Valid expression\n");
else
printf("Parsing failed: Invalid expression\n");
return 0;
}
OUTPUT:

Page 12
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

EXPERIMENT-6
Write C program to compute the First and Follow Sets for the given Grammar.
AIM:
Write C program to compute the First and Follow Sets for the given Grammar.
DESCRIPTION:
Computing First and Follow Sets involves traversing the grammar rules to identify the first set of
symbols a non-terminal can produce and the symbols that can immediately follow it. A C
program for this task would iterate through the grammar rules, updating First and Follow sets
accordingly. It would handle epsilon productions and dependencies between symbols. The
program would include functions for calculating First and Follow sets for each non-terminal,
with appropriate data structures to store the sets. Utilizing recursion and iteration, the program
systematically analyzes the grammar to produce accurate sets. Finally, it prints or outputs the
computed First and Follow sets for each non-terminal.
PROGRAM:
#include <stdio.h>
#include <ctype.h>
void follow(char c);
void findfirst(char c, int q1, int q2);
void followfirst(char c, int c1, int c2);
int count, n = 0, m = 0, k, e ,i ,j,kay,lark;
char calc_first[10][100], calc_follow[10][100], production[10][10], f[10], first[10];
int main() {
int jm = 0, km = 0;
count = 0;
printf("Enter the number of production rules: ");
scanf("%d", &count);
printf("Enter the production rules one by one:\n");
for (i = 0; i < count; i++) {
scanf("%s", production[i]);
}
int done[count],ptr = -1;

Page 13
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

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


for (kay = 0; kay < 100; kay++) {
calc_first[k][kay] = '!';
}}
for (k = 0; k < count; k++) {
char c = production[k][0];
int point1 = k, point2 = 0, xxx = 0;
for (kay = 0; kay <= ptr; kay++) {
if (c == done[kay]) {
xxx = 1;
break;
}}
if (xxx == 1) {
continue;
}
findfirst(c, 0, 0);
ptr += 1;
done[ptr] = c;
printf("\n First(%c) = { ", c);
calc_first[point1][point2++] = c;
for (i = 0 + jm; i < n; i++) {
int chk = 0;
for (lark = 0; lark < point2; lark++) {
if (first[i] == calc_first[point1][lark]) {
chk = 1;
break;
}}
if (chk == 0) {
printf("%c, ", first[i]);

Page 14
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

calc_first[point1][point2++] = first[i];
}}
printf("}\n");
jm = n;
}
printf("\n-----------------------------------------------\n\n");
int donee[count], ptr2 = -1;
int land = 0, point1 = 0;
for (e = 0; e < count; e++) {
char ck = production[e][0];
int point2 = 0, xxx = 0;
for (kay = 0; kay <= ptr2; kay++) {
if (ck == donee[kay]) {
xxx = 1;
break;
}}
if (xxx == 1) {
continue;
}
land += 1;
follow(ck);
ptr2 += 1;
donee[ptr2] = ck;
printf(" Follow(%c) = { ", ck);
calc_follow[point1][point2++] = ck;
for (i = 0 + km; i < m; i++) {
int chk = 0;
for (lark = 0; lark < point2; lark++) {
if (f[i] == calc_follow[point1][lark]) {

Page 15
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

chk = 1;
break;
}}
if (chk == 0) {
printf("%c, ", f[i]);
calc_follow[point1][point2++] = f[i];
}}
printf(" }\n\n");
km = m;
point1++;
}
return 0;
}
void follow(char c) {
if (production[0][0] == c) {
f[m++] = '$';
}
for (i = 0; i < count; i++) {
for (j = 2; production[i][j] != '\0'; j++) {
if (production[i][j] == c) {
if (production[i][j + 1] != '\0') {
followfirst(production[i][j + 1], i, (j + 2));
}
if (production[i][j + 1] == '\0' && c != production[i][0]) {
follow(production[i][0]);
}}}}}
void findfirst(char c, int q1, int q2) {
if (!(isupper(c))) {
first[n++] = c;

Page 16
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

}
for (j = 0; j < count; j++) {
if (production[j][0] == c) {
if (production[j][2] == '#') {
if (production[q1][q2] == '\0') {
first[n++] = '#';
} else if (production[q1][q2] != '\0' && (q1 != 0 || q2 != 0)) {
findfirst(production[q1][q2], q1, (q2 + 1));
} else {
first[n++] = '#';
}
} else if (!isupper(production[j][2])) {

first[n++] = production[j][2];
} else {
findfirst(production[j][2], j, 3);
}}}}
void followfirst(char c, int c1, int c2) {
if (!(isupper(c))) {
f[m++] = c;
} else {
int i = 0, j = 1;
for (i = 0; i < count; i++) {
if (calc_first[i][0] == c) {
break;
}}
while (calc_first[i][j] != '!') {
if (calc_first[i][j] != '#') {
f[m++] = calc_first[i][j];

Page 17
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

} else {
if (production[c1][c2] == '\0') {
follow(production[c1][0]);
} else {
followfirst(production[c1][c2], c1, c2 + 1);
}}
j++;}}}
OUTPUT:

Page 18
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

EXPERIMENT-7
Write a C program for eliminating the left recursion and left factoring of a given grammar.
AIM:
Write a C program for eliminating the left recursion and left factoring of a given grammar.
DESCRIPTION:
To eliminate left recursion and left factoring in a given grammar, a C program can be designed
as follows. Iterate through the production rules, identifying and handling left recursion by
creating new non-terminals. Implement left factoring by finding common prefixes and
refactoring the rules. The program updates the grammar accordingly, printing the modified
grammar rules. It ensures the modified grammar maintains its equivalence to the original. The
code utilizes string manipulation functions to perform these transformations. The elimination
process improves the grammar's compatibility with predictive parsing and reduces ambiguity.
Execute the program to observe the transformed, non-left-recursive, and non-left-factored
grammar.
PROGRAM:
#include <stdio.h>
#include <string.h>
#define SIZE 20
int main() {
char production[SIZE], alpha[SIZE], beta[SIZE], modifiedProduction[SIZE],
newProduction[SIZE];
int nonTerminal, i, j, k = 0, index = 3, pos;
printf("Enter the Production: ");
scanf("%s", production);
nonTerminal = production[0];
if (nonTerminal == production[index]) {
for (i = ++index, j = 0; production[i] != '|'; i++, j++) {
alpha[j] = production[i];
if (production[i + 1] == 0) {
printf("This Grammar CAN'T BE REDUCED.\n");
return 0;
}}

Page 19
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

alpha[j] = '\0';
if (production[++i] != 0) {
for (j = i, i = 0; production[j] != '\0'; i++, j++) {
beta[i] = production[j];
}
beta[i] = '\0';
printf("\nGrammar Without Left Recursion: \n\n");
printf(" %c->%s%c'\n", nonTerminal, beta, nonTerminal);
printf(" %c'->%s%c'|#\n", nonTerminal, alpha, nonTerminal);
} else {
printf("This Grammar CAN'T be REDUCED.\n");
}
} else {
printf("\nThis Grammar is not LEFT RECURSIVE.\n");
}
printf("\nEnter Production: A->");
scanf("%s", production);
char part1[SIZE], part2[SIZE];
j = 0;
for (i = 0; production[i] != '|'; i++, j++) {
part1[j] = production[i];
}
part1[j] = '\0';
for (j = ++i, i = 0; production[j] != '\0'; j++, i++) {
part2[i] = production[j];
}
part2[i] = '\0';
k = 0;
for (i = 0; i < strlen(part1) || i < strlen(part2); i++) {

Page 20
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

if (part1[i] == part2[i]) {
modifiedProduction[k] = part1[i];
k++;
pos = i + 1;
}}
for (i = pos, j = 0; part1[i] != '\0'; i++, j++) {
newProduction[j] = part1[i];
}
newProduction[j++] = '|';
for (i = pos; part2[i] != '\0'; i++, j++) {
newProduction[j] = part2[i];
}
modifiedProduction[k] = 'X';
modifiedProduction[++k] = '\0';
newProduction[j] = '\0';
printf("\nGrammar Without Left Factoring: \n");
printf(" A->%s", modifiedProduction);
printf("\n X->%s\n", newProduction);
return 0;
}

Page 21
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

OUTPUT:

Page 22
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

EXPERIMENT-8
Write a C program to check the validity of input string using Predictive Parser.
AIM:
Write a C program to check the validity of input string using Predictive Parser.
DESCRIPTION:
A C program for checking the validity of an input string using a Predictive Parser involves
initializing a parsing table, defining production rules, and implementing a stack-based parsing
process. The program reads the input string and verifies its validity by comparing each symbol
against the parsing table entries. Employing a stack, the parser ensures correct derivation of the
input string from the grammar. Error handling mechanisms are implemented for invalid input,
providing feedback on parsing success or failure. Execution of the program demonstrates the
effectiveness of the predictive parser in validating input strings against the specified grammar.
PROGRAM:
#include <stdio.h>
#include <ctype.h>
#define ID 0
#define CONST 1
#define MULOP 2
#define ADDOP 3
#define OP 4
#define CP 5
#define ERR 6
#define COL 7
#define SIZE 50
char lexbuff[SIZE];
int lookahead = 0;
int parser();
int E();
int T();
int EPRIME();
int TPRIME();

Page 23
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

int F();
int lexer();
int main() {
printf("Enter the string: ");
gets(lexbuff); // Note: gets is not recommended, consider using fgets
parser();
return 0;
}
int parser() {
if (E()) printf("Valid string\n");
else printf("Invalid string\n");
return 0;
}
int E() {
if (T()) {
if (EPRIME()) return 1;
else return 0;
} else return 0;
}
int T() {
if (F()) {

if (TPRIME()) return 1;
else return 0;

} else return 0;
}
int EPRIME() {
int token = lexer();

Page 24
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

if (token == ADDOP) {
lookahead++;
if (T()) {
if (EPRIME()) return 1;
else return 0;
} else return 0;
} else return 1;
}
int TPRIME() {
int token = lexer();
if (token == MULOP) {
lookahead++;
if (F()) {
if (TPRIME()) return 1;
else return 0;
} else return 0;
} else return 1;
}
int F() {
int token = lexer();
if (token == ID) return 1;
else {
if (token == OP) {
if (E()) {
if (token == CP) return 1;
else return 0;
} else return 0;
} else return 0;
}

Page 25
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

}
int lexer() {
if (lexbuff[lookahead] != '\0') {
while (lexbuff[lookahead] == '\t') lookahead++;
if (isalpha(lexbuff[lookahead])) {
while (isalnum(lexbuff[lookahead])) lookahead++;
return ID;
} else {
if (isdigit(lexbuff[lookahead])) {
while (isdigit(lexbuff[lookahead])) lookahead++;
return CONST;
} else {
if (lexbuff[lookahead] == '+') return ADDOP;
else {
if (lexbuff[lookahead] == '*') return MULOP;
else {
if (lexbuff[lookahead] == '(') {
lookahead++;
return OP;
} else {
if (lexbuff[lookahead] == ')') return CP;
else return ERR;
}}}}
} else return COL;
}

Page 26
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

OUTPUT:

Page 27
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

EXPERIMENT-9
Write a C program for implementation of LR parsing algorithm to accept a given input
string.
AIM:
Write a C program for implementation of LR parsing algorithm to accept a given input
string.
DESCRIPTION:
Implementing an LR parsing algorithm in a C program involves constructing LR parsing tables,
initializing a stack, and defining actions for shifts and reductions. The program reads an input
string and processes it using the LR parser, updating the stack based on transitions in the parsing
table. It handles conflicts and errors, providing detailed feedback on the validity of the input
string. The LR parsing algorithm efficiently handles a broad class of grammars, making it
suitable for practical compiler implementations. Running the program demonstrates its capability
to accept or reject a given input string according to the LR parsing rules.
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int z = 0, i = 0, j = 0, c = 0;
char a[16], ac[20], stk[15], act[10];
void check() {
strcpy(ac, "REDUCE TO E -> ");
for (z = 0; z < c; z++) {
if (stk[z] == 'e') {
printf("%se", ac);
stk[z] = 'E';
stk[z + 1] = '\0';
printf("\n$%s\t%s$\t", stk, a);
}
}
for (z = 0; z < c - 2; z++) {

Page 28
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

if (stk[z] == 'a' && stk[z + 1] == 'E' && stk[z + 2] == 'b') {


printf("%saEb", ac);
stk[z] = 'E';
stk[z + 1] = '\0';
stk[z + 2] = '\0';
printf("\n$%s\t%s$\t", stk, a);
i = i - 2;
}
}
for (z = 0; z < c - 2; z++) {
if (stk[z] == 'c' && stk[z + 1] == 'E' && stk[z + 2] == 'd') {
printf("%scEd", ac);
stk[z] = 'E';
stk[z + 1] = '\0';
stk[z + 2] = '\0';
printf("\n$%s\t%s$\t", stk, a);
i = i - 2;
}
}
return;
}
int main() {
printf("GRAMMAR is -\nE->aEb \nE->cEd \nE->e\n");
printf("Enter the input string: ");
scanf("%s", a);
c = strlen(a);
strcpy(act, "SHIFT");
printf("\nstack \t input \t action\n");
printf("$\t%s$\t", a);

Page 29
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

for (i = 0, j = 0; j < c; i++, j++) {


printf("%s", act);
stk[i] = a[j];
stk[i + 1] = '\0';
a[j] = ' ';
printf("\n$%s\t%s$\t", stk, a);
check();
}
check();
if (stk[0] == 'E' && stk[1] == '\0')
printf("Accept\n");
else
printf("Reject\n");
}

OUTPUT:

Page 30
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

EXPERIMENT-10
Write a C program for implementation of a Shift Reduce Parser using Stack Data
Structure to accept a given input string of a given grammar.
AIM:
Write a C program for implementation of a Shift Reduce Parser using Stack Data
Structure to accept a given input string of a given grammar.
DESCRIPTION:
To create a Shift-Reduce Parser in C for accepting an input string based on a given grammar,
you'd design a program as follows:
1. Initialize a stack and a parsing table for shift and reduce actions.
2. Read the input string and tokenize it.
3. Use the stack to simulate the parser's state transitions.
4. Apply shift and reduce actions according to the parsing table.
5. Handle conflicts and errors through appropriate error recovery strategies.
6. Implement reduction based on grammar rules and pop the stack.
7. Continue shifting and reducing until the input is parsed or an error is detected.
8. Output whether the input string is accepted or rejected.
9. This Shift-Reduce Parser is suitable for handling a wide range of grammars, making it
practical for parsing real-world languages.
10. Execute the program to observe its effectiveness in accepting or rejecting input strings based
on the specified grammar rules.
PROGRAM:
#include <stdio.h>
#include <string.h>
struct ProductionRule{
char left[10];
char right[10];
};
int main() {
char input[20], stack[50], temp[50], ch[2], *token1, *token2, *substring;

Page 31
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

int i, j,k, stack_length, substring_length, stack_top, rule_count = 0;


struct ProductionRule rules[10];
stack[0] = '\0';
printf("\nEnter the number of production rules: ");
scanf("%d", &rule_count);
printf("\nEnter the production rules (in the form 'left->right'): \n");
for (i = 0; i < rule_count; i++) {
scanf("%s", temp);
token1 = strtok(temp, "->");
token2 = strtok(NULL, "->");
strcpy(rules[i].left, token1);
strcpy(rules[i].right, token2);
}
printf("\nEnter the input string: ");
scanf("%s", input);
i = 0;
while (1) {
if (i < strlen(input)) {
ch[0] = input[i];
ch[1] = '\0';
i++;
strcat(stack, ch);
printf("%s\t", stack);
for (k = i; k < strlen(input); k++) {

printf("%c", input[k]);
}
printf("\tShift %s\n", ch);
}

Page 32
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

for (j = 0; j < rule_count; j++) {


substring = strstr(stack, rules[j].right);
if (substring != NULL) {
stack_length = strlen(stack);
substring_length = strlen(substring);
stack_top = stack_length - substring_length;
stack[stack_top] = '\0';
strcat(stack, rules[j].left);
printf("%s\t", stack);
for (k = i; k < strlen(input); k++) {
printf("%c", input[k]);
}
printf("\tReduce %s->%s\n", rules[j].left, rules[j].right);
j = -1;
}}
if (strcmp(stack, rules[0].left) == 0 && i == strlen(input)) {
printf("\nAccepted");
break;
}
if (i == strlen(input)) {
printf("\nNot Accepted");
break;
}}

return 0;
}

Page 33
DEPARTMENT OF ARTIFICIAL INTELLIGENCE EXP NO:-_______

OUTPUT:

Page 34

You might also like