Tuesday 23 February 2016

Experiment No : 04




4. Generate YACC specification for a few syntactic categories.
a) Program to recognize a valid arithmetic expression that usesoperator +, - , * and /.
b) Program to recognize a valid variable which starts with a letterfollowed by any number of letters or digits.
 d)Implementation of Calculator using LEX and YACC


4.Generate YACC specification for a few syntactic categories.
a) Program to recognize a valid arithmetic expression that uses operator +, - , * and /.


Program name:arith_id.l

%{
/* This LEX program returns the tokens for the expression */
#include “y.tab.h”
%}

%%
“=” {printf(“\n Operator is EQUAL”);}
“+” {printf(“\n Operator is PLUS”);}
“-“ {printf(“\n Operator is MINUS”);}
“/” {printf(“\n Operator is DIVISION”);}
“*” {printf(“\n Operator is MULTIPLICATION”);}

[a-z A-Z]*[0-9]* {
printf(“\n Identifier is %s”,yytext);
return ID;
}
return yytext[0];
\n return 0;
%%

int yywrap()
{
return 1;
}


Program Name : arith_id.y

%{
#include
/* This YYAC program is for recognizing the Expression */
%}
%%
statement: A’=’E
| E {
printf(“\n Valid arithmetic expression”);
$$ = $1;
};

E: E’+’ID
| E’-’ID
| E’*’ID
| E’/’ID
| ID
;
%%
extern FILE *yyin;
main()
{
do
{
yyparse();
}while(!feof(yyin));
}

yyerror(char*s)
{
}

Output:

[root@localhost]# lex arith_id.1
[root@localhost]# yacc –d arith_id.y
[root@localhost]# gcc lex.yy.c y.tab.c
[root@localhost]# ./a.out
x=a+b;

Identifier is x
Operator is EQUAL
Identifier is a
Operator is PLUS
Identifier is b


b) Program to recognise a valid variable which starts with a letter
followed by any number of letters or digits.

Program name: variable_test.l

%{
/* This LEX program returns the tokens for the Expression */
#include "y.tab.h"
%}
%%
"int " {return INT;}
"float" {return FLOAT;}
"double" {return DOUBLE;}
[a-zA-Z]*[0-9]*{
printf("\nIdentifier is %s",yytext);
return ID;
}
return yytext[0];
\n return 0;
int yywrap()
{
return 1;
}



Program name: variable_test.y

%{
#include
/* This YACC program is for recognising the Expression*/
%}
%token ID INT FLOAT DOUBLE
%%
D;T L
;
L:L,ID
|ID
;
T:INT
|FLOAT
|DOUBLE
;
%%
extern FILE *yyin;
main()
{
do
{
yyparse();
}while(!feof(yyin));
}
yyerror(char*s)
{
}

Output:

[root@localhost]# lex variable_test.I
[root@localhost]# yacc –d variable_test.y
[root@localhost]# gcc lex.yy.c y.tab.c
[root@localhost]# ./a.out
int a,b;

Identifier is a
Identifier is b[root@localhost]#













c) Program to recognise the gramar(anb where n>=10)
Program name: anb.l

%{
/*Lex Program for anb(n>=10)*/
%}
%%
a {return A;}
b {return B;}
. {return yytext[10];}
\n return('\n');
%%
int yywrap()
{
return 1;
}

Program name:anb.y

%{
/*YACC program for recognising anb(n>=10)*/
%}
%token A B
%%
stmt:A A A A A A A A A A anb'\n'{printf("\n Valid string");
return 0;
}
;
anb:A anb
|A B
;
%%
main()
{
printf("\nEnter some valid string\n");
yyparse();
}

int yyerror(char*s)
{
printf("\nInvalid string\n");
}


Output:

[root@localhost]# lex anb.1
[root@localhost]# yacc -d anb.y
[root@localhost]# gcc lex.yy.c y.tab.c
[root@localhost]# ./a.out


Enter some valid string
aaaaaaaaab

Invalid string
[root@localhost]# ./a.out

Enter some valid string
aaaaaaaaaaab

Valid string [root@localhost]#


d) Implementation of Calculator using LEX and YACC

Program name:calci.l

%{
#include "y.tab.h" /*defines the tokens*/
#include ,math.h.
%}
%%
/*To recognise a valid number*/
([0-9] + |([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) {yylval.dval = atof(yytext);
return NUMBER;}
/*For log no | Log no (log base 10)*/
log | LOG {return LOG;}

/*For ln no (Natural Log)*/
ln {return nLOG;}

/*For sin angle*/
sin | SIN {return SINE;}

/*For cos angle*/
cos | COS {return COS;}

/*For tan angle*/
tan | TAN {return TAN;}
/*For memory*/
mem {return MEM;}

[\t] ; /*Ignore white spaces*/

/*End of input*/
\$ {return 0;}

/*Catch the remaining and return a single character token to
the parser*/
\n| return yytext[0];
%%


Program Name : calci.y

%{
double memvar;
%}

/*To define possible symbol types*/
%token NUMBER
%token MEM
%token LOG SINE nLOG COS TAN

/*Defining the precedences and associativity*/
%left ‘-’ ‘+’ /*Lowest precedence*/
%left ‘*’ ‘/’
%right ‘^’
%left LOG SINE nLOG COS TAN /*Highest precence*/

/*No associativity*/
%nonassoc UMINUS /*Unary Minus*/

/*Sets the type for non-terminal*/
%type expression
%%
/*Start state*/
start: statement ‘\n’
| start statement ‘\n’
;

/*For storing the answer(memory)*/
statement: MEM’=’ expression {memvar=$3;}
| expression {printf(“Answer = %g\n”,$1);}
; /*For printing the Answer*/




/*For binary arithmetic operations*/
expression: expression ‘+’ expression {$$ = $1 + $3;}
| expression ‘-’ expression {$$ = $1 - $3;}
| expression ‘*’ expression {$$ = $1 * $3;}
| expression ‘/’ expression
{ /*Tohandle divide by zero case*/
If($3 == 0)
yyerror(“divide by zero”);
else
$$ = $1 / $3;
}
| expression ‘^’ expression {$$ = pow($1,$3);}
;


/*For unary operators*/
expression: ‘-’expression %prec UMINUS {$$ = -$2;}
/*%prec UMINUS signifies that unary minus should have the highest precedence*/
| ‘(’ expression ‘)’ {$$ = $2}
| LOG expression {$$ = log($2)/log(10);}
| nLOG expression {$$ = log($2);}
*/Trigonometric functions*/
| SINE expression {$$ = sin($2 * 3.141592654 / 180);}
| COS expression {$$ = cos($2 * 3.141592654 / 180);}
| TAN expression {$$ = tan($2 * 3.141592654 / 180);}
| NUMBER {$$ = $1;}
| MEM {$$ = $1;}
; /*Retrieving the memory contents*/
%%
main()
{
printf(“Enter the expression:”);
yyparse();
}
int yyerror(char *error)
{
fprintf(stderr,”%s\n”,error);
}


Output:

The output of the program can be obtained by following commands
[root@localhost]]# lex calci.l
[root@localhost]]# yacc –d calci.y
[root@localhost]]# cc y.tab.c lexyy.c –ll –ly –lm
[root@localhost]]# ./a.out

Enter the expression: 2+@
Answer = 4

2 * 2 + 5 / 4
Answer = 5.25

mem = cos 45
sin 45/mem
Answer = 1

ln 10
Answer = 2.

No comments:

Post a Comment