Lab Manual CD
Lab Manual CD
Language
%{
int COMMENT=0;
%}
identifier [a-zA-Z][a-zA-Z0-9]*
%%
#.* {printf("\n%s is a preprocessor directive",yytext);}
int |
float |
char |
double |
while |
for |
struct |
typedef |
do |
if |
break |
continue |
void |
switch |
return |
else | /*----*/
goto {printf("\n\t%s is a keyword",yytext);}
\( {if(!COMMENT)printf("\nFUNCTION \n\t%s",yytext);}
\{ {if(!COMMENT)printf("\n BLOCK BEGINS");}
\} {if(!COMMENT)printf("\n BLOCK ENDS");}
{identifier}(\[[0-9]*\])? {if(!COMMENT) printf("\n %s
IDENTIFIER",yytext);}
\".*\" {if(!COMMENT)printf("\n\t %s is a STRING",yytext);}
[0-9]+ {if(!COMMENT) printf("\n %s is a NUMBER",yytext);}
\)(\;)? {if(!COMMENT)printf("\n\t");ECHO;printf("\n");}
\( ECHO;
= {if(!COMMENT)printf("\n\t %s is an ASSIGNMENT
OPERATOR",yytext);}
\<= |
\>= |
\< |
== |
\> {if(!COMMENT) printf("\n\t%s is a RELATIONAL
OPERATOR",yytext);}
%%
int main(int argc, char **argv)
{
FILE *file;
file=fopen("var.c","r");
if(!file)
{
printf("could not open %s\n",argv[1]);
exit(0);
}
yyin=file;
yylex();
printf("\n");
return 0;
}
int yywrap()
{
return 1;
}
var.c:-
#include<stdio.h>
main()
{
int a,b;
}
Output:-
$ flex filename.l
$ gcc lex.yy.c
$ a.exe
#include<stdio.h> is a preprocessor directive
main IDENTIFIER
FUNCTION
(
)
BLOCK BEGINS
int is a keyword
a IDENTIFIER,
b IDENTIFIER;
BLOCK ENDS
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
int isKeyword(char* str)
{ //This function returns true if the string is a keyword, else return false.
if (!strcmp(str, "auto") || !strcmp(str, "default")
|| !strcmp(str, "signed") || !strcmp(str, "enum")
||!strcmp(str, "extern") || !strcmp(str, "for")
|| !strcmp(str, "register") || !strcmp(str, "if")
|| !strcmp(str, "else") || !strcmp(str, "int")
|| !strcmp(str, "while") || !strcmp(str, "do")
|| !strcmp(str, "break") || !strcmp(str, "continue")
|| !strcmp(str, "double") || !strcmp(str, "float")
|| !strcmp(str, "return") || !strcmp(str, "char")
|| !strcmp(str, "case") || !strcmp(str, "const")
|| !strcmp(str, "sizeof") || !strcmp(str, "long")
|| !strcmp(str, "short") || !strcmp(str, "typedef")
|| !strcmp(str, "switch") || !strcmp(str, "unsigned")
|| !strcmp(str, "void") || !strcmp(str, "static")
|| !strcmp(str, "struct") || !strcmp(str, "goto")
|| !strcmp(str, "union") || !strcmp(str, "volatile"))
return 1;
return 0;
}
void main()
{
int i,m,j;
char b[50],temp[30];
printf("Enter the string : ");
scanf("%[^\n]s",b);
for(i=0;i<strlen(b);i++)
{
if(isspace(b[i])|| b[i]==';')
{
if(isKeyword(temp)){
printf("Keyword : %s\n",temp);
memset(temp, 0, j);
}
else{
if(temp[0]!='\0')
{
printf("Identifier : %s\n",temp);
memset(temp, 0, j);
}
}
j=0;
continue;
}
else if(isalpha(b[i]))
{
temp[j]=b[i];
j++;
}
else if(isdigit(b[i]))
{
m=(b[i]-'0');
i=i+1;
while(isdigit(b[i]))
{
m=m*10+(b[i]-'0');
i++;
}
i=i-1;
printf("Constant : %d\n",m);
}
else
{
if (b[i] >= 33 || b[i] <=47)
{
if(isKeyword(temp)){
printf("Keyword : %s\n",temp);
memset(temp, 0, j);
} //If if it is an operator, it lies between
33 and 47 (ascii codes)
else
{
if(temp[0]!='\0'){ //a=10, so we check before an
operator for an identifier.
printf("Identifier : %s\n",temp);
memset(temp, 0, j);
j=0;
}
}
switch(b[i]){ //not all symbols are operators, only arithmetic operators are
printed.
case '+': printf("Operator : %c\n", b[i]); break;
case '-': printf("Operator : %c\n", b[i]); break;
case '*': printf("Operator : %c\n", b[i]); break;
case '/': printf("Operator : %c\n", b[i]); break;
case '%': printf("Operator : %c\n", b[i]); break;
case '=': printf("Operator : %c\n", b[i]); break;
}
}
}
}
}
Output:-
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
int i=0,top=0;
char stack[20],ip[20];
void push(char c)
{
if(top>=20)
printf("stack overflow");
else
stack[top++]=c;
}
void pop(void)
{
if(top<0)
printf("stack underflow");
else
top--;
}
void error(void){
printf("\nsyntax error\n");
exit(0);
}
int main()
{
int n;
printf("the given grammar is \n\n");
printf("E->TE' \n");
printf("E'->+TE'|epsilon \n");
printf("T->FT' \n");
printf("T'->*FT'| epsilon \n");
printf("F->(E)|d \n\n");
printf("enter the string to be parsed:\n");
scanf("%s",ip);
n=strlen(ip);
ip[n]='$';
ip[n+1]='\0';
push('$');
push('E');
while(ip[i]!='\0')
{
if(ip[i]=='$' && stack[top-1]=='$')
{
printf("\n\n succesfully parsing of string\n");
return 1;
}
else
if(ip[i]==stack[top-1])
{
printf("\n match of
%c",ip[i]);
i++;
pop();
}
else
{
Output:-
E->TE'
T->FT'
F->d
match of d
T'->*FT'
match of *
F->d
match of d
T'->epsilon
E'->+TE'
match of +
T->FT'
F->d
match of d
T'->epsilon
T'->epsilon
#include<stdio.h>
#include<string.h>
void pm();
void plus();
void div();
int i,ch,j,l,addr=100;
char ex[10],exp[10],exp1[10],exp2[10],id1[5],op[5],id2[5];
void main()
{
while(1)
{
printf("\n1.assignment\n2.arithmetic\n3.relational\n4.Exit\nEnter the choice:");
scanf("%d",&ch);
switch(ch)
{
case 1:
printf("\nEnter the expression with assignment operator:");
scanf("%s",exp);
l=strlen(exp);
exp2[0]='\0';
i=0;
while(exp[i]!='=')
{
i++;
}
strncat(exp2,exp,i);
strrev(exp);
exp1[0]='\0';
strncat(exp1,exp,l-(i+1));
strrev(exp1);
printf("Three address code:\ntemp=%s\n%s=temp\n",exp1,exp2);
break;
case 2:
printf("\nEnter the expression with arithmetic operator:");
scanf("%s",ex);
strcpy(exp,ex);
l=strlen(exp);
exp1[0]='\0';
for(i=0;i<l;i++)
{
if(exp[i]=='+'||exp[i]=='-')
{
if(exp[i+2]=='/'||exp[i+2]=='*')
{
pm();
break;
}
else
{
plus();
break;
}
}
else if(exp[i]=='/'||exp[i]=='*')
{
div();
break;
}
}
break;
case 3:
printf("Enter the expression with relational operator");
scanf("%s%s%s",&id1,&op,&id2);
if(((strcmp(op,"<")==0)||(strcmp(op,">")==0)||(strcmp(op,"<=")==0)||(strcmp(op,"
>=")==0)||(strcmp(op,"==")==0)||(strcmp(op,"!=")==0))==0)
printf("Expression is error");
else
{
printf("\n%d\t if %s%s%s goto %d",addr,id1,op,id2,addr+3);
addr++;
printf("\n%d\t T:=0",addr);
addr++;
printf("\n%d\t goto %d",addr,addr+2);
addr++;
printf("\n%d\t T:=1",addr);
}
break;
case 4:
exit(0);
}
}
}
void pm()
{
strrev(exp);
j=l-i-1;
strncat(exp1,exp,j);
strrev(exp1);
printf("Three address
code:\ntemp=%s\ntemp1=%c%ctemp\n",exp1,exp[j+1],exp[j]);
}
void div()
{
strncat(exp1,exp,i+2);
printf("Three address
code:\ntemp=%s\ntemp1=temp%c%c\n",exp1,exp[i+2],exp[i+3]);
}
void plus()
{
strncat(exp1,exp,i+2);
printf("Three address
code:\ntemp=%s\ntemp1=temp%c%c\n",exp1,exp[i+2],exp[i+3]);
}
Output:-
1.assignment
2.arithmetic
3.relational
4.Exit
Enter the choice:2
Enter the expression with arithmetic operator:a+b-c
Three address code:
temp=a+b
temp1=temp-c
1.assignment
2.arithmetic
3.relational
4.Exit
Enter the choice:2
1.assignment
2.arithmetic
3.relational
4.Exit
Enter the choice: 4
Output:-
enter the input string:i+i*i
stack input
+i*i$
i*i$
*i$
i$
$
SUCCESS
5] Design LALR bottom up parser for the given language
<parser.l>
%{
#include<stdio.h>
#include "y.tab.h"
%}
%%
[0-9]+ {yylval.dval=atof(yytext);
return DIGIT;
}
\n|. return yytext[0];
%%
<parser.y>
%{
/*This YACC specification file generates the LALR parser for the program
considered in experiment 4.*/
#include<stdio.h>
%}
%union
{
double dval;
}
%token <dval> DIGIT
%type <dval> expr
%type <dval> term
%type <dval> factor
%%
line: expr '\n' {
printf("%g\n",$1);
}
;
expr: expr '+' term {$$=$1 + $3 ;}
| term
;
term: term '*' factor {$$=$1 * $3 ;}
| factor
;
factor: '(' expr ')' {$$=$2 ;}
| DIGIT
;
%%
int main()
{
yyparse();
}
yyerror(char *s)
{
printf("%s",s);
}
Output:
$lex parser.l
$yacc –d parser.y
$cc lex.yy.c y.tab.c –ll –lm
$./a.out
2+3
5.0000