CD_LAB_MANUAL
CD_LAB_MANUAL
2
Write a Lex Program to implement a Lexical Analyzer using Lex tool.
3
Write a C program to Simulate Lexical Analyzer to validating a given input String.
4
Write a C program to implement the Brute force technique of Top down Parsing.
5
Write a C program to implement a Recursive Descent Parser.
6 Write C program to compute the First and Follow Sets for the given Grammar
7 Write a C program for eliminating the left recursion and left factoring of a given
grammar
8 Write a C program to check the validity of input string using Predictive Parser.
9
Write a C program for implementation of LR parsing algorithm to accept a given
input string..
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
13 Write a C program for generating the three address code of a given expression /
statement.
14 Write a C program for implementation of a Code Generation Algorithm of a given
expression / statement.
EXPERIMENT- 1
OBJECTIVE:
PROGRAM:
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
if (len == 0)
return false;
if (isKeyword(subStr))
printf("'%s' IS A KEYWORD\n", subStr);
else if (isInteger(subStr))
printf("'%s' IS AN INTEGER\n", subStr);
else if (isRealNumber(subStr))
printf("'%s' IS A REAL NUMBER\n", subStr);
else if (validIdentifier(subStr) && !isDelimiter(str[right - 1]))
printf("'%s' IS A VALID IDENTIFIER\n", subStr);
else if (!validIdentifier(subStr) && !isDelimiter(str[right - 1]))
printf("'%s' IS NOT A VALID IDENTIFIER\n", subStr);
left = right;
free(subStr);
}
}
}
// DRIVER FUNCTION
int main() {
char str[100] = "int a = b + 1c;";
parse(str);
return 0;
}
Output:
'int' IS A KEYWORD
'a' IS A VALID IDENTIFIER
'=' IS AN OPERATOR
'b' IS A VALID IDENTIFIER
'+' IS AN OPERATOR
'1c' IS NOT A VALID IDENTIFIER
EXPERIMENT- 2
OBJECTIVE:
STEPS:
1.INSTALL FLEX.
2.OPEN NEW FILE LEX AND WRITE LEX PROGRAM and save it as lexp.l
3. Then Go to Tools and click Compile Lex
4.yylex.c is created. go to Tools and click Lex Build.
5.Then lexp.exe is created.
6.Then open cmd and go to editor plus in FLEX directory and write a.exe
PROGRAM:
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 yywrap() {
return 1;
}
Input:
#include<stdio.h>
main()
{
int a,b;
}
Output:
#include<stdio.h> is a PREPROCESSOR DIRECTIVE
FUNCTION
main (
)
BLOCK BEGINS
int is a KEYWORD
a IDENTIFIER
b IDENTIFIER
BLOCK ENDS
EXPERIMENT- 3
OBJECTIVE:
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char string[50];
int count = 0, i;
return 0;
}
OUTPUT:
Enter the String: Welcome123
Input String is valid identifier
OBJECTIVE:
Write a C program to implement the Brute force technique of Top down Parsing
PROGRAM:
#include <stdio.h>
#include <string.h>
void check(void);
void set_value_backtracking(void);
void get_value_backtracking(void);
void display_output_string(void);
int main() {
printf("\nEnter the string to check: ");
scanf("%s", input_string);
check();
return 0;
}
void check(void) {
int flag = 1, rule2_index = 1;
strcpy(output_string, "S");
void set_value_backtracking(void) {
// Setting values for backtracking
current_optr = optr;
strcpy(current_output_string, output_string);
return;
}
void get_value_backtracking(void) {
// Backtracking and obtaining previous values
optr = current_optr;
memset(output_string, 0, strlen(output_string));
strcpy(output_string, current_output_string);
return;
}
void display_output_string(void) {
printf("%s\n", output_string);
memset(temp_string, 0, strlen(temp_string));
strcpy(temp_string, output_string);
return;
}
OUTPUT:
OBJECTIVE:
Write a C program to implement a Recursive Descent Parser.
PROGRAM:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char input[10];
int i, error;
void E();
void T();
void Eprime();
void Tprime();
void F();
int main() {
i = 0;
error = 0;
printf("Enter an arithmetic expression : "); // Eg: a+a*a
gets(input);
E();
if (strlen(input) == i && error == 0)
printf("\nAccepted..!!!\n");
else
printf("\nRejected..!!!\n");
return 0;
}
void E() {
T();
Eprime();
}
void Eprime() {
if (input[i] == '+') {
i++;
T();
Eprime();
}
}
void T() {
F();
Tprime();
}
void Tprime() {
if (input[i] == '*') {
i++;
F();
Tprime();
}
}
void F() {
if (isalnum(input[i]))
i++;
else if (input[i] == '(') {
i++;
E();
if (input[i] == ')')
i++;
else
error = 1;
} else
error = 1;
}
OUTPUT:
OBJECTIVE:
Write C program to compute the First and Follow Sets for the given Grammar
PROGRAM:
#include<stdio.h>
#include<ctype.h>
#include<string.h>
int count, n = 0;
char calc_first[10][100]; // Stores First Sets
char calc_follow[10][100]; // Stores Follow Sets
char production[10][10]; // Stores production rules
char f[10], first[10];
int k, m = 0, e;
char ck;
int main() {
int jm = 0, km = 0, i, kay, ptr = -1;
char c, done[10], donee[10];
count = 8;
// Input grammar
strcpy(production[0], "E=TR");
strcpy(production[1], "R=+TR");
strcpy(production[2], "R=#");
strcpy(production[3], "T=FY");
strcpy(production[4], "Y=*FY");
strcpy(production[5], "Y=#");
strcpy(production[6], "F=(E)");
strcpy(production[7], "F=i");
printf("\n-----------------------------------------------\n\n");
ptr = -1;
// Initializing calc_follow array
for (k = 0; k < count; k++) {
for (kay = 0; kay < 100; kay++) {
calc_follow[k][kay] = '!';
}
}
point1 = 0;
for (e = 0; e < count; e++) {
ck = production[e][0];
point2 = 0;
xxx = 0;
for (kay = 0; kay <= ptr; kay++) {
if (ck == donee[kay]) xxx = 1;
}
if (xxx == 1) continue;
follow(ck);
donee[++ptr] = ck;
printf(" Follow(%c) = { ", ck);
calc_follow[point1][point2++] = ck;
for (i = km; i < m; i++) {
int lark, chk = 0;
for (lark = 0; lark < point2; lark++) {
if (f[i] == calc_follow[point1][lark]) {
chk = 1;
break;
}
}
if (chk == 0) {
printf("%c, ", f[i]);
calc_follow[point1][point2++] = f[i];
}
}
printf(" }\n\n");
km = m;
point1++;
}
}
void follow(char c) {
if (production[0][0] == c) {
f[m++] = '$';
}
for (int i = 0; i < 10; i++) {
for (int j = 2; j < 10; 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]);
}
}
}
}
}
OUTPUT:
First(E) = { (, i, }
First(R) = { +, #, }
First(T) = { (, i, }
First(Y) = { *, #, }
First(F) = { (, i, }
-----------------------------------------------
Follow(E) = { $, ), }
Follow(R) = { $, ), }
Follow(T) = { +, $, ), }
Follow(Y) = { +, $, ), }
Follow(F) = { *, +, $, ), }
EXPERIMENT- 7
OBJECTIVE:
Write a C program for eliminating the left recursion and left factoring of a given grammar
#include <stdio.h>
#include <string.h>
void main() {
char input[100], l[50], r[50], temp[10], tempprod[20], productions[25][50];
int i = 0, j = 0, flag = 0, consumed = 0;
if (flag == 1) {
sprintf(productions[i++], "%s->ε", l);
printf("The productions after eliminating Left Recursion are:\n");
for (j = 0; j < i; j++)
printf("%s\n", productions[j]);
} else {
printf("The Given Grammar has no Left Recursion");
}
}
OUTPUT:
#include <stdio.h>
#include <string.h>
int main() {
char gram[50], part1[50], part2[50], modifiedGram[50], newGram[50];
int i, j = 0, k = 0, pos;
OUTPUT:
A->BX
X->a | b
EXPERIMENT- 8
OBJECTIVE:
Write a C program to check the validity of input string using Predictive Parser.
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
int token;
char lexbuff[size];
int lookahead = 0;
int lexer();
int E();
int T();
int EPRIME();
int TPRIME();
int F();
void parser();
int main() {
// Replace clrscr with a clearer alternative for UNIX-like systems
printf("\033[H\033[J"); // ANSI escape sequence to clear screen
void parser() {
if (E())
printf("Valid string\n");
else
printf("Invalid string\n");
}
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() {
token = lexer();
if (token == addop) {
lookahead++;
if (T()) {
if (EPRIME())
return 1;
else
return 0;
} else {
return 0;
}
} else {
return 1;
}
}
int TPRIME() {
token = lexer();
if (token == mulop) {
lookahead++;
if (F()) {
if (TPRIME())
return 1;
else
return 0;
} else {
return 0;
}
} else {
return 1;
}
}
int F() {
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;
}
}
}
int lexer() {
if (lexbuff[lookahead] != '\n') {
while (lexbuff[lookahead] == ' ' || 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;
}
}
OUTPUT:
OBJECTIVE:
Write a C program for implementation of LR parsing algorithm to accept a given input string
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
typedef struct {
char stack[MAX_STACK_SIZE];
int top;
} Parser;
bool isTerminal(char c) {
return c == 'a' || c == 'b' || c == '+' || c == '*' || c == '(' || c == ')';
}
// Final validation
while (parser.top >= 0) {
char top = parser.stack[parser.top];
if (top != 'F' && top != 'E' && top != 'T') return false;
pop(&parser);
}
return true;
}
int main() {
// Test input strings
char* accepted_strings[] = {
"a",
"b",
"a+b",
"a*b",
"(a+b)",
"a+a*b",
"(a)*b",
"a+(b*a)"
};
char* rejected_strings[] = {
"+",
"*",
"a++b",
"(a",
"a)",
"a+*b"
};
printf("Accepted Strings:\n");
for (int i = 0; i < sizeof(accepted_strings) / sizeof(char*); i++) {
printf("%s - %s\n",
accepted_strings[i],
parse(accepted_strings[i]) ? "Accepted" : "Rejected");
}
printf("\nRejected Strings:\n");
for (int i = 0; i < sizeof(rejected_strings) / sizeof(char*); i++) {
printf("%s - %s\n",
rejected_strings[i],
parse(rejected_strings[i]) ? "Accepted" : "Rejected");
}
return 0;
}
OUTPUT:
Accepted Strings:
a - Accepted
b - Accepted
a+b - Accepted
a*b - Accepted
(a+b) - Accepted
a+a*b - Accepted
(a)*b - Accepted
a+(b*a) - Accepted
Rejected Strings:
+ - Rejected
* - Rejected
a++b - Rejected
(a - Rejected
a) - Rejected
a+*b - Rejected
EXPERIMENT- 10
OBJECTIVE:
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
PROGRAM:
#include <stdio.h>
#include <string.h>
int k = 0, z = 0, i = 0, j = 0, c = 0;
char a[16], ac[20], stk[15], act[10];
void check();
int main() {
puts("GRAMMAR is E->E+E \n E->E*E \n E->(E) \n E->id");
puts("Enter input string: ");
gets(a);
c = strlen(a);
strcpy(act, "SHIFT->");
void check() {
strcpy(ac, "REDUCE TO E");
OUTPUT:
GRAMMAR is E->E+E
E->E*E
E->(E)
E->id enter input string
id+id*id+id
OBJECTIVE:
PROGRAM:
%{
/* Definition section */
#include <stdio.h>
int flag = 0;
%}
%token NUMBER
/* Rule Section */
%%
ArithmeticExpression: E {
printf("\nResult = %d\n", $$);
return 0;
};
E: E '+' E { $$ = $1 + $3; }
| E '-' E { $$ = $1 - $3; }
| E '*' E { $$ = $1 * $3; }
| E '/' E { $$ = $1 / $3; }
| E '%' E { $$ = $1 % $3; }
| '(' E ')' { $$ = $2; }
| NUMBER { $$ = $1; }
;
%%
// Driver code
void main() {
printf("\nEnter any arithmetic expression which can have operations Addition, Subtraction,
Multiplication, Division, Modulus, and Round brackets:\n");
yyparse();
if (flag == 0)
printf("\nEntered arithmetic expression is valid\n\n");
}
void yyerror() {
printf("\nEntered arithmetic expression is invalid\n\n");
flag = 1;
}
OUTPUT:
Input: 4+5
Output: Result=9
Entered arithmetic expression is Valid
Input: 10-5
Output: Result=5
Entered arithmetic expression is Valid
Input: 10+5-
Output:
Entered arithmetic expression is Invalid
EXPERIMENT- 12
OBJECTIVE:
Program:
/* Tokens */
%token NUMBER
%token PLUS MINUS MUL DIV
%%
/* Grammar Rules */
expression:
expression PLUS term { $$ = $1 + $3; }
| expression MINUS term { $$ = $1 - $3; }
| term { $$ = $1; }
;
term:
term MUL factor { $$ = $1 * $3; }
| term DIV factor { $$ = $1 / $3; }
| factor { $$ = $1; }
;
factor:
NUMBER { $$ = $1; }
| '(' expression ')' { $$ = $2; }
;
%%
/* Driver Code */
int main()
{
printf("Enter an arithmetic expression: \n");
yyparse();
return 0;
}
digit [0-9]
%%
%%
int yywrap() {
return 1;
}
Output:
For input like:
Enter an arithmetic expression:
3 + 5 * (2 - 8)
Output will be:
Result = -13
In this case, the arithmetic expression 3 + 5 * (2 - 8) is parsed and evaluated correctly, considering
operator precedence and parentheses, resulting in -13.
EXPERIMENT- 13
OBJECTIVE :
Write a C program for generating the three address code of a given expression / statement.
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
return 0;
}
OUTPUT:
OBJECTIVE:
Write a C program for implementation of a Code Generation Algorithm of a given expression / statement.
PROGRAM:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX 100
postfix[j] = '\0';
}
typedef struct {
char items[MAX][MAX];
int top;
} Stack;
int main() {
char input[MAX], infix[MAX], postfix[MAX], lhs[10] = "";
infixToPostfix(infix, postfix);
printf("\nPostfix expression: %s\n", postfix);
char result[MAX];
pop(&stack, result);
if(strlen(lhs) > 0)
printf("MOV %s, %s\n", lhs, result);
else
printf("Final result in %s\n", result);
return 0;
}
OUTPUT: