CC_Lab4

Extending the Syntax Analyser for your mini-compiler

Problem which need to be done:

To begin with, finish off the implementations of insert() and lookup() functions as instructed in your previous experiment and test your implementations for the given test cases in the given extended version of the problem. You may have to use conflict resolution rules to handle the following exercises. Further, modify your lex program in tandem whenever required. In the following problems, you could assume the operands to be variables.

  • 1. The program given in the previous lab does type checking (for data types int and char) given you implement the functions insert() and lookup() properly. Modify the given program to incorporate the same for float and double data types too.

  • 2. Incorporate binary operator ˆ (exponent) into your compiler. Note that the exponent operator is a right associative operator and has higher precedence than all those arithmetic operators (+, −, ∗, /) that are already defined in your compiler (refer to these definitions and incorporate the modifications).

  • 3. Incorporate unary increment ++ and decrement −− operators too (are of highest precedence).

  • 4. Do the same for modulo operator (%), has the same precedence as * and / operators. In this case, further, we are supposed to ensure that both operands are of type “int”.

  • 5. In the given implementation, the input C file is expected to have all declaration statements in the beginning, followed by program statements. Rewrite your grammar to let the user to have declarative and program statements in any arbitrary interleaved order in their input C program.

  • 6. Update your rules section to incorporate logical expressions in your program. A logical expression (composite) could be defined as a composition of simple logical expressions connected by any of the binary connectives && or ||, or the unary connective !(not). Further, each simple logical expression is one of the “binary” comaprison operators in the set {≥, ≤, <, >, ! =, ==} together with operands (Eg: (x ≥ y)&&!(y == z)||(ptr! = NULL)).

  • 7. Incorporate if(logical expresion){...}else{...} construct in to your compiler.

Project.l

%option yylineno


%{

#include<stdio.h>

#include<string.h>

#include"y.tab.h"

#include<math.h>

extern int var_count;


%}


%%

"#include<stdio.h>" {return HEADER;}

"if" {printf("usage of keyword \"%s\" is prohibited\n",yytext);exit(0);}

"int" {yylval.data_type=0;return INT;}

"char" {yylval.data_type=1; return CHAR;}

"main" {return MAIN;}

"(" {return LB;}

")" {return RB;}

"{" {return LCB;}

"}" {return RCB;}

"," {return COMA;}

";" {return SC;}

[+] {return PLUS;}

[-] {return MINUS;}

[*] {return MUL;}

[/] {return DIV;}

"=" {return EQ;}

[a-z]+ {strcpy(yylval.var_name,yytext);return VAR;}

[\n\t ]+ {/*new line or space*/}

. {printf("invalid character sequence %s\n",yytext); exit(0);}

%%



int yywrap(void)

{

return 1;

}


Project.y

%{

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

int yylex(void);

int yyerror(const char *s);

int success = 1;

int current_data_type;

int expn_type=-1;

int temp;

struct symbol_table{char var_name[30]; int type;}var_list[20];

int var_count=-1;

extern int lookup_in_table(char var[30]);

extern void insert_to_table(char var[30], int type);

%}


%union{

int data_type;

char var_name[30];

}

%token HEADER MAIN LB RB LCB RCB SC COMA VAR EQ PLUS MINUS MUL DIV EXP UPLUS UMINUS


%left PLUS MINUS

%left MUL DIV


%token<data_type>INT

%token<data_type>CHAR

%token<data_type>FLOAT

%token<data_type>DOUBLE


%type<data_type>DATA_TYPE

%type<var_name>VAR

%start prm


%%

prm : HEADER MAIN_TYPE MAIN LB RB LCB BODY RCB {

printf("\n parsing successful\n");

}

BODY : DECLARATION_STATEMENTS PROGRAM_STATEMENTS

DECLARATION_STATEMENTS : DECLARATION_STATEMENT DECLARATION_STATEMENTS

{

printf("\n Declaration section successfully parsed\n");

}

| DECLARATION_STATEMENT

DECLARATION_STATEMENT: DATA_TYPE VAR_LIST SC {}

VAR_LIST : VAR COMA VAR_LIST {

insert_to_table($1,current_data_type);

}

| VAR {

insert_to_table($1,current_data_type);

}


MAIN_TYPE : INT

DATA_TYPE : INT {

$$=$1;

current_data_type=$1;

}

| CHAR {

$$=$1;

current_data_type=$1;

}

| FLOAT {}

| DOUBLE {}



PROGRAM_STATEMENTS : PROGRAM_STATEMENT PROGRAM_STATEMENTS

{

printf("\n program statements successfully parsed\n");

}

| PROGRAM_STATEMENT


PROGRAM_STATEMENT : VAR EQ A_EXPN SC {

if((temp=lookup_in_table($1))!=-1)

{

if(expn_type==-1)

{

expn_type=temp;

}else if(expn_type!=temp)

{

printf("\ntype mismatch in the expression\n");

exit(0);

}

}else

{

printf("\n variable \"%s\" undeclared\n",$1);exit(0);

}

expn_type=-1;

}

A_EXPN :A_EXPN PLUS A_EXPN

|A_EXPN MINUS A_EXPN

|A_EXPN MUL A_EXPN

|A_EXPN DIV A_EXPN

| LB A_EXPN RB

| VAR {

if((temp=lookup_in_table($1))!=-1)

{

if(expn_type==-1)

{

expn_type=temp;

}else if(expn_type!=temp)

{

printf("\ntype mismatch in the expression\n");

exit(0);

}

}else

{

printf("\n variable \"%s\" undeclared\n",$1);exit(0);

}

}


%%


int lookup_in_table(char var[30])

{

return -1;

}

void insert_to_table(char var[30], int type)

{

}

int main()

{

yyparse();

/* if(success)

printf("Parsing Successful\n");*/

return 0;

}


int yyerror(const char *msg)

{

extern int yylineno;

printf("Parsing Failed\nLine Number: %d %s\n",yylineno,msg);

success = 0;

return 0;

}



input1.c

#include<stdio.h>

int main()

{

int varone,vartwo,varthree;

char testone,testtwo,testthree;

testone=testtwo+testthree/(testone*testtwo);

vartwo=varone*varone+varthree;

}


input2.c

#include<stdio.h>

int main()

{

int varone,vartwo,varthree;

char testone, testtwo,testthree;

testone=testtwo+testthree/(testone*testtwo);

vartwo=varone*varone^varthree+++varone;

}


input3.c

#include<stdio.h>

int main()

{

int varone,vartwo,varthree;

char testone, testtwo,testthree;

testone=vartwo+testthree/(testone*testtwo);

vartwo=varone*varone+varfive;

}


input4.c

#include<stdio.h>

int main()

{

int varone,vartwo,varthree;

char testone, testtwo,testthree;

testone=testtwo+testthree/(testone*testtwo);

vartwo=varone*varfour+varfive;

}


input5.c

#include<stdio.h>

int main()

{

int varone,vartwo,varthree,varfour;

char testone, testtwo,testthree;

float x,y;

testone=testtwo+testthree/(testone*testtwo);

vartwo=varone*varfour;

varone=vartwo%x;


}


input6.c

#include<stdio.h>

int main()

{

int varone,vartwo,varthree,varfour;

char testone, testtwo,testthree;

float x,y;

double z;

testone=testtwo+testthree/(testone*testtwo);

vartwo=varone*varfour;

x=x*y+y;


}


input7.c

#include<stdio.h>

int main()

{

int varone,vartwo,varthree,varfour;

char testone, testtwo,testthree;

float x,y;

testone=testtwo+testthree/(testone*testtwo);

vartwo=varone*varfour;

x=x*y+y;

int z;

if(x>=y && y<=z)

{

z=x;

}

else

{

z=y;

}

}