EX - NO:6: Implementation of Type Checking
EX - NO:6: Implementation of Type Checking
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#inlcude<string.h>
#include<stdlib.h>
char *type(char[],int);
void main()
{
char a[10][10],b[10][10],mess[20],mess1[20];
int i,l;
clrscr();
printf("\nint a,b;\nint c=a+b\n");
printf(\n\nEnter a value for a:");
scanf("%s",a);
l=strlen(a);
printf("\n a is :");
strcpy(mess,type(a,l));
printf("%s",mess);
printf("\n\nEnter a value for b\n:");
scanf("%s",b);
l=strlen(b);
printf("\n b is :");
strcpy(mess1,type(b,l));
printf("%s",mess1);
if(strcmp(mess,"int")==0&&strcmp(mess1,"int")==0)
printf("\nNo type error");
else
printf("\n Type error");
getch();
}
char *type(char x[],int m)
{
int i;
char mes[20];
for(i=0;i<m;i++)
{
if(isalpha(x[i]))
{
strcpy(mes,"Alpha numberic");
goto x;
}
else if(x[i]=='.')
{
strcpy(mes,"float");
goto x;
}
}
strcpy(mes,"int");
x:
return mes;
}
OUTPUT:
int a,b;
int c=a+b;
Enter a value for a:10
a is :int
Enter a value for b:10
b is :int
No type error
ALGORITHM:
LEX specification:
1. In declaration part: Include necessary header files.
a. Declare and set 1 to lineno.
2. Declare identifier and number.
3. In rule part:
a. token main() then return MAIN
b. token if then return IF
c. token else then return ELSE
d. token while return WHILE
e. int or char or float then return TYPE
f. identifier then yytext copied to yylval.var return VAR
g. number then yytext copied to yylval.var return NUM
h. <,>,<= ,>=,== then yytext is copied to yylval.var return RELOP
i. [ \t]
j. \n then Lineno is incremented by 1
k. . return yytext[0].
YACC Specification:
1. In declaration part: Include necessary header files
2. Declare and define structure for quad with member variables – op[],arg1[],arg2[]
and result[] and stack with member variables- items[],top.
3. Declare the variables
4. union declare var[] as character type.
5. token declare <var> NUM VAR RELOP
6. token MAIN IF ELSE WHILE TYPE
7. type <var> EXPR ASSIGNMENT CONDITION IFST ELSEST WHILELOOP
8. left ‘-‘ ‘+’ ‘*’ ‘/’
9. PROGRAM: MAIN BLOCK
10. BLOCK:{ CODE }
11. CODE: BLOCK or STATEMENT CODE or STATEMENT
12. STATEMENT: DESC ‘;’ or ASSIGNMENT ’;’ CONST or WHILEST
13. DESCT: TYPE VARLIST
14. VARLIST: VAR ‘,’ VARLIST or VAR
15. ASSIGNMENT: VAR ‘*’ EXPR then copy “*” to QUAD[index].op, copy “$3” to
QUAD[index].arg1 , copy “” to QUAD[index].arg2, copy $1 to QUAD[index].result.
16. EXPR : EXPR ‘+’ EXPR then AddQuadruple(“+”,$1,$3,$$) Similarly for -,*./
a. Or ‘-‘ EXPR then AddQuadruple(“UMIN”,$2,””,$$)
b. Or’(‘ EXPR ‘)’then copy $2 to $1
c. Or VAR or NUM
PROGRAM:
%{
#include"y.tab.h"
#include<stdio.h>
#include<string.h>
int LineNo=1;
%}
identifier [a-zA-Z][_a-zA-Z0-9]*
number [0-9]+|([0-9]*\.[0-9]+)
%%
main\(\) return MAIN;
if return IF;
else return ELSE;
while return WHILE;
int | char |
float return TYPE;
{identifier} {strcpy(yylval.var,yytext);
return VAR;}
{number} {strcpy(yylval.var,yytext);
return NUM;}
\ < | \ > | \ >= | \ <= |
== {strcpy(yylval.var,yytext);
return RELOP;}
[ \t] ;
\n LineNo++;
. return yytext[0];
%%
//bnf.y
%{
#include<string.h>
#include<stdio.h>
struct quad{
char op[5];
char arg1[10];
char arg2[10];
char result[10];
}QUAD[30];
struct stack{
int items[100];
int top;
}stk;
int Index=0,tIndex=0,StNo,Ind,tInd;
extern int LineNo;
%}
%union{
char var[10];
}
%token <var> NUM VAR RELOP
%token MAIN IF ELSE WHILE TYPE
%type <var> EXPR ASSIGNMENT CONDITION IFST ELSEST WHILELOOP
%left '-' '+'
%left '*' '/'
%%
PROGRAM : MAIN BLOCK
;
BLOCK: '{' CODE '}'
;
CODE: BLOCK
| STATEMENT CODE | STATEMENT
;
STATEMENT: DESCT ';'
| ASSIGNMENT ';' | CONDST | WHILEST
;
DESCT: TYPE VARLIST
;
VARLIST: VAR ',' VARLIST
| VAR
;
ASSIGNMENT: VAR '=' EXPR{
strcpy(QUAD[Index].op,"=");
strcpy(QUAD[Index].arg1,$3);
strcpy(QUAD[Index].arg2,"");
strcpy(QUAD[Index].result,$1);
strcpy($$,QUAD[Index++].result); } ;
EXPR: EXPR '+' EXPR {AddQuadruple("+",$1,$3,$$);}
| EXPR '-' EXPR {AddQuadruple("-",$1,$3,$$);}
| EXPR '*' EXPR {AddQuadruple("*",$1,$3,$$);}
| EXPR '/' EXPR {AddQuadruple("/",$1,$3,$$);}
| '-' EXPR {AddQuadruple("UMIN",$2,"",$$);}
| '(' EXPR ')' {strcpy($$,$2);}
| VAR | NUM
;
CONDST: IFST{
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
}
| IFST ELSEST
;- INSERT --
IFST: IF '(' CONDITION ')' {
strcpy(QUAD[Index].op,"==");
strcpy(QUAD[Index].arg1,$3);
strcpy(QUAD[Index].arg2,"FALSE");
strcpy(QUAD[Index].result,"-1");
push(Index);
Index++;
}
BLOCK {
strcpy(QUAD[Index].op,"GOTO");
strcpy(QUAD[Index].arg1,"");
strcpy(QUAD[Index].arg2,"");
strcpy(QUAD[Index].result,"-1");
push(Index);
Index++; }
;- INSERT --
ELSEST: ELSE{
tInd=pop();
Ind=pop();--
push(tInd);
sprintf(QUAD[Ind].result,"%d",Index);
}
BLOCK{
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
}; INSERT --
CONDITION: VAR RELOP VAR {AddQuadruple($2,$1,$3,$$);
StNo=Index-1;
}
| VAR | NUM
;
WHILEST: WHILELOOP{
Ind=pop();
sprintf(QUAD[Ind].result,"%d",StNo);
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
}
;
WHILELOOP: WHILE '(' CONDITION ')' {
strcpy(QUAD[Index].op,"==");
strcpy(QUAD[Index].arg1,$3);
strcpy(QUAD[Index].arg2,"FALSE");
strcpy(QUAD[Index].result,"-1");
push(Index);
Index++;
}
BLOCK {
strcpy(QUAD[Index].op,"GOTO");
strcpy(QUAD[Index].arg1,"");
strcpy(QUAD[Index].arg2,"");
push(Index);
Index++;
}
;
%%
extern FILE *yyin;
int main(int argc,char *argv[]) {
FILE *fp;
int i;
if(argc>1){
fp=fopen(argv[1],"r");
if(!fp) {
printf("\n File not found");
exit(0);
}
yyin=fp;
}
yyparse();
printf("\n\t\t Pos Operator Arg1 Arg2 Result");
for(i=0;i<Index;i++) {
printf("\n\t\t %d\t %s\t %s\t %s\t %s",i,QUAD[i].op,QUAD[i].arg1,QUAD[i].arg2,QU
AD[i].result);
}
printf("\n\n");
return 0;
}
void push(int data){
stk.top++;
if(stk.top==100)
{
printf("\n Stack overflow\n");
exit(0);
}
stk.items[stk.top]=data;
}
int pop()
{
int data;
if(stk.top==-1){
printf("\n Stack underflow\n");
exit(0);
}
data=stk.items[stk.top--];
return data;
}
void AddQuadruple(char op[5],char arg1[10],char arg2[10],char result[10])
{
strcpy(QUAD[Index].op,op);
strcpy(QUAD[Index].arg1,arg1);
strcpy(QUAD[Index].arg2,arg2);
sprintf(QUAD[Index].result,"t%d",tIndex++);
strcpy(result,QUAD[Index++].result);
}
yyerror() {
printf("\n Error on line no:%d",LineNo);
}
INPUT:
main()
{
int a,b,c;
if ( a < b )
{ a=a+b; }
while ( a < b)
{ a=a+b; }
if ( a <= b )
{ c=a-b; }
else
{ c=a+b; }
}
OUTPUT:
[814413104001@telnet compiler]$lex bnf.l
[814413104001@telnet compiler]$yacc –d bnf.y
[814413104001@telnet compiler]$gcc lex.yy.c y.tab.c –ll -lm
[814413104001@telnet compiler]$ ./a.out test.c
0 < a b t0
1 == t0 FALSE 5
2 + a b t1
3 = t1 a
4 GOTO 5
5 < a b t2
6 == t2 FALSE 10
7 + a b t3
8 = t3 a
9 GOTO 5
10 <= a b t4
11 == t4 FALSE 15
12 - a b t5
13 = t5 c
14 GOTO 17
15 + a b t6
16 = t6 c
EX.NO:9 CONSTRUCTION OF DAG
#include<stdio.h>
#define N 8
typedef struct node node;
struct node
{
int count;
node *next;
};
node graph[N];
void buildGraph(int a[][2],int edges)
{
int i;
for(i=0;i<N;i++)
{
graph[i].count=0;
graph[i].next=NULL;
}
for(i=0;i<edges;++i)
{
node *ptr=(node*)malloc(sizeof(node));
ptr->count=a[i][1];
ptr->next=graph[a[i][0]].next;
graph[a[i][0]].next=ptr;
graph[a[i][1]].count++;
}
}
void printGraph()
{
int i;
node *ptr;
for(i=0;i<N;i++)
{
node *ptr;
printf("%d:pred=%d:connected to",i,graph[i].count);
for(ptr=graph[i].next;ptr;ptr=ptr->next)
printf("%d",ptr->count);
printf("\n");
}
}
void main()
{
int a[8][2],i,j;
clrscr();
printf("\nEnter the edges between nodes");
for(i=0;i<8;i++)
{
for(j=0;j<2;j++)
{
scanf("%d",&a[i][j]);
}
}
buildGraph(a,8);
printf(“\nThe DAG for(a+b)*c+((a+b)+e):\n");
printGraph();
getch();
}
OUTPUT:
Enter the edges b/w nodes
01
02
13
14
23
27
35
36
Thus the above program to convert the BNF rules into YACC form and write code
to generate Abstract Syntax Tree was executed and output was verified.