0% found this document useful (0 votes)
29 views31 pages

CD 1

The document describes a program to convert three address code to assembly code. It includes lex and yacc files to parse the three address code and generate the assembly code. The lex file defines tokens for letters, numbers and other symbols. The yacc file defines grammar rules for expressions and statements. It uses yacc actions to generate the assembly code by calling functions to output triples and quadruples with the operands, operators and temporaries. A symbol table is used to track variable names and generate addresses.

Uploaded by

ddm22212
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)
29 views31 pages

CD 1

The document describes a program to convert three address code to assembly code. It includes lex and yacc files to parse the three address code and generate the assembly code. The lex file defines tokens for letters, numbers and other symbols. The yacc file defines grammar rules for expressions and statements. It uses yacc actions to generate the assembly code by calling functions to output triples and quadruples with the operands, operators and temporaries. A symbol table is used to track variable names and generate addresses.

Uploaded by

ddm22212
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/ 31

Ex.

no 1 Develop Lexical analyzer to recognize patterns in C

Program

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

#define MAX_TOKEN_LENGTH 100

// Token types
enum TokenType {
KEYWORD,
IDENTIFIER,
CONSTANT,
COMMENT,
OPERATOR,
SPECIAL_SYMBOL
};

// Token structure
struct Token {
enum TokenType type;
char value[MAX_TOKEN_LENGTH];
};

// Function to print tokens


void printToken(struct Token token) {

printf("%s \t %s\n", (token.type==0) ? "Keyword": (token.type==1) ? "Identifier" : (token.type==2)


? "Constant" :
(token.type==3) ? "Comment" : (token.type=4) ? "Operator" : "Special_symbol",
token.value);

// Function to perform lexical analysis


void lexer(char *input_code) {
struct Token token;
char *delimiters = " \t\n"; // Whitespace characters

while (*input_code != '\0') {


// Skip whitespace
if (strchr(delimiters, *input_code) != NULL) {
input_code++;
continue;
}

// Check for keywords


if (isalpha(*input_code) || *input_code == '_') {
token.type = IDENTIFIER;
int i = 0;
while (isalnum(*input_code) || *input_code == '_') {
token.value[i++] = *input_code++;
}
token.value[i] = '\0';

// Check if the identifier is a keyword


if (strcmp(token.value, "int") == 0 ||
strcmp(token.value, "float") == 0 ||
strcmp(token.value, "char") == 0 ||
strcmp(token.value, "if") == 0 ||
strcmp(token.value, "else") == 0 ||
strcmp(token.value, "while") == 0 ||
strcmp(token.value, "for") == 0 ||
strcmp(token.value, "return") == 0 ||
strcmp(token.value, "main") == 0) {
token.type = KEYWORD;
}

printToken(token);
continue;
}

// Check for constants (integers)


if (isdigit(*input_code)) {
token.type = CONSTANT;
int i = 0;
while (isdigit(*input_code)) {
token.value[i++] = *input_code++;
}
token.value[i] = '\0';
printToken(token);
continue;
}

// Check for comments


if (*input_code == '/') {
input_code++;
if (*input_code == '/') {
token.type = COMMENT;
int i = 0;
while (*input_code != '\n' && *input_code != '\0') {
token.value[i++] = *input_code++;
}
token.value[i] = '\0';
printToken(token);
continue;
} else if (*input_code == '*') {
token.type = COMMENT;
int i = 0;
while (!(input_code[0] == '*' && input_code[1] == '/') && *input_code != '\0') {
token.value[i++] = *input_code++;
}
token.value[i] = '\0';
printToken(token);
input_code += 2; // Skip the closing */
continue;
}
}

// Check for operators


if (*input_code == '+' || *input_code == '-' || *input_code == '*' || *input_code == '/' ||
*input_code == '=' || *input_code == '<' || *input_code == '>') {
token.type = OPERATOR;
token.value[0] = *input_code++;
token.value[1] = '\0';
printToken(token);
continue;
}
// Move to the next character if none of the patterns match
input_code++;
}
}

int main() {
char code[] = "int main() {\n"
" // This is a comment\n"
" int x = 10;\n"
" y = x + 5;\n"
" return 0;\n"
"}\n";

lexer(code);

return 0;
}
Ex.no 1.a Create a symbol table

Program:

//Implementation of symbol table


#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
void main()
{
int i=0,j=0,x=0,n;
void *p,*add[5];
char ch,srch,b[15],d[15],c;
printf("Expression terminated by $:");
while((c=getchar())!='$')
{
b[i]=c;
i++;
}
n=i-1;
printf("Given Expression:");
i=0;
while(i<=n)
{
printf("%c",b[i]);
i++;
}
printf("\n Symbol Table\n");
printf("Symbol \t addr \t type");
while(j<=n)
{
c=b[j];
if(isalpha(toascii(c)))
{
p=malloc(c);
add[x]=p;
d[x]=c;
printf("\n%c \t %p \t identifier\n",c,p);
x++;
j++;
}
else
{
ch=c;
if(ch=='+'||ch=='-'||ch=='*'||ch=='=')
{
p=malloc(ch);
add[x]=p;
d[x]=ch;
printf("\n %c \t %p \t operator\n",ch,p);
x++;
j++;
}
}
}
}
Ex.no 2 Implement a Lexical Analyzer using Lex tool

//Implementation of Lexical Analyzer using Lex tool


%{
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");}
\( 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 File

var.c

#include<stdio.h>
#include<conio.h>
void main()
{
int a,b,c;
a=1;
b=2;
c=a+b;
printf("Sum:%d",c);
}
Ex.no 3.a Valid arithmetic expression

lex file 3a.l

%{
#include<stdio.h>
#include "y.tab.h"
%}
%%
[a-zA-Z][0-9a-zA-Z]* {return ID;}
[0-9]+ {return DIG;}
[ \t]+ {;}
. {return yytext[0];}
\n {return 0;}
%%
int yywrap()
{
return 1;
}

yacc file 3a.y

%{
#include <stdio.h>
#include <stdlib.h>
int yylex(void);
void yyerror(char const *);
%}
%token ID DIG
%left '+''-'
%left '*''/'
%right UMINUS
%%
stmt:expn ;
expn:expn'+'expn
|expn'-'expn
|expn'*'expn
|expn'/'expn
|'-'expn %prec UMINUS
|'('expn')'
|DIG
|ID
;
%%
int main()
{
printf("Enter the Expression \n");
yyparse();
printf("valid Expression \n");
return 0;
}
void yyerror(const char *s)
{
printf("Invalid Expression");
exit(0);
}
Ex.no 3.b Check valid variable or not

var.l

%{
#include "y.tab.h"
%}
%%
[0-9]+ {return DIGIT;}
[a-zA-Z]+ {return LETTER;}
[ \t] {;}
\n { return 0;}
. {return yytext[0];}
%%
int yywrap() {
// Return 1 to indicate the end of input
return 1;
}

var.y

%{
#include<stdio.h>
#include<stdlib.h>
int yylex(void);
void yyerror(char const *);
%}
%token DIGIT LETTER
%%
stmt:A
;
A: LETTER B
;
B: LETTER B
| DIGIT B
| LETTER
| DIGIT
;
%%
void main(){
printf("enter string \n");
yyparse();
printf("valid");
exit(0);
}
void yyerror(const char *s)
{
printf("invalid");
exit(0);
}
Ex.no 3c Calculator using LEX and YACC

calc.l

%{

#include <stdio.h>
#include "y.tab.h"
int c;
extern int yylval;
%}
%%
"" ;
[a-z] {
c = yytext[0];
yylval = c - 'a';
return(LETTER);
}
[0-9] {
c = yytext[0];
yylval = c - '0';
return(DIGIT);
}
[^a-z0-9\b] {
c = yytext[0];
return(c);
}

calc.y

%{
#include <stdio.h>
int yylex(void);
void yyerror(char const *);
int regs[26];
int base;

%}

%start list

%token DIGIT LETTER

%left '|'
%left '&'
%left '+' '-'
%left '*' '/' '%'
%left UMINUS /*supplies precedence for unary minus */

%% /* beginning of rules section */


list: /*empty */
|
list stat '\n'
|
list error '\n'
{
yyerrok;
}
;

stat: expr
{
printf("%d\n",$1);
}
|
LETTER '=' expr
{
regs[$1] = $3;
}

expr: '(' expr ')'


{
$$ = $2;
}
|
expr '*' expr
{
$$ = $1 * $3;
}
|
expr '/' expr
{
$$ = $1 / $3;
}
|
expr '%' expr
{
$$ = $1 % $3;
}
|
expr '+' expr
{
$$ = $1 + $3;
}
|

expr '-' expr


{
$$ = $1 - $3;
}
|
expr '&' expr
{
$$ = $1 & $3;
}
|
expr '|' expr
{
$$ = $1 | $3;
}
|

'-' expr %prec UMINUS


{
$$ = -$2;
}
|
LETTER
{
$$ = regs[$1];
}

|
number
;

number: DIGIT
{
$$ = $1;
base = ($1==0) ? 8 : 10;
} |
number DIGIT
{
$$ = base * $1 + $2;
}
;

%%
int main()
{
return(yyparse());
}

void yyerror(const char *s)


{
fprintf(stderr, "%s\n",s);
}

int yywrap()
{
return(1);}
Ex.no 4 Convert three address code

three.l

%{
#include "y.tab.h"
%}

%%

[0-9]+? {yylval.sym=(char)yytext[0]; return NUMBER;}


[a-zA-Z]+? {yylval.sym=(char)yytext[0];return LETTER;}

\n {return 0;}
. {return yytext[0];}

%%
int yywrap()
{
return 1;
}

three.y

%{
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
int yylex(void);
void yyerror(char const *);
void ThreeAddressCode();
void triple();
void qudraple();
char AddToTable(char ,char, char);

int ind=0;//count number of lines


char temp = '1';//for t1,t2,t3.....
struct incod
{
char opd1;
char opd2;
char opr;
};
%}

%union
{
char sym;
}

%token <sym> LETTER NUMBER


%type <sym> expr
%left '+'
%left '*''/'
%left '-'
%%

statement: LETTER '=' expr ';' {AddToTable((char)$1,(char)$3,'=');}


| expr ';'
;

expr:
expr '+' expr {$$ = AddToTable((char)$1,(char)$3,'+');}
| expr '-' expr {$$ = AddToTable((char)$1,(char)$3,'-');}
| expr '*' expr {$$ = AddToTable((char)$1,(char)$3,'*');}
| expr '/' expr {$$ = AddToTable((char)$1,(char)$3,'/');}
| '(' expr ')' {$$ = (char)$2;}
| NUMBER {$$ = (char)$1;}
| LETTER {$$ = (char)$1;}
|'-' expr {$$ = AddToTable((char)$2,(char)'\t','-');}
;

%%

void yyerror(const char *s)


{
printf("%s",s);
exit(0);
}

struct incod code[20];

char AddToTable(char opd1,char opd2,char opr)


{
code[ind].opd1=opd1;
code[ind].opd2=opd2;
code[ind].opr=opr;
ind++;
return temp++;
}

void ThreeAddressCode()
{
int cnt = 0;
char temp = '1';
printf("\n\n\t THREE ADDRESS CODE\n\n");
while(cnt<ind)
{
if(code[cnt].opr != '=')
printf("t%c : = \t",temp++);

if(isalpha(code[cnt].opd1))
printf(" %c\t",code[cnt].opd1);
else if(code[cnt].opd1 >='1' && code[cnt].opd1 <='9')
printf("t%c\t",code[cnt].opd1);

printf(" %c\t",code[cnt].opr);

if(isalpha(code[cnt].opd2))
printf(" %c\n",code[cnt].opd2);
else if(code[cnt].opd2 >='1' && code[cnt].opd2 <='9')
printf("t%c\n",code[cnt].opd2);

cnt++;
}
}

void quadraple()
{
int cnt = 0;
char temp = '1';
printf("\n\n\t QUADRAPLE CODE\n\n");
while(cnt<ind)
{
printf(" %c\t",code[cnt].opr);
if(code[cnt].opr == '=')
{
if(isalpha(code[cnt].opd2))
printf(" %c\t \t",code[cnt].opd2);
else if(code[cnt].opd2 >='1' && code[cnt].opd2 <='9')
printf("t%c\t \t",code[cnt].opd2);

printf(" %c\n",code[cnt].opd1);
cnt++;
continue;
}
if(isalpha(code[cnt].opd1))
printf(" %c\t",code[cnt].opd1);
else if(code[cnt].opd1 >='1' && code[cnt].opd1 <='9')
printf("t%c\t",code[cnt].opd1);

if(isalpha(code[cnt].opd2))
printf(" %c\t",code[cnt].opd2);
else if(code[cnt].opd2 >='1' && code[cnt].opd2 <='9')
printf("t%c\t",code[cnt].opd2);
else printf(" %c",code[cnt].opd2);

printf("t%c\n",temp++);

cnt++;
}
}

void triple()
{
int cnt=0;
char temp='1';
printf("\n\n\t TRIPLE CODE\n\n");
while(cnt<ind)
{
printf("(%c) \t",temp);
printf(" %c\t",code[cnt].opr);
if(code[cnt].opr == '=')
{
if(isalpha(code[cnt].opd2))
printf(" %c \t \t",code[cnt].opd2);
else if(code[cnt].opd2 >='1' && code[cnt].opd2 <='9')
printf("(%c)\n",code[cnt].opd2);
cnt++;
temp++;
continue;
}
if(isalpha(code[cnt].opd1))
printf(" %c \t",code[cnt].opd1);
else if(code[cnt].opd1 >='1' && code[cnt].opd1 <='9')
printf("(%c)\t",code[cnt].opd1);

if(isalpha(code[cnt].opd2))
printf(" %c \n",code[cnt].opd2);
else if(code[cnt].opd2 >='1' && code[cnt].opd2 <='9')
printf("(%c)\n",code[cnt].opd2);
else printf(" %c\n",code[cnt].opd2);

cnt++;
temp++;
}
}

int main()
{
printf("\n Enter the Expression : ");
yyparse();
ThreeAddressCode();
quadraple();
triple();
}
Ex.No 5 Implement type checking using C programming Language
Program:
#include<stdio.h>
#include<string.h>
#include<conio.h>
int count=1,i=0,j=0,l=0,findval=0,k=0,kflag=0;
char key[4][12]= {"int","float","char","double"};
char dstr[100][100],estr[100][100];
char token[100],resultvardt[100],arg1dt[100],arg2dt[100];
void entry();
int check(char[]);
int search(char[]);
void typecheck();
struct table
{
char var[10];
char dt[10];
};
struct table tbl[20];
void main()
{
clrscr();
printf("\n IMPLEMENTATION OF TYPE CHECKING \n");
printf("\n DECLARATION \n\n");
do
{
printf("\t");
gets(dstr[i]);
i++;
} while(strcmp(dstr[i-1],"END"));
printf("\n EXPRESSION \n\n");
do
{
printf("\t");
gets(estr[l]);
l++;
}while(strcmp(estr[l-1],"END"));
i=0;
printf("\n SEMANTIC ANALYZER(TYPE CHECKING): \n");
while(strcmp(dstr[i],"END"))
{
entry();
printf("\n");
i++;
}
l=0;
while(strcmp(estr[l],"END"))
{
typecheck();
printf("\n");
l++;
}
printf("\n PRESS ENTER TO EXIT FROM TYPE CHECKING\n");
getch();
}
void entry()
{
j=0;
k=0;
memset(token,0,sizeof(token));
while(dstr[i][j]!=' ')
{
token[k]=dstr[i][j];
k++;
j++;
}
kflag=check(token);
if(kflag==1)
{
strcpy(tbl[count].dt,token);
k=0;
memset(token,0,strlen(token));
j++;
while(dstr[i][j]!=';')
{
token[k]=dstr[i][j];
k++;
j++;
}
findval=search(token);
if(findval==0)
{
strcpy(tbl[count].var,token);
}
else
{
printf("The variable %s is already declared",token);
}
kflag=0;
count++;
}
else
{
printf("Enter valid datatype\n");
}
}
void typecheck()
{
memset(token,0,strlen(token));
j=0;
k=0;
while(estr[l][j]!='=')

{
token[k]=estr[l][j];
k++;
j++;
}
findval=search(token);
if(findval>0)
{
strcpy(resultvardt,tbl[findval].dt);
findval=0;
}
else
{
printf("Undefined Variable\n");
}
k=0;
memset(token,0,strlen(token));
j++;
while(((estr[l][j]!='+')&&(estr[l][j]!='-
')&&(estr[l][j]!='*')&&(estr[l][j]!='/')))
{
token[k]=estr[l][j];
k++;
j++;
}
findval=search(token);
if(findval>0)
{
strcpy(arg1dt,tbl[findval].dt);
findval=0;
}
else
{
printf("Undefined Variable\n");
}
k=0;
memset(token,0,strlen(token));
j++;
while(estr[l][j]!=';')
{
token[k]=estr[l][j];
k++;
j++;
}
findval=search(token);
if(findval>0)
{
strcpy(arg2dt,tbl[findval].dt);
findval=0;
}
else
{
printf("Undefined Variable\n");
}
if(!strcmp(arg1dt,arg2dt))
{
if(!strcmp(resultvardt,arg1dt))
{
printf("\tThere is no type mismatch in the expression %s
",estr[l]);
}
else
{
printf("\tLvalue and Rvalue should be same\n");
}
}
else
{
printf("\tType Mismatch\n");
}
}
int search(char variable[])
{
int i;
for(i=1;i<=count;i++)
{
if(strcmp(tbl[i].var,variable) == 0)
{
return i;
}
}
return 0;
}
int check(char t[])
{
int in;
for(in=0;in<4;in++)
{
if(strcmp(key[in],t)==0)
{
return 1;
}
}
return 0;
}
Ex.no 6. Implement simple code optimization techniques

Program

#include<stdio.h>
#include<conio.h>
#include<ctype.h>
void main()
{
char a[25][25],u,op1='*',op2='+',op3='/',op4='-';
int p,q,r,l,o,ch,i=1,c,k=1,j,count=0;
FILE *fi,*fo;
// clrscr();
printf("Enter three address code");
printf("\nEnter the ctrl-z to complete:\n");
fi=fopen("infile.txt","w");
while((c=getchar())!=EOF)
fputc(c,fi);
fclose(fi);
printf("\n Unoptimized input block\n");
fi=fopen("infile.txt","r");
while((c=fgetc(fi))!=EOF)
{
k=1;
while(c!=';'&&c!=EOF)
{
a[i][k]=c;
printf("%c",a[i][k]);
k++;
c=fgetc(fi);
}
printf("\n");
i++;
}
count=i;
fclose(fi);
i=1;
printf("\n Optimized three address code");
while(i<count)
{
if(strcmp(a[i][4],op1)==0&&strcmp(a[i][5],op1)==0)
{
printf("\n Type 1 reduction in strength ");
if(strcmp(a[i][6],'2')==0)
{
for(j=1;j<=4;j++)
printf("%c",a[i][j]);
printf("%c",a[i][3]);
}
}
else if(isdigit(a[i][3])&&isdigit(a[i][5]))
{
printf("\n Type2 constant folding ");
p=a[i][2];
q=a[i][4];
if(strcmp(a[i][3],op1)==0)
r=p*q;
if(strcmp(a[i][3],op2)==0)
r=p+q;
if(strcmp(a[i][3],op3)==0)
r=p/q;
if(strcmp(a[i][3],op4)==0)
r=p-q;
for(j=1;j<=2;j++)
printf("%c",a[i][j]);
printf("%d",r);
printf("\n");
}
else if(strcmp(a[i][5],'0')==0||strcmp(a[i][5],'1')==0)
{
printf("\n Type3 algebraic expression elimation ");
if((strcmp(a[i][4],op1)==0&&strcmp(a[i][5],'1')==0)||(strcmp(a[i][4],op3)==0&&strcmp(a[i][5],'1')
==0))
{
for(j=1;j<=3;j++)
printf("%c",a[i][j]);
printf("\n");
}
else
printf("\n sorry cannot optimize\n");
}
else
{
printf("\n Error input");
}
i++;
}
getch();
}
Ex.no 7 Implement back end of the compiler

Program

#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>
#include<graphics.h>
typedef struct
{
char var[10];
int alive;
}
regist;
regist preg[10];
void substring(char exp[],int st,int end)
{
int i,j=0;
char dup[10]="";
for(i=st;i<end;i++)
dup[j++]=exp[i];
dup[j]='0';
strcpy(exp,dup);
}
int getregister(char var[])
{
int i;
for(i=0;i<10;i++)
{
if(preg[i].alive==0)
{
strcpy(preg[i].var,var);
break;
}
}
return(i);
}
void getvar(char exp[],char v[])
{
int i,j=0;
char var[10]="";
for(i=0;exp[i]!='\0';i++)
if(isalpha(exp[i]))
var[j++]=exp[i];
else
break;
strcpy(v,var);
}
void main()
{
char basic[10][10],var[10][10],fstr[10],op;
int i,j,k,reg,vc,flag=0;
clrscr();
printf("\nEnter the Three Address Code:\n");
for(i=0;;i++)
{
gets(basic[i]);
if(strcmp(basic[i],"exit")==0)
break;
}
printf("\nThe Equivalent Assembly Code is:\n");
for(j=0;j<i;j++)
{
getvar(basic[j],var[vc++]);
strcpy(fstr,var[vc-1]);
substring(basic[j],strlen(var[vc-1])+1,strlen(basic[j]));
getvar(basic[j],var[vc++]);
reg=getregister(var[vc-1]);
if(preg[reg].alive==0)
{
printf("\nMov R%d,%s",reg,var[vc-1]);
preg[reg].alive=1;
}
op=basic[j][strlen(var[vc-1])];
substring(basic[j],strlen(var[vc-1])+1,strlen(basic[j]));
getvar(basic[j],var[vc++]);
switch(op)
{
case '+': printf("\nAdd"); break;
case '-': printf("\nSub"); break;
case '*': printf("\nMul"); break;
case '/': printf("\nDiv"); break;
}
flag=1;
for(k=0;k<=reg;k++)
{
if(strcmp(preg[k].var,var[vc-1])==0)
{
printf("R%d, R%d",k,reg);
preg[k].alive=0;
flag=0;
break;
}
}
if(flag)
{
printf(" %s,R%d",var[vc-1],reg);
printf("\nMov %s,R%d",fstr,reg);
}
strcpy(preg[reg].var,var[vc-3]);
getch();}}

You might also like