Beruflich Dokumente
Kultur Dokumente
AIM:
To write a program in C to demonstrate symbol table management using C program.
ALGORITHM:
Step-1. Start the program for performing insert, display, search and modify option in symbol
table
Step-3. Enter the choice for performing the operations in the symbol Table
Step-4. 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.
Step-5. If the entered choice is 2, the symbols present in the symbol table are displayed.
Step-6. If the entered choice is 3, the symbol is searched in the symbol table. If it is not found in
the symbol table it displays "Label Not found".
Step-7. If the entered choice is 4, the symbol to be modified is searched in the symbol table. The
address of the label can be modified.
PROGRAM:
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<stdlib.h>
void create();
void search();
RESULT:
Thus Symbol table is implemented using data structure in C and output is verified.
AIM:
To develop a lexical analyzer to identify identifiers, constants, comments, operators etc
using C program
ALGORITHM:
PROGRAM:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void removeduplicate();
void final();
int Isiden(char ch);
int Isop(char ch);
int Isdel(char ch);
int Iskey(char * str);
void removeduplicate();
//char *operato[]={"+","-","/","*","<",">","=","%","<=",">=","++"};
int idi=0,idj=0,k,opi=0,opj=0,deli=0,uqdi=0,uqidi=0,uqoperi=0,kdi=0,liti=0,ci=0;
int uqdeli[20],uqopi[20],uqideni[20],l=0,j;
char uqdel[20],uqiden[20][20],uqop[20][20],keyword[20][20];
char iden[20][20],oper[20][20],delem[20],litral[20][20],lit[20],constant[20][20];
removeduplicate();
void removeduplicate()
{
int i,j;
for(i=0;i<20;i++)
{
uqdeli[i]=0;
uqopi[i]=0;
uqideni[i]=0;
}
for(i=1;i<deli+1;i++) //removing duplicate delemeters
{
if(uqdeli[i-1]==0)
{
uqdel[uqdi++]=delem[i-1];
for(j=i;j<deli;j++)
{
if(delem[i-1]==delem[j])
uqdeli[j]=1;
OUTPUT:
Enter the string:
#include<stdio.h>
void main()
{ printf (“Hello”);
}
Delimiter are :
(
)
{
;
}
Operators are :
<
>
Identifiers are :
include
stdio.h
printf
Keywords are :
Void
Main
Constants are :
Literals :
“Hello”
RESULT:
Thus the few patterns are identified in lexical analyzer
AIM:
To write sample lex programs to illustrate basic operations.
ALGORITHM:
Step-1: Lex program is to display the all characters typed from keyboard
Step-2: Program to identify only identifiers, pattern is written in the form of Lex structure
Step-3: Lex Program to display the line no for the text which is typed from keyboard
Step-4: Program is to count no of vowels and consonants and pattern is represented in the form
of Lex
PROGRAM 1:
Write A Lex Program To Show The Function Of Echo
%%
. ECHO;
\n ECHO;
%%
int yywrap(void)
{
return 1;
}
int main()
{
yylex();
return o;
}
PROGRAM 2:
Lex Program To Find Only Identifiers
ID [a-z0-9]
%%
{ID} {printf(“It is an Identifier”);}
%%
int yywrap(void)
{
return 1;
}
int main()
{
yylex();
return 0;
}
OUTPUT:
g
It is an Identifier
j
It is an Identifier
OUTPUT:
Abc
0 Abc
Hai
1 Hai
PROGRAM 4:
Lex Program To Find The Number Of Vowels And Consonants
%{
int count=0;count2=0;
%}
%%
OUTPUT:
a
vowel 1
b
consonants 1
RESULT :
Thus the sample lex programs were executed and output was verified
AIM:
To implement a lexical analyzer using Lex Tool.
ALGORITHM:
PROGRAM:
%{
#include<stdio.h>
int e,k,c,d,i,s;
%}
%%
include|void|main|int|float|double|scanf|char|printf {printf("keyword"); i++;}
[a-z][a-zA-Z0-9]* {printf("Identifier"); k++;}
[0-9]* {printf("digit"); e++;}
[+|-|*|/|=]* {printf("operator"); c++;}
[;|:|(|)|{|}|"|'|,|\n|\t]* {printf("delimeter"); d++;}
[#|<|>|%]* {printf("symbols"); s++;}
%%
int main(void)
{
return 1;
}
int yywrap()
{
return 1;
}
INPUT:
Lexyi.txt
int a=10;
OUTPUT:
Identifier 1
Digit 1
Keyword 1
Operator 1
Delimiter 1
RESULT:
Thus a lexical analyzer is implemented using Lex Tool and the output is verified.
AIM:
To write a yacc program to identify identifiers.
ALGORITHM:
Step-1:Reading an expression
Step-2: Checking the validating of the given expression according to the rule using yacc.
Step-3: Display “ identifier” or syntax error
PROGRAM:
id.l :
%{
#include "y.tab.h"
%}
%%
%%
int yywrap()
return 1;
id.y :
%{
#include<stdio.h>
int i;
%}
%token number ID
%%
%%
void main()
yyparse();
}while(!feof(yyin));
printf("error");
OUTPUT:
>> lex id.l
>> bison -d -y id.y
>> cc y.tab.c lex.yy.c
>>./a.out
RESULT:
Thus the yacc program to find identifier was verified
ALGORITHM:
Step-1:Reading an expression
Step-2: Checking the validating of the given expression according to the rule using yacc.
Step-3:Using expression rule print the result of the given values
PROGRAM:
calc.y
%{
#include <stdio.h>
void yyerror(char *);
int yylex(void);
int sym[26],i=0;
%}
%token INTEGER VARIABLE
%left '+' '-'
%left '*' '/'
%%
program:
program statement '\n'
| /* NULL */
;
statement:
expression { printf("%d\n", $1); }
| VARIABLE '=' expression { printf ("Node =\t\t"); sym[$1] = $3;}
;
expression:
%%
[a-z] {
printf("Tdentifier");
return VARIABLE;
}
[0-9]+ {
yylval = atoi(yytext);
return INTEGER;
}
OUTPUT:
bison -d -y calc.y
lex calc.l
gcc lex.yy.c y.tab.c
./a.out
a+b
valid
ab-
syntax error
RESULT:
Thus the program for validating arithmetic expression was done
AIM :
To write a yacc program to check valid variable followed by letter or digits
ALGORITHM:
Step-1:Reading an expression
Step-2: Checking the validating of the given expression according to the rule using yacc.
Step-3:Using expression rule print the result of the given values
PROGRAM:
valid.y
%{
#include <stdio.h>
void yyerror(char *);
int yylex(void);
int sym[26],i=0;
%}
%token INTEGER VARIABLE
%left '+' '-'
%left '*' '/'
%%
program:
program statement '\n'
| /* NULL */
;
statement:
expression { printf("%d\n", $1); }
| VARIABLE '=' expression { printf ("Node =\t\t"); sym[$1] = $3;}
;
%%
[a-z] {
printf("Tdentifier");
return VARIABLE;
}
[0-9]+ {
yylval = atoi(yytext);
return INTEGER;
OUTPUT:
bison -d -y valid.y
lex valid.l
gcc lex.yy.c y.tab.c
./a.out
A1
valid
10a
syntax error
RESULT:
Thus the program for checking letter followed by letter or digits were done
AIM :
To write a yacc program to implement calculator using yacc
ALGORITHM:
Step-1:Reading an expression
Step-2: Calculate the value of given expression using yacc .
Step-3:Using expression rule print the result of the given values
PROGRAM:
valid.y
%{
#include <stdio.h>
void yyerror(char *);
int yylex(void);
int sym[26],i=0;
%}
%token INTEGER VARIABLE
%left '+' '-'
%left '*' '/'
%%
program:
program statement '\n'
| /* NULL */
;
statement:
expression { printf("%d\n", $1); }
| VARIABLE '=' expression { printf ("Node =\t\t"); sym[$1] = $3;}
;
%%
[a-z] {
printf("Tdentifier");
return VARIABLE;
}
[0-9]+ {
yylval = atoi(yytext);
return INTEGER;
OUTPUT:
bison -d -y valid.y
lex valid.l
gcc lex.yy.c y.tab.c
./a.out
3+5
8
35/
syntax error
RESULT:
Thus the program for checking letter followed by letter or digits were done
AIM:
To implement Stack storage allocation strategies using C program.
ALGORITHM:
Step-1: Initially check whether the stack is empty
Step-2: Insert an element into the stack using push operation
Step-3: Insert more elements onto the stack until stack becomes full
Step-4: Delete an element from the stack using pop operation
Step-5: Display the elements in the stack
Step-6: Top the stack element will be displayed
PROGRAM:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#define size 5
struct stack
{
int s[size];
int top;
} st;
int stfull()
{
if (st.top >= size - 1)
return 1;
else
return 0;
RESULT:
Thus the stack is implemented in C using arrays and output is verified.
AIM:
To write a yacc program to change yacc form into abstract syntax Tree
ALGORITHM:
Step-1: Reading an expression.
Step-2: Calculate the value of given expression
Step-3: Display the value of the nodes based on the precedence.
Step-4: Using expression rule print the result of the given values
PROGRAM:
abs.l :
%{
#include "y.tab.h"
%}
%%
[0-9]+ {yylval=atoi(yytext);
return number;
[+ -] {return *yytext;}
[* /] {return *yytext;}
\n return 0;
%%
int yywrap()
return 1;
abs.y :
%{
#include<stdio.h>
int i;
%}
%%
|term {$$=$1;}
|factor {$$=$1;}
%%
void main()
do
yyparse();
}while(!feof(yyin));
printf("error");
RESULT:
Thus, the yacc program for abstract tree was executed successfully.
AIM:
To write a C program to implement type checking
ALGORITHM:
Step-1: Track the global scope type information (e.g. classes and their members)
Step-2: Determine the type of expressions recursively, i.e. bottom-up, passing the
resulting types upwards.
Step-3: If type found correct, do the operation
Step-4: Type mismatches, semantic error will be notified
PROGRAM:
#include<stdio.h>
#include<string.h>
struct symTable
int type;
char var[10];
}sT[50];
int c = 0;
int i,j=0;
char temp[50],tp[50];
if(a[i] != 32)
tp[i] = a[i];
else
break;
tp[i] = '\0';
temp[0]='\0';
++i;
temp[j++] = a[i];
else
if(strcmp(tp,"int") == 0)
sT[c].type = 1;
else if(strcmp(tp,"float") == 0)
sT[c].type = 2;
strcpy(sT[c++].var,temp);
temp[0] = '\0';
j=0;
char temp[50];
if(a[i] != 32 && a[i] != '+' && a[i] != '=' && a[i] != ';')
temp[j++] = a[i];
else
temp[j]='\0';
if(strcmp(sT[k].var,temp) == 0)
if(key == 0)
key = sT[k].type;
return 0;
j = 0;
return 1;
int N,ans,i;
char s[50];
scanf("%d",&N);
while(N--)
scanf(" %[^\n]",s);
sep(s);
scanf(" %[^\n]",s);
if(check(s))
else
printf("Semantic error\n");
OUTPUT:
RESULT:
Thus, the c program for implementation of type checking was done successfully.
AIM:
To write a c program for implementing backend of a compiler.
ALGORITHM:
PROGRAM:
#include<stdio.h>
#include<string.h>
int main(){
char inp[100][100];
int n,i,j,len;
int reg = 1;
scanf("%s",&inp[i]);
len = strlen(inp[i]);
j=3;
printf("STORE %c R%d\n",inp[i][0],reg-2);
else if(inp[i][j]=='-')
printf("STORE %c R%d\n",inp[i][0],reg-2);
else if(inp[i][j]=='*')
printf("STORE %c R%d\n",inp[i][0],reg-2);
printf("STORE %c R%d\n",inp[i][0],reg-2);
break;
return 0;
RESULT:
Thus, the c program for implementing backend of the compiler was done successfully.
AIM:
To write a C program to eliminate dead code as code optimization
ALGORITHM:
PROGRAM:
#include<stdio.h>
void main()
{
char all_var[10];
int ptr=0,dup=0,i,j,c,a=0;
FILE *file;
for(i=0;i<=ptr;i++)
{
for(j = i+1; j <= ptr; j++)
if(all_var[i] == all_var[j])
{
dup=1;
}
if(dup==0)
{printf("%c",all_var[i]);
dup=0;
}
}
fclose(file);
}
}
INPUT:
a;
b;
c;
a;
a=34;
c=78;
OUTPUT:
b is unused variable
RESULT:
Thus the program for code optimization was implemented
AIM:
To study the concept of Directed acyclic graph
PROCEDURE:
Directed acyclic graphs :
Directed acyclic graphs (DAGs) give a picture of how the value computed by each
statement in the basic block is used in the subsequent statements of the block.
Definition:
A DAG for a basic block is a directed acyclic graph with the following labels on nodes:
leaves are labeled with either variable names or constants.
they are unique identifiers
from operators we determine whether l- or r-value.
represent initial values of names. Subscript with 0.
interior nodes are labeled by an operator symbol.
Nodes are also (optionally) given a sequence of identifiers for labels.
interior node º computed value
identifiers in the sequence – have that value.
Output: A DAG where each node n has a value, VALUE(n), which is an operator in the case of
an interior node or a variable name if the node is a leaf. Also, each node n has a (possibly empty)
list of identifiers attached, ID(n).
The DAG Representation of Basic Blocks The previous algorithm aims at improving the
quality of the target code,but only with respect to register utilization.There are a number
of other issues in the generation of efficient code.One of them is the elimination of
redundant computation
T1 = J * 2
Example: T2 = X[T1]
T3 = T2 + N
T4 = J * 2
T5 = Y[T4]
T6 = T5 + T3
ANS = T6
T7 = J+ 1
J = T7
ANS = J
If J<10 goto L
Thus the DAG for the expression in basic block was studied
AIM:
To study the concept of control flow and data flow analysis
PROCEDURE:
AIM:
To write a C program to implement recursive descent parser
ALGORITHM:
Step-1:Read the input string.
Step-2:By using the FIRST AND FOLLOW values.
Step-3: Verify the FIRST of non terminal and insert the production in the FIRST value
Step-4:If we have any @ terms in FIRST then insert the productions in FOLLOW values
PROGRAM:
#include<stdio.h>
#include<conio.h>
#include<string.h>
void match(char);
void b(void);
char c[10];
static int i;
void main()
{
int n;
char k;
clrscr();
printf("Recursive Descent parser \n");
printf("Grammar is \n");
printf("S->AB ; A->a ; B->b \n");
printf("enter the string ");
gets(c);
printf(" input string is %s\n",c);
void b(void)
{
printf("now in b()\n");
printf("now the character is %c\n",c[i]);
}
}
OUTPUT:
Recursive Descent parser
Grammar is
S->AB ; A->a ; B->b
enter the string ab
input string is ab
lengthof input string is 2
in main() now character is a
current input sumbol matched
now in b()
now the character is b
current input sumbol matched
parsing completed
RESULT:
Thus the recursive descent parser was implemented using C program