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
%token
%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
%%
/*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