Compiler Design Record Old
Compiler Design Record Old
Compiler Design Record Old
DATE:
AIM:
Using the LEX tool, Develop a lexical analyser to recognize a few patterns in C. (Ex. identifiers,
constants, comments, operators etc.). Create a symbol table, while recognizing identifiers.
ALGORITM:
PROGRAM:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
int isKeyword(char buffer[]){
char keywords[32][10] = {"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 i, flag = 0;
for(i = 0; i < 32; ++i){
if(strcmp(keywords[i], buffer) == 0){
flag = 1;
break;
}
}
return flag;
}
int main(){
char ch, buffer[15], operators[] = "+-*/%=";
FILE *fp;
int i,j=0;
fp = fopen("C:\\Users\\dhivy\\My Drive\\SEM_5\\02_LAB\\CD\\PROGRAMS_CD\\for_exp1.txt", "r");
if(fp == NULL){
printf("error while opening the file\n");
exit(0);
}
while((ch = fgetc(fp)) != EOF){
for(i = 0; i < 6; ++i){
if(ch == operators[i])
printf("%c is operator\n", ch);
}
if(isalnum(ch)){
buffer[j++] = ch;
}
else if((ch == ' ' || ch == '\n') && (j != 0)){
buffer[j] = '\0';
j = 0;
if(isKeyword(buffer) == 1)
printf("%s is keyword\n", buffer);
else
printf("%s is indentifier\n", buffer);
}
}
fclose(fp);
return 0;
}
C program that used for lexical analyser:
for_exp_1.txt:
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
OUTPUT:
include is indentifier
stdioh is indentifier
int is keyword
main is indentifier
printfHello is indentifier
Worldn is indentifier
return is keyword
0 is indentifier
RESULT:
AIM:
To write C program for implementing symbol table.
ALGORITHM:
1. Start
2. Prompt input Expression
3. Print the given expression from array b[].
4. Create the symbol table and allocate memory for it and store it in d[] also store its memory
address in add[].
5. Display the symbol table
6. End
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main() {
int i = 0, j = 0, x = 0, n = 0, flag = 0;
void *p, *add[15];
char ch, srch, b[15], d[15], c;
printf("Symbol Table\n");
printf("Symbol\tAddress\t\tType\n\n");
i = 0;
while (i <= n) {
c = b[i];
if (isalpha(c)) {
if (i == n || !isalpha(b[i + 1])) {
p = malloc(sizeof(c));
add[x] = p;
d[x] = c;
printf("%c\t%p\tIdentifier\n", c, p);
x++;
}
} else {
ch = b[i + 1];
if (ch == '+' || ch == '-' || ch == '*' || ch == '=') {
p = malloc(sizeof(c));
add[x] = p;
d[x] = c;
printf("%c\t%p\tOperator\n", c, p);
x++;
}
}
i++;
}
return 0;
}
OUTPUT:
a 00BD18B8 Identifier
b 00BD18F8 Identifier
c 00BD1908 Identifier
RESULT:
Thus, to write a program to implement symbol table was executed successfully.
EXP NO: 2 LEXICAL ANALYZER USING LEX TOOL
DATE:
AIM:
Implement a Lexical Analyzer using LEX Tool.
ALGORITM:
PROGRAM:
File name: la.l
%{
#include<stdio.h>
%}
%%
int|char|float|return { printf("\n%s => Keyword", yytext); }
#.* { printf("\n%s => Preprocessor Directive", yytext); }
printf|scanf|main { printf("\n%s => Function", yytext); }
\"[a-zA-Z ]*\" { printf("\n%s => String", yytext); }
[[a-z]|[A-Z]][[a-z]|[A-Z]|[0-9]]+ { printf("\n%s => Identifier", yytext); }
[0-9]+ { printf("\n%s => Number", yytext); }
"+"|"-"|"*"|"/"|"%" { printf("\n%s => Operator", yytext); }
","|";"|"&"|"("|")"|"["|"]"|"{"|"}" { printf("\n%s => Special Character", yytext); }
%%
int main()
{
printf("Enter your input: \n");
yylex();
return 0;
}
int yywrap()
{
return 1;
}
OUTPUT:
To Compile: (In command Prompt)
C:\Users\dhivya\My Drive\SEM_5\02_LAB\CD\PROGRAMS_CD>flex la.l
C:\Users\dhivya\My Drive\SEM_5\02_LAB\CD\PROGRAMS_CD>gcc lex.yy.c -o la.exe
C:\Users\dhivya\My Drive\SEM_5\02_LAB\CD\PROGRAMS_CD>la.exe
Input:
int main()
{
int a,b;
printf("hello");
}
Program Output:
RESULT:
AIM:
Generate YACC specification program to recognize a valid arithmetic expression that uses operator
+, -, * and /.
ALGORITHM:
YACC Parser:
1. Initialize parser.
Lexer:
1. Initialize lexer.
PROGRAM:
arithmetic.y
%{
#include <stdio.h>
#include <stdlib.h>
%}
%token NUM
%%
%%
return 0;
int main() {
yyparse();
return 0;
arthemetic.l
%{
#include "y.tab.h"
%}
%%
[0-9]+ { yylval = atoi(yytext); return NUM; }
[ \t\n] { /* skip whitespace */ }
. { return yytext[0]; }
%%
int yywrap() {
return 1;
}
OUTPUT:
(In cmd):
flex arithmetic.l --This will produce lex.yy.c file and compile the program
bison -dy arithmetic.y --This will produce y.tab.c and y.tab.h also compile the program
Program output:
Enter an arithmetic expression: 1+2
Valid number
Valid number
Valid expression
RESULT:
Thus, to generate YACC specification program to recognize a valid arithmetic expression that uses
operator +, -, * and / was executed successfully.
Exp No: 3b
YACC Specification for Valid Variable Recognition
Date:
AIM:
Generate YACC specification to recognize a valid variable which starts with a letter followed by any
number of letters or digits.
ALGORITHM:
YACC Parser:
1. Initialize parser.
Lexer:
1. Initialize lexer.
PROGRAM:
variable.y
%{
#include <stdio.h>
#include <stdlib.h>
%}
%token ID
%%
%%
printf("Invalid variable\n");
return 0;
int main() {
yyparse();
return 0;
variable.l
%{
#include "y.tab.h"
%}
%%
. { return yytext[0]; }
%%
int yywrap() {
return 1;
}
OUTPUT:
Enter a variable: var1
Valid variable
12
Invalid variable
RESULT:
Thus, to generate YACC specification to recognize a valid variable which starts with a letter
followed by any number of letters or digits was executed successfully.
Exp No: 3c
YACC Specification for Valid Control Statements
Date:
AIM:
Generate YACC specification to recognize a valid control structures syntax of C language (For loop,
while loop, if-else, if-else-if, switch-case, etc.).
ALGORITHM:
YACC Parser:
1. Initialize parser.
Lexer:
1. Initialize lexer.
PROGRAM:
cs.y
%{
#include <stdio.h>
#include <stdlib.h>
%}
%token IF ELSE FOR WHILE SWITCH CASE DEFAULT
%%
program:
control_structures
control_structures:
control_structure
| control_structures control_structure
control_structure:
if_structure
| for_structure
| while_structure
| switch_structure
if_structure:
| IF '(' ')' '{' '}' ELSE '{' '}' { printf("Valid if-else structure\n"); }
for_structure:
FOR '(' ';' ';' ')' '{' '}' { printf("Valid for structure\n"); }
while_structure:
switch_structure:
cases:
%%
return 0;
int main() {
yyparse();
return 0;
cs.l
%{
#include "y.tab.h"
%}
%%
. { return yytext[0]; }
%%
int yywrap() {
return 1;
OUTPUT:
Enter control structures:
if () {}
Valid if structure
for {}
RESULT:
Thus, to generate YACC specification to recognize a valid control structures syntax of C language
was executed successfully.
Exp No: 3d
Implementation of calculator using LEX and YACC
Date:
AIM:
To implementation of calculator using LEX and YACC.
ALGORITHM:
YACC Parser:
1. Initialize parser.
Lexer:
1. Initialize lexer.
PROGRAM:
calc.y
%{
#include <stdio.h>
#include <stdlib.h>
%}
%token NUM
%left '+' '-'
%%
program:
calculation:
expr { $$ = $1; }
expr:
| NUM { $$ = $1; }
%%
return 0;
int main() {
yyparse();
return 0;
}
calc.l
%{
#include "y.tab.h"
%}
%%
\n { return '\n'; }
. { return yytext[0]; }
%%
int yywrap() {
return 1;
OUTPUT:
Enter expressions (end with Ctrl+D or an empty line):
456+4
Result: 460
56/2
Result: 28
54-9
Result: 45
20*10
Result: 200
RESULT:
Thus, to implementation of calculator using LEX and YACC was executed successfully.
EXP NO: 4 Three Address Code using LEX and YACC
DATE:
AIM:
To generate three address code for a simple program using LEX and YACC.
ALGORITHM:
YACC Parser:
1. Start.
2. Initialize parser with temp_var set to 0.
3. Define grammar rules for parsing expressions, operators, and parentheses, including intermediate
code generation.
4. Define error handling function (yyerror) to print error messages.
5. Prompt user for input to enter arithmetic expressions.
6. Call yyparse to start parsing the input.
7. Print result based on the evaluated expression.
Lexer:
PROGRAM:
tac.l (lex file)
%{
#include <stdio.h>
#include "y.tab.h"
%}
%%
<<EOF>> { return 0; }
%%
int yywrap() {
return 1;
%{
#include <stdio.h>
#include <stdlib.h>
int temp_var = 0;
int yylex(void);
%}
%token NUMBER
%token EOL
%%
input: /* empty */
| input line
;
line: expr EOL {
| EOL
%%
switch(op) {
case '=':
break;
case '+':
case '-':
case '*':
case '/':
break;
}
int yyerror(const char *s) {
return 0;
for_exp_4.c (c file)
#include <stdio.h>
int main() {
yyparse();
return 0;
OUTPUT:
In cmd:
flex tac.l
bison -dy tac.y
gcc lex.yy.c y.tab.c for_exp_4.c -o tac
tac
Program output:
Enter an arithmetic expression:
2+3*4
t0 = 2
t1 = 3
t2 = 4
t3 = t1 * t2
t4 = t0 + t3
Result: t4
Enter an arithmetic expression (or press Ctrl+C to exit):
^C
RESULT:
Thus, to generate three address code for a simple program using LEX and YACC was executed
successfully.
EXP NO: 5 Type Checking using Lex and Yacc.
DATE:
AIM:
To implement type checking using Lex and Yacc.
ALGORITHM:
Lex Program
PROGRAM:
%option noyywrap
%{
#include "y.tab.h"
#include <stdlib.h>
#include <string.h>
%}
%%
= { return ASSIGN; }
\+ { return PLUS; }
\- { return MINUS; }
\* { return MUL; }
\/ { return DIV; }
\n { return NEWLINE; }
. { return UNKNOWN; }
%%
tc.y(bison file)
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "y.tab.h"
typedef struct {
char *name;
int ival;
float fval;
int is_float;
} Variable;
Variable vars[MAX_VARS];
int var_count = 0;
exit(1);
int yylex();
if (strcmp(vars[i].name, name) == 0) {
return &vars[i];
return NULL;
void set_variable(const char *name, int ival, float fval, int is_float) {
if (var == NULL) {
vars[var_count].name = strdup(name);
vars[var_count].ival = ival;
vars[var_count].fval = fval;
vars[var_count].is_float = is_float;
var_count++;
} else {
var->ival = ival;
var->fval = fval;
var->is_float = is_float;
%}
%union {
int ival;
float fval;
char *sval;
%%
program:
statement_list
statement_list:
statement
| statement_list statement
;
statement:
expr:
NUMBER { $$ = $1; }
| variable {
if (var == NULL) {
} else if (var->is_float) {
} else {
$$ = var->ival;
float_expr:
FLOAT { $$ = $1; }
variable:
VARIABLE { $$ = $1; }
%%
int main() {
yyparse();
return 0;
}
OUTPUT:
x=10
Assigned 10 to x
y=x+2
Assigned 12 to y
x+y
Result: 22
RESULT:
Thus, to implement type checking using Lex and Yacc was executed successfully.
EXP NO: 6 IMPLEMENTING CODE OPTIMIZATION TECHNIQUES
DATE:
AIM:
Implement simple code optimization techniques (Constant folding, Strength reduction and Algebraic
transformation).
ALGORITHM:
1. Start Program
2. Read n, the number of expressions.
3. For each expression, read the left variable and the right-hand side expression.
4. Store these in a list or array.
5. Iterate over the stored expressions and print them.
6. Apply Dead Code Elimination
7. For each expression, check if its left variable is used in any other expressions' right-hand sides.
8. For each expression, search if its right-hand side appears in any other expressions.
9. For each expression, check if the right-hand side can be evaluated (e.g., arithmetic operations with
constants).
10. Identify opportunities for strength reduction (e.g., replacing multiplication by 2 with addition).
11. Print all expressions after applying all the optimization techniques.
12. End Program
PROGRAM:
#include <stdio.h>
#include <string.h>
#define MAX_OPS 10
int i;
struct op {
char l;
char r[20];
} op[MAX_OPS], pr[MAX_OPS];
if (strchr(ops[i].r, var)) {
return 1;
return 0;
void main() {
int i, j, k, n, z = 0;
char *p;
char temp, t;
char *tem
scanf("%d", &n);
getchar();
printf("left: ");
op[i].l = getchar();
getchar();
printf("right: ");
scanf("%s", op[i].r);
getchar();
}
printf("Intermediate Code\n");
print_operations(op, n);
pr[z] = op[i];
z++;
print_operations(pr, z);
if (strcmp(pr[i].r, pr[j].r) == 0) {
if (pos) {
*pos = pr[i].l;
pr[j].l = '\0';
strcpy(pr[j].r, "");
print_operations(pr, z);
printf("Optimized Code\n");
for (i = 0; i < z; i++) {
if (pr[i].l != '\0') {
OUTPUT:
Enter the Number of Values: 5
left: a
right: 1+2
left: b
right: a+2
left: c
right: a+b
left: d
right: c*2
left: e
right: d-1
Intermediate Code
a = 1+2
b = a+2
c = a+b
d = c*2
e = d-1
a = 1+2
b = a+2
c = a+b
d = c*2
a = 1+2
b = a+2
c = a+b
d = c*2
Optimized Code
a = 1+2
b = a+2
c = a+b
d = c*2
RESULT:
Thus, to implement simple code optimization techniques (Constant folding, Strength
reduction and Algebraic transformation) was executed successfully.
EXP NO: 7 INTERMEDIATE TO ASSEMBLY CODE GENERATION
DATE:
AIM:
To implement back-end of the compiler for which the three-address code is given as input and the
8086 assembly language code is produced as output.
ALGORITHM:
1. Start the program.
2. Initialize Variables
3. Input Intermediate Code
4. Print the header for target code generation.
5. Process Each Intermediate Code Line
6. Parse the Line
7. Determine the Corresponding Assembly Instruction
8. Generate and Print the Assembly Instructions
9. Repeat steps 5-7 for all lines of intermediate code
10. End Program.
PROGRAM:
File name: codegen.c
#include <stdio.h>
#include <string.h>
void main() {
char icode[10][30];
int j,i = 0;
while (1) {
icode[i][strcspn(icode[i], "\n")] = 0;
i++;
}
printf("\nTarget Code Generation:");
printf("\n************************");
if (strcmp(operator, "+") == 0) {
strcpy(operator, "ADD");
strcpy(operator, "SUB");
strcpy(operator, "MUL");
strcpy(operator, "DIV");
} else {
strcpy(operator, "UNKNOWN");
}
OUTPUT:
Enter the set of intermediate codes (terminated by 'exit'):
t1 = a + b
t2 = t1 * c
t3 = t2 / d
exit
************************
MOV a, R0
ADD b, R0
MOV R0, t1
MOV t1, R1
MUL c, R1
MOV R1, t2
MOV t2, R2
DIV d, R2
MOV R2, t3
RESULT:
Thus, to implement back-end of the compiler for which the three address code is given as input and
the 8086 assembly language code is produced as output.