Beruflich Dokumente
Kultur Dokumente
An action is the piece of code which is to be executed whenever token specified by the
corresponding regular expression is recognized. The output of the LEX is the lexical
analyzer program constructed from the LEX source specification.
Unlike most programming languages a LEX source program doesn’t contain the details
of the computation. The data inputted is in the form of transition tables. The transition
table is that part of LEX output that is directly taken from LEX input.
Lexical
Input Stream of tokens
analyzer
The lexical analyzer L is the transition table plus the program to stimulate finite automata
expressed as transition table.
LEX source Program
Ri = Regular expressions.
Di = Distinct names assigned to those regular expressions.
Pi = Patterns of regular expressions
Ai = Actions to be performed
The transition rules of a LEX program are the statements of the given form where each P i
is a regular expression called the pattern over the alphabets consisting of auxiliary
definitions. The pattern describes the form of tokens.
Each Ai is a program fragment describing what actions the lexical analyzer should
perform when corresponding token is found. The Ais are written in conventional
programming language. To create the lexical analyzer each of the A is must be compiled
into machine code.
The lexical analyzer created by LEX behaves in the following manner: L reads its input
one character at a time until it has found the longest prefix to the input which matches
one of the regular expressions Pi.
One L has found that prefix L removes it from input and places it to the buffer called
token.
Lexical analyzer can be built from its input. Lexical analyzer behaves rough as a finite
automaton. The idea is to construct a NFA ‘N’ for each token P in the translation table.
NFA1
Є NFA2
Є
NFA3
Є
Є NFAn
Link these NFAs together with a new start state. Next we convert this NFA to DFA using
subset construction.
These are several cases while constructing this procedure:
• There are several different accepting states i.e. the accepting state of each Ni
indicates that its own token has been found.
• When we convert to DFA, the subsets we construct may contain several different
finite states but final DFA must contain a single accepting state i.e. the state with
the longest prefix which matches with the given pattern.
• After reaching the final state the lexical analyzer must continue to simulate the
DFA until it reaches at a state where no next state for the current input symbol.
We call this state as a termination.
#include<iostream.h>
#include<conio.h>
#include<string.h>
void main()
{
char a[10];int count1=0,count2=0;
clrscr();
cout<<"enter the string";
cin>>a;
int l=strlen(a);
for(int i=0;i<l;i++)
{
if(a[i]=='A' || a[i]=='a')
count1++;
else
count2++;
}
if(count1==count2)
cout<<"grammar is accepted";
else
cout<<"grammer is not accepted";
getch();
}
OUTPUT:
EXPERIMENT-3
#include<iostream.h>
#include<conio.h>
#include<string.h>
#include<graphics.h>
void main()
{
clrscr();
char s[5],a[5][5],b[5][2],cq[5][2],z[5];
int p=0;
cout<<"\nEnter the productions for S -> ";
cin>>s;
int len=strlen(s);
cout<<"\nProductions for S -> "<<s;
for(int i=0;i<5;i++)
if((s[i]>='A')&&(s[i]<='Z'))
{ z[p]=s[i]; p++; }
int o=p;
cout<<"\nValue: "<<o;
for(p=0;p<o;p++)
{
cout<<"\nEnter the productions for "<<z[p]<<" -> ";
cin>>a[p];
cout<<"\nProduction for "<<z[p]<<" -> "<<a[p];
}
clrscr();
int driver,mode;
driver=DETECT;
initgraph(&driver,&mode,"c:\\tc\\bgi");
outtextxy(320,50,"S");
int count;
int g=0,h=-100,c,u,y=200;
p=0;
for(u=0;u<len;u=u+1)
{
y=y+50;
lineto(y,100);
b[u][0]=s[u];
b[u][1]='\0';
outtext(*(b+u));
if((s[u]>='A')&&(s[u]<='Z'))
{
count=strlen(a[g]);
a[g][count+1]='\0';
c=0;
for(int q=0;q<count;q++)
{
h=h+50;
moveto(y,100);
linerel(h,100);
cq[p][0]=*(*(a+g)+c);
cq[p][1]='\0';
outtext(cq[p]);
++p;
++c;
}
g++;
}
moveto(320,50);
}
getch();
}
Output:
EXPERIMENT-4
//computation of first.
#include<iostream.h>
#include<conio.h>
void main()
{
int n;char q[3],w[3],e[3];
clrscr();
cout<<"enter the no. of prod";
cin>>n;
for(int i=1;i<=n;i++)
{
cout<<"enter "<<i<<"pord : \n";
cout<<"enter left symbol \n";
cin>>q[i];
cout<<"enter the right fisrt symabol \n";
cin>>w[i];
cout<<"enter the next \n";
cin>>e[i];
}
cout<<"the prod are :\n\n\n";
for(i=1;i<=n;i++)
{
cout<<"pord 1: "<<q[i]<<"->"<<w[i]<<e[i]<<"\n";
}
for(i=1;i<=n;i++) //recoginition of +,*,(.
{
if(w[i]=='+')
cout<<"\nfisrt("<<q[i]<<")"<<"="<<"+";
else if(w[i]=='*')
cout<<"\nfisrt("<<q[i]<<")"<<"="<<"*";
else if(w[i]=='(')
cout<<"\nfisrt("<<q[i]<<")"<<"="<<"(";
else
cout<<"chain rule";
}
EXPERIMENT-5
Regular Expressions
Just as finite automata are used to recognize patterns of strings, regular expressions are
used to generate patterns of strings. A regular expression is an algebraic formula whose
value is a pattern consisting of a set of strings, called the language of the expression.
• characters from the alphabet over which the regular expression is defined.
• variables whose values are any pattern defined by a regular expression.
• epsilon which denotes the empty string containing no characters.
• null which denotes the empty set of strings.
• Kleene closure: If R1 is a regular expression, then R1* (the Kleene closure of R1)
is also a regular expression.
We will use the rules which defined a regular expression as a basis for the construction:
2. If the regular expression is just a character, eg. a, then the corresponding NFA is :
3. The union operator is represented by a choice of transitions from a node; thus a|b
can be represented as:
4. Concatenation simply involves connecting one NFA to the other; eg. ab is:
5. The Kleene closure must allow for taking zero or more instances of the letter from
the input; thus a* looks like:
EXPERIMENT-6
#include<iostream.h>
#include<conio.h>
void main()
{
char k[5],l[5],s,p;
clrscr();
cout<<"enter the start symbol\n";
cin>>s;
cout<<"enter the first symbol at right\n";
cin>>p;
cout<<"enter the remaining at right\n";
cin>>k;
cout<<"enter the string after /\n";
cin>>l;
cout<<"prod is\n"<<s<<"->"<<p<<k<<"/"<<l;
if(s==p)
{
cout<<"\n grammar is left recursive";
cout<<"\n grammar after rcursion removal\n\n";
cout<<s<<"->"<<l<<s<<"'";
cout<<"\n\n";
cout<<s<<"'"<<"->"<<k<<s<<"'"<<"/"<<"ep";
}
else
{
cout<<"grammar is not left recursive";
}
getch();
}
OUTPUT:
EXPERIMENT-7
#include<iostream.h>
#include<conio.h>
void main()
{
char A,K,L,M,N;
clrscr();
cout<<"enter the value for start symabol :";
cin>>A;
cout<<"enter the Alpha before \ : \n";
cin>>K;
cout<<"enter the Beta value :\n ";
cin>>L;
cout<<"enter the Alpha after \ : \n";
cin>>N;
cout<<"enter the Gama value :\n ";
cin>>M;
cout<<"prod is\n"<<A<<"->"<<K<<L<<"/"<<N<<M;
if(K==N)
{
cout<<"\n\n grammar is left factored";
cout<<"\n\n after removal of left factoring :\n\n";
cout<<A<<"->"<<K<<A<<"\'";
cout<<"\n\n";
cout<<A<<"\'"<<"->"<<L<<"/"<<M;
}
getch();
}
OUTPUT:
EXPERIMENT-8
//push operation.
#include<stdio.h>
#include<conio.h>
#define MAX 5;
void push();
void pop();
int top=-1;
int stack[5];
int item;
void main()
{ int i;
int a;
do
{ int ch;
clrscr();
printf("-------1.Push-------\n");
printf("-------2.pop--------\n");
printf("enter the choice");
scanf("%d",&ch);
switch(ch)
{
case 1:
push();
break;
case 2:
pop();
break;
case 3:
exit(0);
default:
printf("u have entered a wrong choice");
}
}while(a!=3);
}
void push()
{
if(stack[top]==5)
printf("overflow");
else
{
printf("enter the item:");
scanf("%d",&item);
top=top+1;
stack[top]=item;
}
}
void pop()
{
if(top==-1)
printf("underflow");
else
{
item=stack[top];
top=top-1;
printf("%d",item);
getch();
}
}
OUTPUT
Experiment – 10
AIM : To show read, write operation on file.
// file operation
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
void main()
{
FILE *fp;
int i,num;
clrscr();
fp=fopen("INTEGER.DAT","w");
if(fp==NULL)
{
printf("error opening file");
exit(1);
}
for(i=0;i<5;i++)
{
scanf("%d",&num);
if(num==-99)
break;
putw(num,fp);
}
fclose(fp);
fp=fopen("INTEGER.DAT","r");
if(fp==NULL)
{
printf("error opening file");
exit(1);
}
while((num=getw(fp)) !=EOF)
{
printf("%d",num);
fclose(fp);
}
getch();
Output :