0% found this document useful (0 votes)
5 views

Class Notes - Compiler Design

The document details code for a compiler that generates an abstract syntax tree and intermediate code from a given input. It includes lexer and parser specifications along with helper functions for initializing nodes in the AST and generating quadruple code. Temporaries and labels are tracked during quad code generation.

Uploaded by

komal.260186
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views

Class Notes - Compiler Design

The document details code for a compiler that generates an abstract syntax tree and intermediate code from a given input. It includes lexer and parser specifications along with helper functions for initializing nodes in the AST and generating quadruple code. Temporaries and labels are tracked during quad code generation.

Uploaded by

komal.260186
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 19

UE20CS353

COMPILER DESIGN
ASSIGNMENT 2

PART 1

ABSTRACT SYNTAX TREE


LEX FILE (lexer.l)

%{

#define YYSTYPE char*

#include <unistd.h>

#include "y.tab.h"

#include <stdio.h>

extern void yyerror(const char *); // declare the error handling


function

%}

/* Regular definitions */

digit [0-9]

letter [a-zA-Z]

id {letter}({letter}|{digit})*

digits {digit}+

1
opFraction (\.{digits})?

opExponent ([Ee][+-]?{digits})?

number {digits}{opFraction}{opExponent}

%option yylineno

%%

\/\/(.*) ; // ignore comments

[\t\n] ; // ignore whitespaces

"(" {return *yytext;}

")" {return *yytext;}

"." {return *yytext;}

"," {return *yytext;}

"*" {return *yytext;}

"+" {return *yytext;}

";" {return *yytext;}

"-" {return *yytext;}

"/" {return *yytext;}

"=" {return *yytext;}

">" {return *yytext;}

"<" {return *yytext;}

"if" {return IF;}

"else" {return ELSE;}

"{" {return *yytext;}

2
"}" {return *yytext;}

{number} {

yylval = strdup(yytext); //stores the value of the number to


be used later for symbol table insertion

return T_NUM;

{id} {

yylval = strdup(yytext); //stores the identifier to be


used later for symbol table insertion

return T_ID;

. {} // anything else => ignore

%%

Parser.y
%{

#include "abstract_syntax_tree.c"

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

void yyerror(char* s); // error handling


function

int yylex(); // declare the function


performing lexical analysis

extern int yylineno; // track the line


number

%}

3
%union // union to allow nodes to
store return different datatypes

char* text;

expression_node* exp_node;

%token <text> T_ID T_NUM IF ELSE

%type <text> RELOP

%type <exp_node> E T F START ASSGN S C SEQ

/* specify start symbol */

%start START

%%

START : SEQ {

display_exp_tree($1);

printf("\n");

YYACCEPT;

};

SEQ : S SEQ { $$=init_exp_node("seq",$1,$2,NULL);}

4
| S {$$=$1;}

S : IF '(' C ')' '{' SEQ '}' {

$$=init_exp_node(strdup("if"),$3,$6,NULL);

| IF '(' C ')' '{' SEQ '}' ELSE '{' SEQ '}' {

$$=init_exp_node(strdup("if-else"),$3,$6,$10);

| ASSGN { $$=$1;}

C : F RELOP F {

$$=init_exp_node(strdup($2),$1,$3,NULL);

RELOP : '<' { $$="<";}

| '>' { $$=">";}

| '>''=' { $$=">=";}

| '<''=' { $$="<=";}

| '=''=' { $$="==";}

| '!''=' { $$="!=";}

/* Grammar for assignment */

5
ASSGN : T_ID '=' E ';' {

$$ =
init_exp_node(strdup("="),init_exp_node(strdup($1),NULL,NULL,NULL),$3,NULL);

/* Expression Grammar */

E : E '+' T {

$$ = init_exp_node(strdup("+"),$1,$3,NULL);

| E '-' T {

$$ = init_exp_node(strdup("-"),$1,$3,NULL);

| T { $$ = $1; }

T : T '*' F {

$$ = init_exp_node(strdup("*"),$1,$3,NULL);

| T '/' F {

$$ = init_exp_node(strdup("/"),$1,$3,NULL);

| F { $$ = $1; }

F : '(' E ')' { $$ = $2; }

| T_ID {

6
$$ = init_exp_node(strdup($1),NULL,NULL,NULL);

| T_NUM {

$$ = init_exp_node(strdup($1),NULL,NULL,NULL);

%%

/* error handling function */

void yyerror(char* s)

printf("Error :%s at %d \n",s,yylineno);

/* main function - calls the yyparse() function which will in turn drive
yylex() as well */

int main(int argc, char* argv[])

yyparse();

return 0;

Abstract syntax tree.c

#include <stdio.h>

7
#include <stdlib.h>

#include <string.h>

#include "abstract_syntax_tree.h"

expression_node* init_exp_node(char* val, expression_node* left,


expression_node* mid, expression_node* right)

expression_node* node = (expression_node*)malloc(sizeof(expression_node));

node->left = left;

node->mid=mid;

node->right=right;

node->val= val;

return node;

void display_exp_tree(expression_node* exp_node)

// traversing the AST in preorder and displaying the nodes

if(exp_node == NULL) return ;

printf("%s, ",exp_node->val);

display_exp_tree(exp_node->left);

display_exp_tree(exp_node->mid);

display_exp_tree(exp_node->right);

Abstract_syntax_tree.h
typedef struct expression_node

8
struct expression_node* left;

struct expression_node* mid;

struct expression_node* right;

char* val;

}expression_node;

expression_node* init_exp_node(char* val, expression_node* left,


expression_node* middle, expression_node* right);

void display_exp_tree(expression_node* exp_node);

Output 1:

Output 2 :

Output 3

9
PART 2

ICG
Lexer.l
%{

#define YYSTYPE char*

#include <unistd.h>

#include "y.tab.h"

#include <stdio.h>

extern void yyerror(const char *); // declare the error handling function

%}

/* Regular definitions */

digit [0-9]

letter [a-zA-Z]

id {letter}({letter}|{digit})*

digits {digit}+

opFraction (\.{digits})?

opExponent ([Ee][+-]?{digits})?

number {digits}{opFraction}{opExponent}

%option yylineno

%%

\/\/(.*) ; // ignore comments

[\t\n] ; // ignore whitespaces

"<=" {return LTEQ;}

10
">=" {return GTEQ;}

"==" {return EQQ;}

"!=" {return NEQ;}

"{" {return OC;}

"}" {return CC;}

"(" {return *yytext;}

")" {return *yytext;}

"." {return *yytext;}

"," {return *yytext;}

"*" {return *yytext;}

"+" {return *yytext;}

";" {return *yytext;}

"-" {return *yytext;}

"/" {return *yytext;}

"=" {return *yytext;}

">" {return GT;}

"<" {return LT;}

{number} {

yylval = strdup(yytext); //stores the value of the number to be used


later for symbol table insertion

return T_NUM;

"if" {return T_IF;}

"else" {return T_ELSE;}

{id} {

yylval = strdup(yytext); //stores the identifier to be used


later for symbol table insertion

return T_ID;

11
. {} // anything else => ignore

%%

Parser.y
%{

#include "quad_generation.c"

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define YYSTYPE char*

void yyerror(char* s); // error handling


function

int yylex(); // declare the function


performing lexical analysis

extern int yylineno; // track the line


number

FILE* icg_quad_file;

int temp_no = 1;

int label_no=1;

%}

%token T_ID T_NUM T_IF T_ELSE GTEQ LTEQ EQQ NEQ GT LT OC CC

/* specify start symbol */

%start START

12
%nonassoc T_IF

%nonassoc T_ELSE

%%

START : S {

printf("Valid syntax\n");

YYACCEPT;

};

/* Grammar for assignment */

ASSGN : T_ID '=' E {

quad_code_gen($1, $3, "=", " ");

/* Expression Grammar */

E : E '+' T {

$$ = new_temp();

quad_code_gen($$, $1, "+", $3);

| E '-' T {

$$ = new_temp();

13
quad_code_gen($$, $1, "-", $3);

| T

T : T '*' F {

$$ = new_temp();

quad_code_gen($$, $1, "*", $3);

| T '/' F {

$$ = new_temp();

quad_code_gen($$, $1, "/", $3);

| F

F : '(' E ')' {

$$=strdup($2);

| T_ID {

$$=strdup($1);

| T_NUM {

$$=strdup($1);

14
}

S : T_IF '('C')' OC S CC {quad_code_gen($3,"","Label","");} S

| T_IF '('C')' OC S CC {

$2 = new_label();

quad_code_gen($2,"","goto","");

quad_code_gen($3,"","Label","");} T_ELSE OC S CC
{quad_code_gen($2,"","Label","");}S

| ASSGN ';' S

|'{'S'}'

C : E rel E { $$ = new_temp();

quad_code_gen($$, $1, $2, $3);

$1 = new_label();

quad_code_gen($1,$$,"if","");

$$ = new_label();

quad_code_gen($$,"","goto","");

quad_code_gen($1,"","Label","");

};

rel : GT {strcpy($$,">");}

| LT {strcpy($$,"<");}

| LTEQ {strcpy($$,"<=");}

| GTEQ {strcpy($$,">=");}

15
| EQQ {strcpy($$,"==");}

| NEQ {strcpy($$,"!=");}

%%

/* error handling function */

void yyerror(char* s)

printf("Error :%s at %d \n",s,yylineno);

/* main function - calls the yyparse() function which will in turn drive
yylex() as well */

int main(int argc, char* argv[])

icg_quad_file = fopen("icg_quad.txt","a");

fprintf(icg_quad_file,"Generated Intermediate Code \n");

yyparse();

fclose(icg_quad_file);

return 0;

Quad generation.c
#include <stdio.h>

16
#include <stdlib.h>

#include <string.h>

#include "quad_generation.h"

void quad_code_gen(char* a, char* b, char* op, char* c)

fprintf(icg_quad_file,"%s\t%s\t%s\t%s\n",op,b,c,a);

char* new_temp()

char* tempNew = (char*)malloc(sizeof(char)*4);

sprintf(tempNew,"t%d",temp_no);

temp_no++;

return tempNew;

char* new_label()

char* label = (char*)malloc(sizeof(char)*4);

sprintf(label,"L%d",label_no);

label_no++;

return label;

Quad_generation.h

17
extern FILE* icg_quad_file; //pointer to the output file

extern int temp_no; //variable to keep track of current temporary


count

extern int label_no;

void quad_code_gen(char* a, char* b, char* op, char* c);

char* new_temp();

Output 1:

Ouput 2:

18
19

You might also like