You are on page 1of 26

Ex No:1 IMPLEMENTATION OF SYMBOL TABLE USING C

AIM:
To write a program for implementing Symbol Table using C.

ALGORITHM:

Step1: Start the program for performing insert, display, delete, search and modify option in symbol table
Step2: Define the structure of the Symbol Table
Step3: Enter the choice for performing the operations in the symbol Table
Step4: If the entered choice is 1, search the symbol table for the symbol to be inserted. If the symbol is
already present, it displays “Duplicate Symbol”. Else, insert the symbol and the corresponding address in
the symbol table.
Step5: If the entered choice is 2, the symbols present in the symbol table are displayed.
Step6: If the entered choice is 3, the symbol to be deleted is searched in the symbol table.
Step7: If it is not found in the symbol table it displays “Label Not found”. Else, the symbol is deleted.
Step8: If the entered choice is 5, the symbol to be modified is searched in the symbol table.

PROGRAM CODE:
//Implementation of symbol table
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
void main()
{
int i=0,j=0,x=0,n;
void *p,*add[5];
char ch,srch,b[15],d[15],c;
printf("Expression terminated by $:");
while((c=getchar())!='$')
{
b[i]=c;
i++;
}
n=i-1;
printf("Given Expression:");
i=0;
while(i<=n)
{
printf("%c",b[i]);
i++;
}
printf("\n Symbol Table\n");
printf("Symbol \t addr \t type");
while(j<=n)
{
c=b[j];
if(isalpha(toascii(c)))
{
p=malloc(c);
add[x]=p;
d[x]=c;
printf("\n%c \t %d \t identifier\n",c,p);
x++;
j++;
}
else
{
ch=c;
if(ch=='+'||ch=='-'||ch=='*'||ch=='=')
{
p=malloc(ch);
add[x]=p;
d[x]=ch;
printf("\n %c \t %d \t operator\n",ch,p);
x++;
j++;
}}}}

OUTPUT:
Ex No: 2 IMPLEMENTATION OF A LEXICAL ANALYZER USING LEX

AIM:

To write a program for implementing a Lexical analyser using LEX tool in Linux platform.

ALGORITHM:

Step1: Lex program contains three sections: definitions, rules, and user subroutines. Each section must
be separated from the others by a line containing only the delimiter, %%. The format is as follows:
definitions %% rules %% user_subroutines

Step2: In definition section, the variables make up the left column, and their definitions make up the
right column. Any C statements should be enclosed in %{..}%. Identifier is defined such that the first
letter of an identifier is alphabet and remaining letters are alphanumeric.

Step3: In rules section, the left column contains the pattern to be recognized in an input file to yylex().
The right column contains the C program fragment executed when that pattern is recognized. The
various patterns are keywords, operators, new line character, number, string, identifier, beginning and
end of block, comment statements, preprocessor directive statements etc.

Step4: Each pattern may have a corresponding action, that is, a fragment of C source code to execute
when the pattern is matched.

Step5: When yylex() matches a string in the input stream, it copies the matched text to an external
character array, yytext, before it executes any actions in the rules section.

Step6: In user subroutine section, main routine calls yylex(). yywrap() is used to get more input.

Step7: The lex command uses the rules and actions contained in file to generate a program, lex.yy.c,
which can be compiled with the cc command. That program can then receive input, break the input into
the logical pieces defined by the rules in file, and run program fragments contained in the actions in file.

PROGRAM CODE:

//Implementation of Lexical Analyzer using Lex tool

%{
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);}


"/*" {COMMENT=1;}{printf("\n\t %s is a COMMENT",yytext);}
{identifier}\( {if(!COMMENT)printf("\nFUNCTION \n\t%s",yytext);}
\{ {if(!COMMENT)printf("\n BLOCK BEGINS");}
\} {if(!COMMENT)printf("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 the file");


exit(0);
}
yyin=file;
yylex();
printf("\n");
return(0);
}

int yywrap()
{
return(1);
}

INPUT:
//var.c
#include<stdio.h>
#include<conio.h>

void main()
{
int a,b,c;

a=1;
b=2;
c=a+b;
printf("Sum:%d",c);
}

OUTPUT:
3. Generate YACC specification for a few syntactic categories.

3a. Program to recognize a valid arithmetic expression that uses operator +, -, * and /.

AIM:

To write a Yacc program to valid arithmetic expression using Yacc .

ALGORITHM:

Step1: Start the program.

Step2: Reading an expression .

Step3: Checking the validating of the given expression according to the rule using yacc.

Step4: Using expression rule print the result of the given values

Step5: Stop the program.

Lex Program: (sample.l)

%{
#include<stdio.h>
#include "y.tab.h"
%}
%%
[a-zA-Z]+ return VARIABLE;
[0-9]+ return NUMBER;
[\t] ;
[\n] return 0;
. return yytext[0];
%%
int yywrap()
{
return 1;
}
Yacc program: (sample.y)

%{
#include<stdio.h>
%}
%token NUMBER
%token VARIABLE
%left '+' '-'
%left '*' '/' '%'
%left '(' ')'
%%
S: VARIABLE'='E {
printf("\nEntered arithmetic expression is Valid\n\n");
return 0;
}
E:E'+'E
|E'-'E
|E'*'E
|E'/'E
|E'%'E
|'('E')'
| NUMBER
| VARIABLE
;
%%
void main()
{
printf("\nEnter Any Arithmetic Expression which can have operations Addition, Subtraction,
Multiplication, Divison, Modulus and Round brackets:\n");
yyparse();
}
void yyerror()
{
printf("\nEntered arithmetic expression is Invalid\n\n");

Output:
3b. Program to recognize a valid variable which starts with a letter followed by any number of letters or
digits

AIM :

To write a yacc program to check valid variable followed by letter or digits

ALGORITHM:

Step1: Start the program

Step2: Reading an expression

Step3: Checking the validating of the given expression according to the rule using yacc.

Step4: Using expression rule print the result of the given values

Step5: Stop the program

%{

#include<stdio.h>

#include<ctype.h>

#include<stdlib.h>

%}

%token let dig

%%

TERM: XTERM '\n' {printf("\nAccepted\n"); exit(0);}

| error {yyerror ("Rejected\n"); exit(0);}

XTERM: XTERM let

| XTERM dig

| let

%%

main()
{

printf("Enter a variable:");

yyparse();

yylex()

char ch;

while((ch=getchar())==' ');

if(isalpha(ch))

return let;

if(isdigit(ch))

return dig;

return ch;

yyerror(char *s)

printf("%s",s);

Output:
3d. IMPLEMENTATION OF CALCULATOR USING LEX & YACC

AIM:

To write a program for implementing a calculator for computing the given expression using semantic
rules of the YACC tool and LEX.

ALGORITHM:

Step1: A Yacc source program has three parts as follows:

Declarations %% translation rules %% supporting C routines

Step2: Declarations Section: This section contains entries that:

i. Include standard I/O header file.

ii. Define global variables.

iii. Define the list rule as the place to start processing.

iv. Define the tokens used by the parser. v. Define the operators and their precedence.

Step3: Rules Section: The rules section defines the rules that parse the input stream. Each rule of a
grammar production and the associated semantic action.

Step4: Programs Section: The programs section contains the following subroutines. Because these
subroutines are included in this file, it is not necessary to use the yacc library when processing this file.

Step5: Main- The required main program that calls the yyparse subroutine to start the program.

Step6: yyerror(s) -This error-handling subroutine only prints a syntax error message.

Step7: yywrap -The wrap-up subroutine that returns a value of 1 when the end of input occurs. The
calc.lex file contains include statements for standard input and output, as programmar file information if
we use the -d flag with the yacc command. The y.tab.h file contains definitions for the tokens that the
parser program uses.

Step8: calc.lex contains the rules to generate these tokens from the input stream.

PROGRAM CODE:

//Implementation of calculator using LEX and YACC

LEX PART:

%{

#include<stdio.h>
#include "y.tab.h"

extern int yylval;

%}

%%

[0-9]+ {

yylval=atoi(yytext);

return NUMBER;

[\t] ;

[\n] return 0;

. return yytext[0];

%%

int yywrap()

return 1;

YACC PART:

%{

#include<stdio.h>

int flag=0;

%}

%token NUMBER

%left '+' '-'

%left '*' '/' '%'

%left '(' ')'

%%

ArithmeticExpression: E{

printf("\nResult=%d\n",$$);

return 0;
};

E:E'+'E {$$=$1+$3;}

|E'-'E {$$=$1-$3;}

|E'*'E {$$=$1*$3;}

|E'/'E {$$=$1/$3;}

|E'%'E {$$=$1%$3;}

|'('E')' {$$=$2;}

| NUMBER {$$=$1;}

%%

void main()

printf("\nEnter Any Arithmetic Expression which can have operations Addition, Subtraction,
Multiplication, Divison, Modulus and Round brackets:\n");

yyparse();

if(flag==0)

printf("\nEntered arithmetic expression is Valid\n\n");

void yyerror()

printf("\nEntered arithmetic expression is Invalid\n\n");

flag=1;

OUTPUT:
4. Generate three address code for a simple program using LEX and YACC.
Program:

Lex Part

%{

#include"y.tab.h"

extern char yyval;

%}

%%

[0-9]+ {yylval.symbol=(char)(yytext[0]);return NUMBER;}

[a-z] {yylval.symbol= (char)(yytext[0]);return LETTER;}

. {return yytext[0];}

\n {return 0;}

%%

Yacc Part

%{

#include"y.tab.h"

#include<stdio.h>

char addtotable(char,char,char);

int index1=0;

char temp = 'A'-1;

struct expr{

char operand1;

char operand2;

char operator;

char result;

};

%}

%union{

char symbol;

}
%left '+' '-'

%left '/' '*'

%token <symbol> LETTER NUMBER

%type <symbol> exp

%%

statement: LETTER '=' exp ';' {addtotable((char)$1,(char)$3,'=');};

exp: exp '+' exp {$$ = addtotable((char)$1,(char)$3,'+');}

|exp '-' exp {$$ = addtotable((char)$1,(char)$3,'-');}

|exp '/' exp {$$ = addtotable((char)$1,(char)$3,'/');}

|exp '*' exp {$$ = addtotable((char)$1,(char)$3,'*');}

|'(' exp ')' {$$= (char)$2;}

|NUMBER {$$ = (char)$1;}

|LETTER {(char)$1;};

%%

struct expr arr[20];

void yyerror(char *s){

printf("Errror %s",s);

char addtotable(char a, char b, char o){

temp++;

arr[index1].operand1 =a;

arr[index1].operand2 = b;

arr[index1].operator = o;

arr[index1].result=temp;

index1++;

return temp;

void threeAdd(){
int i=0;

char temp='A';

while(i<index1){

printf("%c:=\t",arr[i].result);

printf("%c\t",arr[i].operand1);

printf("%c\t",arr[i].operator);

printf("%c\t",arr[i].operand2);

i++;

temp++;

printf("\n");

int find(char l){

int i;

for(i=0;i<index1;i++)

if(arr[i].result==l) break;

return i;

int yywrap(){

return 1;

int main(){

printf("Enter the expression: ");

yyparse();

threeAdd();

printf("\n");

return 0;

}
5. IMPLEMENTATION OF TYPE CHECKING

AIM:

To write a C program to implement type checking

ALGORITHM:

Step1: Track the global scope type information (e.g. classes and their members)

Step2: Determine the type of expressions recursively, i.e. bottom-up, passing the resulting types
upwards.

Step3: If type found correct, do the operation

Step4: Type mismatches, semantic error will be notified

PROGRAM CODE:

//To implement type checking

#include<stdio.h>

#include<stdlib.h>

int main()

int n,i,k,flag=0;

char vari[15],typ[15],b[15],c;

printf("Enter the number of variables:");

scanf(" %d",&n);

for(i=0;i<n;i++)

printf("Enter the variable[%d]:",i);

scanf(" %c",&vari[i]);

printf("Enter the variable-type[%d](float-f,int-i):",i);

scanf(" %c",&typ[i]);

if(typ[i]=='f')

flag=1;

}
printf("Enter the Expression(end with $):");

i=0;

getchar();

while((c=getchar())!='$')

b[i]=c;

i++; }

k=i;

for(i=0;i<k;i++)

if(b[i]=='/')

flag=1;

break; } }

for(i=0;i<n;i++)

if(b[0]==vari[i])

if(flag==1)

if(typ[i]=='f')

{ printf("\nthe datatype is correctly defined..!\n");

break; }

else

{ printf("Identifier %c must be a float type..!\n",vari[i]);

break; } }

else

{ printf("\nthe datatype is correctly defined..!\n");

break; } }
}

return 0;

OUTPUT:
6. Implement simple code optimization techniques

6a. CONSTANT FOLDING


PROGRAM CODE:

//Code Optmization for constant folding

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#include<ctype.h>

struct ConstFold

char New_Str[10];

char str[10];

Opt_Data[20];

void ReadInput(char Buffer[],FILE *Out_file);

int Gen_Token(char str[],char Tokens[][10]);

int New_Index=0;

int main()

FILE *In_file,*Out_file;

char Buffer[100],ch;

int i=0;

In_file=fopen("code.txt","r");

Out_file=fopen("output.txt","w");

while(1)

ch= fgetc(In_file);

i=0;

while(1)

{
if(ch=='\n')

break;

Buffer[i++] = ch;

ch = fgetc(In_file);

if(ch==EOF)

break;

if(ch==EOF)

break;

Buffer[i]='\0';

ReadInput(Buffer,Out_file);

return 0;

fclose(In_file);

fclose(Out_file);

void ReadInput(char Buffer[],FILE *Out_file)

char temp[100],Token[10][10];

int n,i,j,flag=0;

strcpy(temp,Buffer);

n=Gen_Token(temp,Token);

for(i=0;i<n;i++)

if(!strcmp(Token[i],"="))

if(isdigit(Token[i+1][0]) || Token[i+1][0]=='.')

flag=1;
strcpy(Opt_Data[New_Index].New_Str,Token[i-1]);

strcpy(Opt_Data[New_Index++].str,Token[i+1]);

}}}

if(!flag)

for (i=0;i<New_index;i++)

for(j=0;j<n;j++)

if(!strcmp(Opt+Data[i].New_Str,Token[j]))

strcpy(Token[j],Opt_Data[i].str);

fflush(Out_file);

strcpy(temp,””);

for(i=0;i<n;i++)

strcat(temp,Token[i]);

if(Token[i+1][0]!=’,’||Token[i+1][0]!=’;’)

strcat(temp, “ “);

strcat(temp,”\n\0”);

fwrite(&temp,strlen(temp),1,Out_file);

int Gen_Token[char str[],char Token[][10])

int i=0,j=0,k=0;

while(str[k]!=’\0’)

j=0;

while(str[k]==’ ‘ || str[k]==’\t’)
k++;

while(str[k]!=’ ‘&& str[k] !=’\0’

&& str[k]!=’=’ ‘&& str[k] !=’/’

&& str[k]!=’+’ && str[k] !=’-‘

&& str[k]!=’*’&& str[k] !=’,’ && str[k] !=’;’)

Token[i][j++] = str[k++];

Token[i++][j]=’\0’;

if(str[k] = = ‘=’ || str[k] = = ‘/’|| str[k] = =’+’

|| str[k] = = ‘-‘|| str[k] = =’*’|| str[k] = = ‘,’

|| str[k] = =’;’)

Token[i][0] = str[k++];

Token[i++][1]=’\0’;

if(str[k] = =’\0’)

break;

return i:

Input file: code.txt

int main()

float pi = 3.14,r,a;

a= pi*r*r;

printf("a = %f",a);

return 0;
}
Output file: output.txt

main()

float pi=3.14,r,a;

a = pi*r*r;

printf("a = %f",a);

return 0;

}
How to run this program in windows,

C:\Users\user\Documents>flex ex3.l

C:\Users\user\Documents>gcc lex.yy.c

C:\Users\user\Documents\calculator>bison -dy calc.y

C:\Users\user\Documents\calculator>flex calc.l

C:\Users\user\Documents\calculator>gcc lex.yy.c y.tab.c

You might also like