Download as pdf or txt
Download as pdf or txt
You are on page 1of 8

INPUT FILE:

int main(int a)
{
// this is a single line comment .........................
float sot, x, n, trm, eps, alt;
/*This is a Multi
Line Comment*/
x = 3.1459;
eps = 0.1;
n = 1;
sot = 1;
trm = 1;
alt = -1;
while (trm > eps)
{
trm = trm * x * x / n / (n + 1);
sot = sot + alt * trm;
alt = -alt;
n = n + 2;
}
}

LEX FILE:
%{
#include <stdio.h>
#include <string.h>
#include "y.tab.h"
int pos=0;
char linebuffer[500];
char *name;

void assign(char *n){


free(name);
name=strdup(n);
}
char *prevline;
void insert(char *s){
char *temp=s;
while (*temp!='\0'){
linebuffer[pos]=*temp;
temp++;
pos++;
}
}
struct ML {
char *name;
double value;
};

%}
Identifier [a-zA-Z]+[a-zA-Z0-9]*
Operator "+"|"*"|"-"|"="|"/"
Digit [0-9]+("."[0-9]+)?
String \".*?\"|\'.*?\'
MultiComment "/*"(.|\n)*"*/"
SingleComment \/\/.*\n
InvalidVar [0-9]+[a-zA-Z]+[a-zA-Z0-9]*
InvalidValue [0-9]+("."[0-9]+)[a-zA-Z]+|[0-9]+[a-zA-Z]+("."[0-9]+)|[0-9]+("."[a-zA-Z0-9]+)|[0-9]+("."[0-9a-zA-Z0-9]+)
%%
"while" {insert("while");return WHILE;}
"for" {insert("for");return FOR;}
"if" {insert("if");return IF;}
"else" {insert("else");return ELSE;}
"==" {insert("==");return EQ;}
"!=" {insert("!=");return NE;}
"<=" {insert("<=");return LE;}
">=" {insert(">=");return GE;}
"<" {insert("<");return LT;}
">" {insert(">");return GT;}
"int" {insert("int");return INT;}
"float" {insert("float");return FLOAT;}
"double" {insert("double");return DOUBLE;}
{Identifier} {yylval.multi=malloc(sizeof(struct ML));insert(yytext);yylval.multi->name=strdup(yytext);return IDENTIFIER;}
{Operator} {insert(yytext);return yytext[0];}
{Digit} {yylval.multi=malloc(sizeof(struct ML));insert(yytext);yylval.multi->value=atof(yytext); return NUMBER;}
{String} {printf("Lexeme = %s\tToken is STRING_LITERAL\tLine No. = %d\n", yytext, yylineno);}
{SingleComment} {yylineno++;}
{MultiComment} {
char *s = strdup(yytext);
while (*s!='\0'){
if (*s=='\n'){
yylineno++;
}
s++;
}
}
"("|")"|"["|"]"|"{"|"}"|","|";" {insert(yytext);return yytext[0];}
{InvalidVar} {printf("Error '%s' Invalid Identifier pos\n", yytext);}

{InvalidValue} {printf("Valueerror '%s' \n", yytext);}


\n {yylineno++;
pos=0;
free(prevline);
prevline=strdup(&linebuffer);
memset(linebuffer,0,sizeof(linebuffer));}
. {insert(" ");}

%%
int yywrap() { return 1; }

YACC FILE:
%{
#include <stdio.h>
#include<stdlib.h>

extern int yylineno;


extern FILE *yyin;
extern char *yytext;
extern char linebuffer[500];
extern char* prevline;

struct Node {
char * name;
char * type;
double value;
struct Node *next;
};
struct Node Symboltable[47];

void insert_t(char *n, char *t, double v) {


int found = 0;
int key = 0;
char *temp = n;

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


int ascii = (int)(*temp);
key += ascii;
temp++;
}
key=key%47;
if (Symboltable[key].name == NULL) {
Symboltable[key].name = strdup(n);
Symboltable[key].type = strdup(t);
Symboltable[key].value = v;
} else {
struct Node *ptr = &Symboltable[key];
while (ptr->next != NULL) {
if (strcmp(ptr->name, n) == 0) {
found = 1;
break;
} else {
ptr = ptr->next;
}
}
if (found == 1) {
ptr->value = v;
}
else {
struct Node *Dummy = malloc(sizeof(struct Node));
if (Dummy == NULL) {
printf("Memory allocation failed\n");
return;
}
Dummy->name = strdup(n);
Dummy->type = strdup(t);
Dummy->value = v;
ptr->next = Dummy;
}
}
}

double lookup(char *n){


int key = 0;
char *temp = n;

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


int ascii = (int)(*temp);
key += ascii;
temp++;
}
key=key%47;

if (Symboltable[key].next == NULL ) {
if (Symboltable[key].name!=NULL){
if (strcmp(Symboltable[key].name,n)==0){
return Symboltable[key].value;
}
}
}
else {
struct Node * ptr=&Symboltable[key];
while (strcmp(ptr->name,n)!=0){
ptr=ptr->next;
if (ptr->next==NULL){
return 0;
}
}
return ptr->value;
}
}
struct ML {
char *name;
double value;
struct Tree_Node *tna;
};
struct Tree_Node {
struct Tree_Node* left;
double num;
char *name;
struct Tree_Node* right;
};

struct Tree_Node *maketree(struct ML *left, struct ML *root, struct ML *right) {

struct Tree_Node *temp = (struct Tree_Node *)malloc(sizeof(struct Tree_Node));


if (root->name!=NULL){
temp->name = root->name;
}
else temp->num = root->value;

temp->left = NULL;
temp->right = NULL;

if (left != NULL) {
if (left->tna==NULL){
struct Tree_Node *temp2 = (struct Tree_Node *)malloc(sizeof(struct Tree_Node));
if(left->name!=NULL) temp2->name = left->name;
else temp2->num = left->value;
temp->left=temp2;
}
else temp->left=left->tna;
}

if (right != NULL) {
if (right->tna==NULL){
struct Tree_Node *temp3 = (struct Tree_Node *)malloc(sizeof(struct Tree_Node));

if (right->name!=NULL) temp3->name = right->name;


else temp3->num = right->value;

temp->right=temp3;
}
else temp->right=right->tna;
}

return temp;
}
void tree_traverse(struct Tree_Node *n){
if (n==NULL) return;
tree_traverse(n->left);
if (n->name!=NULL) printf("Node %s\n",n->name);
else printf("Node %f\n",n->num);
tree_traverse(n->right);
}
// struct three_address {
// char operator;
// struct ML *value1;
// struct ML *value2;
// };

// int t=0;
// struct three_address table[100];
// struct three_address* gen_code(char operator,struct ML *value1,struct ML *value2,struct ML *result){
// while (table[t]!=NULL){
// t++;
// }
// table.operator=operator;
// table.value1=value1;
// table.value2.value2;
// table.result=result;
// }
%}
%union {
struct ML *multi;
}

%token INT FLOAT DOUBLE FOR WHILE IF ELSE


%token <multi> IDENTIFIER
%token <multi> NUMBER
%token EQ NE LE GE LT GT

%type <multi> Factor


%type <multi> Term
%type <multi> Expr
%type <multi> LExpr
%type <multi> Expression

%%
Function: Type IDENTIFIER '(' ArgumentList ')' CompoundStmt
|
Type IDENTIFIER error ArgumentList ')' CompoundStmt {printf("Missing '(' \n");yyerrok;}
|
Type IDENTIFIER '(' ArgumentList error CompoundStmt {printf("Missing ')'\n");yyerrok;}
|
error IDENTIFIER '(' ArgumentList ')' CompoundStmt {printf("Return type defaults to int\n");yyerrok;}
;
ArgumentList: Argument
|
ArgumentList ',' Argument
|
ArgumentList error Argument {printf("error: expected ';', ',' or ')' before \n");yyerrok;}
|
;
Argument: Type IDENTIFIER
;
Declaration: Type IdentifierList ';'
|
Type IdentifierList error {printf("missing ; or ,\n");yyerrok;}
| error IdentifierList ';' {printf("missing or wrong datatype\n");yyerrok;}
;
Type: INT
|
FLOAT
|
DOUBLE
;
IdentifierList: IDENTIFIER ',' IdentifierList
|
IDENTIFIER
|
;
Stmt: ForStmt
|
WhileStmt
|
Expr ';'
|
IfStmt
|
CompoundStmt
|
Declaration
|
Expression ';'
|
';'
|
Expression error {printf("missing ;\n");yyerrok;}
;
ForStmt: FOR '(' Expression ';' OptExpr ';' OptExpr ')' Stmt
;
OptExpr: Expression
|
;
WhileStmt: WHILE '(' Expression ')' Stmt
|
WHILE '(' Expression error Stmt {printf("missing )\n");yyerrok;}
|
WHILE error Expression ')' Stmt {printf("missing (\n");yyerrok;}
;
IfStmt: IF '(' Expression ')' Stmt ElsePart
;
ElsePart: ELSE Stmt
|
;
CompoundStmt: '{' StmtList '}'
;
StmtList: StmtList Stmt
|
;
Expression: IDENTIFIER '=' Expression {$$->value=$3->value;insert_t($1->name,"ID",$$->value);/*printf("Value %f goes to ID %s\n ",$$-
>value,$1->name);*/
struct ML m;m.name=$1->name;$$->tna=maketree($3,&m,NULL);tree_traverse($$->tna);printf("\n");}
|
error '=' Expression {printf("Expected a expression \n");yyerrok;}
|
LExpr {$$->value=$1->value;$$->tna=$1->tna;}
;
LExpr: LExpr Compare Expr
|
Expr {$$->value=$1->value;$$->tna=$1->tna;}
;
Compare: EQ
|
NE
|
LE
|
GE
|
LT
|
GT
;
Expr: Expr '+' Term {$$->value=$1->value+$3->value;struct ML m;m.name="+";$$->tna=maketree($1,&m,$3);}
|
Expr '-' Term {$$->value=$1->value-$3->value;struct ML m;m.name="-";$$->tna=maketree($1,&m,$3);}
|
Term {$$->value=$1->value;}
;
Term: Term '*' Factor {$$->value=$1->value*$3->value;struct ML m;m.name="*";$$->tna=maketree($1,&m,$3);}
|
Term '/' Factor {if ($3->value==0) {printf("Cant't devide with zero\n"); }$$->value=$1->value/$3->value;struct ML m;m.name="/";$$-
>tna=maketree($1,&m,$3);}
|
Factor {$$->value=$1->value;$$->tna=$1->tna;}
|error '*' Factor {printf("expected expression before ‘*’ token\n");}
|error '/' Factor {printf("expected expression before ‘/’ token\n");}
;
Factor: '(' Expr ')' {$$->value=$2->value;$$->tna=$2->tna;}
|
'-' Factor {$$->value=-$2->value;struct ML m;m.name="-";$$->tna=maketree($2,&m,NULL);}
|
'+' Factor {$$->value=+$2->value;struct ML m;m.name="+";$$->tna=maketree($2,&m,NULL);}
|
IDENTIFIER {$$->value=lookup($1->name);if (lookup($1->name)){struct ML *m = malloc(sizeof(struct ML));m->value=lookup($1-
>name);$$->tna=maketree(m,$1,NULL);}else {$$->tna=maketree(NULL,$1,NULL);}}
|
NUMBER {$$->value=$1->value;$$->tna=maketree(NULL,$1,NULL);}
;
%%
void main()
{
FILE *fp;
fp=fopen("input.c","r");
if (fp == NULL) {
perror("Error opening input file");
return 1;
}
yyin=fp;
int x=yyparse();
fclose(fp);
if (x==0) printf("Parsing Successful\n");
else printf("Parsing Failed\n");
}
void yyerror(char *s) {
if (prevline!=NULL) fprintf(stderr, "Line %d: error near '%s' in line \"%s%s\"\n", yylineno,yytext,prevline,linebuffer);
else fprintf(stderr, "Line %d: error near '%s' in line \"%s\"\n", yylineno,yytext,linebuffer);
}
OUTPUT:
@DESKTOP-IA5MEHH:~/abstract_syntax_tree$ flex flex.l
@DESKTOP-IA5MEHH:~/abstract_syntax_tree$ yacc -d parser.y
parser.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
parser.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
@DESKTOP-IA5MEHH:~/abstract_syntax_tree$ gcc lex.yy.c y.tab.c -w
@DESKTOP-IA5MEHH:~/abstract_syntax_tree$ ./a.out
Node 3.145900
Node x

Node 0.100000
Node eps

Node 1.000000
Node n

Node 1.000000
Node sot

Node 1.000000
Node trm

Node 1.000000
Node -
Node alt

Node 1.000000
Node trm
Node *
Node 3.145900
Node x
Node *
Node 3.145900
Node x
Node /
Node 1.000000
Node n
Node /
Node 1.000000
Node n
Node +
Node 1.000000
Node trm

Node 1.000000
Node sot
Node +
Node -1.000000
Node alt
Node *
Node 1.000000
Node trm
Node sot

Node -1.000000
Node alt
Node -
Node alt

Node 1.000000
Node n
Node +
Node 2.000000
Node n
Parsing Successful

You might also like