Lab Manual Toc
Lab Manual Toc
LAB MANUAL
CS019
THEORY OF COMPUTATION
(Regulation 2016)
SAVEETHA SCHOOL OF ENGINEERING
LIST OF EXPERIMENTS
AIM :
ALGORTIHM :
1. Draw a DFA for the given language and construct the transition table.
2. Store the transition table in a two-dimensional array.
3. Initialize present_state, next_state and final_state
4. Get the input string from the user.
5. Find the length of the input string.
6. Read the input string character by character.
7. Repeat step 8 for every character
8. Refer the transition table for the entry corresponding to the present
state and the current input symbol and update the next state.
9. When we reach the end of the input, if the final state is reached, the
input is accepted. Otherwise the input is not accepted.
Example:
Simulate a DFA for the language representing strings over 𝚺={a,b} that start
with a and end with b
Transition Table:
State / Input a b
→0 1 3
1 1 2
2 1 2
3 3 3
PROGRAM :
#include<stdio.h>
#include<string.h>
#define max 20
int main()
{
int trans_table[4][2]={{1,3},{1,2},{1,2},{3,3}};
int final_state=2,i;
int present_state=0;
int next_state=0;
int invalid=0;
char input_string[max];
printf("Enter a string:");
scanf("%s",input_string);
int l=strlen(input_string);
for(i=0;i<l;i++)
{
if(input_string[i]=='a')
next_state=trans_table[present_state][0];
else if(input_string[i]=='b')
next_state=trans_table[present_state][1];
else
invalid=l;
present_state=next_state;
}
if(invalid==l)
{
printf("Invalid input");
}
else if(present_state==final_state)
printf("Accept\n");
else
printf("Don't Accept\n");
}
OUTPUT
EXP NO : 2
AIM :
ALGORTIHM :
#include<stdio.h>
#include<string.h>
int main()
{
int i,j,k,l,m,next_state[20],n,mat[10][10][10],flag,p;
int num_states,final_state[5],num_symbols,num_final;
int present_state[20],prev_trans,new_trans;
char ch,input[20];
int symbol[5],inp,inp1;
printf("How many states in the NFA : ");
scanf("%d",&num_states);
printf("How many symbols in the input alphabet : ");
scanf("%d",&num_symbols);
for(i=0;i<num_symbols;i++)
{
printf("Enter the input symbol %d : ",i+1);
scanf("%d",&symbol[i]);
}
printf("How many final states : ");
scanf("%d",&num_final);
for(i=0;i<num_final;i++)
{
printf("Enter the final state %d : ",i+1);
scanf("%d",&final_state[i]);
}
//Initialize all entries with -1 in Transition table
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
for(k=0;k<10;k++)
{
mat[i][j][k]=-1;
}
}
}
//Get input from the user and fill the 3D transition table
for(i=0;i<num_states;i++)
{
for(j=0;j<num_symbols;j++)
{
printf("How many transitions from state %d for the input %d :
",i,symbol[j]);
scanf("%d",&n);
for(k=0;k<n;k++)
{
printf("Enter the transition %d from state %d for the input
%d : ",k+1,i,symbol[j]);
scanf("%d",&mat[i][j][k]);
}
}
}
printf("The transitions are stored as shown below\n");
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
for(k=0;k<10;k++)
{
if(mat[i][j][k]!=-1)
printf("mat[%d][%d][%d] = %d\n",i,j,k,mat[i][j][k]);
}
}
}
while(1)
{
printf("Enter the input string : ");
scanf("%s",input);
present_state[0]=0;
prev_trans=1;
l=strlen(input);
for(i=0;i<l;i++)
{
if(input[i]=='0')
inp1=0;
else if(input[i]=='1')
inp1=1;
else
{
printf("Invalid input\n");
exit(0);
}
for(m=0;m<num_symbols;m++)
{
if(inp1==symbol[m])
{
inp=m;
break;
}
}
new_trans=0;
for(j=0;j<prev_trans;j++)
{
k=0;
p=present_state[j];
while(mat[p][inp][k]!=-1)
{
next_state[new_trans++]=mat[p][inp][k];
k++;
}
}
for(j=0;j<new_trans;j++)
{
present_state[j]=next_state[j];
}
prev_trans=new_trans;
}
flag=0;
for(i=0;i<prev_trans;i++)
{
for(j=0;j<num_final;j++)
{
if(present_state[i]==final_state[j])
{
flag=1;
break;
}
}
}
if(flag==1)
printf("Acepted\n");
else
printf("Not accepted\n");
printf("Try with another input\n");
}
}
Example:
Simulate a NFA for the language representing strings over 𝚺={a,b} that start
and end with the same symbol
Design of the NFA
Transition Table
State / Input 0 1
→0 1 3
1 {1,2} 1
2 - -
3 3 {2,3}
OUTPUT:
EXP NO : 3
AIM :
ALGORTIHM :
ε-closure(0)={0,1,2)
ε-closure(1)={1,2}
ε-closure(2)={2}
Here, we see that ε-closure of every state contains that state first. So
initialize the first entry of the array e_closure with the same state.
e_closure(0,0)=0;
e_closure(1,0)=1;
e_closure(2,0)=2;
6. For every state i, find ε-closure as follows:
If there is an ε-transition from state i to state j, add j to the matrix
e_closure[i]. Call the recursive function find_e_closure(j) and add
the other states that are reachable from i using ε
7. For every state, print the ε-closure values
PROGRAM :
#include<stdio.h>
#include<string.h>
int trans_table[10][5][3];
char symbol[5],a;
int e_closure[10][10],ptr,state;
void find_e_closure(int x);
int main()
{
int i,j,k,n,num_states,num_symbols;
for(i=0;i<10;i++)
{
for(j=0;j<5;j++)
{
for(k=0;k<3;k++)
{
trans_table[i][j][k]=-1;
}
}
}
printf("How may states in the NFA with e-moves:");
scanf("%d",&num_states);
printf("How many symbols in the input alphabet including e :");
scanf("%d",&num_symbols);
printf("Enter the symbols without space. Give 'e' first:");
scanf("%s",symbol);
for(i=0;i<num_states;i++)
{
for(j=0;j<num_symbols;j++)
{
printf("How many transitions from state %d for the input
%c:",i,symbol[j]);
scanf("%d",&n);
for(k=0;k<n;k++)
{
printf("Enter the transitions %d from state %d for the input
%c :", k+1,i,symbol[j]);
scanf("%d",&trans_table[i][j][k]);
}
}
}
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
e_closure[i][j]=-1;
}
}
for(i=0;i<num_states;i++)
e_closure[i][0]=i;
for(i=0;i<num_states;i++)
{
if(trans_table[i][0][0]==-1)
continue;
else
{
state=i;
ptr=1;
find_e_closure(i);
}
}
for(i=0;i<num_states;i++)
{
printf("e-closure(%d)= {",i);
for(j=0;j<num_states;j++)
{
if(e_closure[i][j]!=-1)
{
printf("%d, ",e_closure[i][j]);
}
}
printf("}\n");
}
}
void find_e_closure(int x)
{
int i,j,y[10],num_trans;
i=0;
while(trans_table[x][0][i]!=-1)
{
y[i]=trans_table[x][0][i];
i=i+1;
}
num_trans=i;
for(j=0;j<num_trans;j++)
{
e_closure[state][ptr]=y[j];
ptr++;
find_e_closure(y[j]);
}
}
Example:
Find ε-closure for all the states for the NFA with ε-moves given below:
0 1 2
TRANSITION TABLE :
State / Input ε 0 1
→0 1 - 1
1 2 {0,1} -
2 - - -
OUTPUT :
EXP NO : 4
Ex 4 a
AIM :
ALGORTIHM :
1. Get the input string from the user.
2. Find the length of the string.
3. Check whether all the symbols in the input are either 0 or 1. If so,
print “String is valid” and go to step 4. Otherwise print “String not
valid” and quit the program.
4. If the first symbol is 0 and the last symbol is 1, print “String
accepted”. Otherwise, print “String not accepted”
PROGRAM :
#include<stdio.h>
#include<string.h>
int main(){
char s[100];
int i,flag;
int l;
printf("enter a string to check:");
scanf("%s",s);
l=strlen(s);
flag=1;
for(i=0;i<l;i++)
{
if(s[i]!='0' && s[i]!='1')
{
flag=0;
}
}
if(flag!=1)
printf("string is Not Valid\n");
if(flag==1)
{
if (s[0]=='0'&&s[l-1]=='1')
printf("string is accepted\n");
else
printf("string is Not accepted\n");
}
}
OUTPUT :
EXP 4 b
CHECKING WHETHER A STRING BELONGS TO A GRAMMAR
AIM :
ALGORITHM :
#include<stdio.h>
#include<string.h>
void main()
{
char s[100];
int i,flag,flag1,a,b;
int l;
printf("enter a string to check:");
scanf("%s",s);
l=strlen(s);
flag=1;
for(i=0;i<l;i++)
{
if(s[i]!='0' && s[i]!='1')
{
flag=0;
}
}
if(flag!=1)
printf("string is Not Valid\n");
if(flag==1)
{
flag1=1;
a=0;b=l-1;
while(a!=(l/2))
{
if(s[a]!=s[b])
{
flag1=0;
}
a=a+1;
b=b-1;
}
if (flag1==1)
{
printf("The string is a palindrome\n");
printf("string is accepted\n");
}
else
{
printf("The string is not a palindrome\n");
printf("string is Not accepted\n");
}
}
}
OUTPUT :
EXP 4 c
CHECKING WHETHER A STRING BELONGS TO A GRAMMAR
AIM :
ALGORITHM :
#include<stdio.h>
#include<string.h>
void main()
{
char s[100];
int i,flag,flag1,a,b;
int l,count1,count2;
printf("enter a string to check:");
scanf("%s",s);
l=strlen(s);
flag=1;
for(i=0;i<l;i++)
{
if(s[i]!='0' && s[i]!='1')
{
flag=0;
}
}
if(flag!=1)
printf("string is Not Valid\n");
if(flag==1)
{
i=0;count1=0;
while(s[i]=='0') // Count the no of 0s in the front
{
count1++;
i++;
}
while(s[i]=='1')
{
i++; // Skip all 1s
}
flag1=1;
count2=0;
while(i<l)
{
if(s[i]=='0')// Count the no of 0s at the end
{
count2++;
}
else
{
flag1=0;
}
i++;
}
if(flag1==1)
{
if(count1==count2)
{
printf("The string satisfies the condition 0n1m0n\n");
printf ("String Accepted\n");
}
else
{
printf("The string does not satisfy the condition 0n1m0n\n");
printf("String Not Accepted\n");
}
}
else
{
printf("The string does not satisfy the condition 0n1m0n\n");
printf("String Not Accepted\n");
}
}
}
OUTPUT :
EXP 4 d
AIM :
ALGORITHM :
#include<stdio.h>
#include<string.h>
void main()
{
char s[100];
int i,flag,flag1,flag2;
int l;
printf("enter a string to check:");
scanf("%s",s);
l=strlen(s);
flag=1;
for(i=0;i<l;i++)
{
if(s[i]!='0' && s[i]!='1')
{
flag=0;
}
}
if(flag!=1)
printf("string is Not Valid\n");
if(flag==1)
{
if(l%2!=0) // If string length is odd
{
printf("The string does not satisfy the condition 0n1n\n");
printf("String Not Accepted\n");
}
else
{
// To check first half contains 0s
flag1=1;
for(i=0;i<(l/2);i++)
{
if(s[i]!='0')
{
flag1=0;
}
}
// To check second half contains 1s
flag2=1;
for(i=l/2;i<l;i++)
{
if(s[i]!='1')
{
flag2=0;
}
}
if(flag1==1 && flag2==1)
{
printf("The string satisfies the condition 0n1n\n");
printf("String Accepted\n");
}
else
{
printf("The string does not satisfy the condition 0n1n\n");
printf("String Not Accepted\n");
}
}
}
}
OUTPUT :
EXP 4 e
AIM :
ALGORITHM :
#include<stdio.h>
#include<string.h>
int main()
{
char s[100];
int i,flag,flag1;
int l;
printf("enter a string to check:");
scanf("%s",s);
l=strlen(s);
flag=1;
for(i=0;i<l;i++)
{
if(s[i]!='0' && s[i]!='1')
{
flag=0;
}
}
if(flag==1)
printf("string is Valid\n");
else
printf("string is Not Valid\n");
if(flag==1)
{
flag1=0;
for(i=0;i<l-2;i++)
{
if(s[i]=='1')
{
if(s[i+1]=='0' && s[i+2]=='1')
{
flag1=1;
printf("Substring 101 exists. String accepted\n");
break;
}
}
}
if(flag1==0)
printf("Substring 101 does not exist. String not accepted\n");
}
}
OUTPUT :
EXP NO : 05
AIM :
ALGORITHM :
#include<stdio.h>
#include<string.h>
char stack[20];
int top;
void push()
{
top=top+1;
stack[top]='0';
stack[top+1]='\0';
}
int pop()
{
if(top<1)
return(0);
else
{
stack[top]='\0';
top=top-1;
return(1);
}
}
void main()
{
int m,i,j,k,l,a,len;
char input[20],rem_input[20];
printf("Simulation of Pushdown Automata for 0n1n\n");
printf("Enter a string : ");
scanf("%s",input);
l=strlen(input);
j=0;stack[0]='Z';top=0;
printf("Stack\tInput\n");
printf("%s\t%s\n",stack,input);
while(1)
{
len=strlen(input);
while(len>0)
{
if(input[0]=='0')
{
push();
m=0;
for(k=1;k<len;k++)
{
rem_input[m]=input[k];
m=m+1;
}
rem_input[m]='\0';
strcpy(input,rem_input);
printf("%s\t%s\n",stack,input);
}
if(input[0]=='1')
{
a=pop();
if(a==0)
{
printf("String not accepted");
goto b;
}
else
{
m=0;
for(k=1;k<len;k++)
{
rem_input[m]=input[k];
m=m+1;
}
rem_input[m]='\0';
strcpy(input,rem_input);
printf("%s\t%s\n",stack,input);
}
}
break;
}
j=j+1;
if(j==(l))
{
break;
}
}
if(top>=1)
{
printf("String not accepted");
}
else
{
printf("String accepted");
}
b:
printf(".............");
}
OUTPUT :
EXP NO : 06
AIM :
To write a C program to simulate a PDA for the language L={ 0n 12n | n>=1 }
in which n number of 0’s are followed by 2n number of 1’s
ALGORITHM :
#include<stdio.h>
#include<string.h>
char stack[20];
int top,count=0;
void push()
{
top=top+1;
stack[top]='0';
stack[top+1]='\0';
}
int pop()
{
if(top<1)
return(0);
else
{
stack[top]='\0';
top=top-1;
return(1);
}
}
void main()
{
int m,i,j,k,l,a,len;
char input[20],rem_input[20];
printf("Simulation of PDA for n 0's followed by 2n 1's\n");
printf("Enter a string : ");
scanf("%s",input);
l=strlen(input);
j=0;stack[0]='Z';top=0;
printf("Stack\tInput\n");
printf("%s\t%s\n",stack,input);
while(1)
{
len=strlen(input);
while(len>0)
{
if(input[0]=='0')
{
push();
m=0;
for(k=1;k<len;k++)
{
rem_input[m]=input[k];
m=m+1;
}
rem_input[m]='\0';
strcpy(input,rem_input);
printf("%s\t%s\n",stack,input);
}
if(input[0]=='1')
{
count++;
if(count%2==0)
{
a=pop();
if(a==0)
{
printf("String not accepted");
goto b;
}
else
{
m=0;
for(k=1;k<len;k++)
{
rem_input[m]=input[k];
m=m+1;
}
}
rem_input[m]='\0';
strcpy(input,rem_input);
printf("%s\t%s\n",stack,input);
}
else
{
m=0;
for(k=1;k<len;k++)
{
rem_input[m]=input[k];
m=m+1;
}
rem_input[m]='\0';
strcpy(input,rem_input);
printf("%s\t%s\n",stack,input);
}
}
break;
}
j=j+1;
//printf("j = %d\t l = %d\n",j,l);
if(j==l)
{
break;
}
}
if(top>=1)
{
printf("String not accepted");
}
else
{
printf("String accepted");
}
b:
printf(".............");
}
OUTPUT :
EXP NO : 07
AIM :
ALGORITHM :
#include<stdio.h>
#include<string.h>
void main()
{
int i,j,le,flag,flag1,flag2;
char str[20];
printf("Program to show how a turing machine will process 0n1n2n\n");
printf("Enter a string : ");
scanf("%s",str);
le=strlen(str);
j=0;
while(1)
{
flag=0;flag1=0;flag2=0;i=0;
while(i<le)
{
if((str[i]=='0')&&(flag==0))
{
str[i] = 'A';
printf("%s\n",str);
flag=1; //To mark that a 0 is changed to A
i=i+1;
}
else if((str[i]=='0')&&(flag==1))
{
i=i+1; //Skip 0
}
else if(str[i]=='A')
{
i=i+1; //Skip A
}
else if((str[i]=='1')&&(flag1==0))
{
str[i] = 'B';
printf("%s\n",str);
flag1=1; //To mark that a 1 is changed to B
i=i+1;
}
else if((str[i]=='1')&&(flag1==1))
{
i=i+1; //Skip 1
}
else if(str[i]=='B')
{
i=i+1; //Skip B
}
else if((str[i]=='2')&&(flag2==0))
{
str[i] ='C';
printf("%s\n",str);
flag2=1; //To mark that a 2 is changed to C
i=i+1;
}
else if((str[i]=='2')&&(flag2==1))
{
i=i+1; //Skip 2
}
else if(str[i]=='C')
{
i=i+1; //Skip C
}
}
j=j+1;
if(j==le)
{
break;
}
}
}
OUTPUT
EXP NO : 08
AIM: To study and understand the formal design, specification and modelling of the
ATM system using Finite State Machine
An ATM system is a real-time front terminal of automatic teller services with the
support of a central bank server and a centralized account database. The ATM provides
money withdrawal and account balance management services. It encompasses an ATM
processor, a system clock, a remote account database, and a set of peripheral devices
such as the card reader, monitor, keypad, bills storage and bills disburser. The
conceptual model of an ATM system is usually described by a Finite State Machine
(FSM) which adopts a set of states and a set of transitions modelled by a transition
diagram or a transition table to describe the basic behaviours of the ATM system,
FORMAL DEFINITION OF THE FINITE STATE MACHINE :
s0 e0 s1
s1 e1 s2
s2 e2 s3
s2 e3 s2
s2 e6 s7
s3 e4 s4
s3 e5 s3
s3 e6 s7
s4 e7 s5
s4 e8 s7
s5 e9 s6
s5 e10 s7
s6 - s7
s7 - s1
RESULT:
The conceptual model of ATM system, its configuration, basic behaviours and logical
relationships among components of the ATM system are studied.
EXP NO : 8(B)
DATE :
PATTERN SEARCHING
AIM: To study and understand the formal design, specification and modelling of Pattern
Searching / Text Searching using Finite State Machine
A Simple Example:
Suppose a text file consists of only a’s and b’s and the search is for the string “abba”.
The corresponding finite automata will be as follows:
Start searching for the string from the initial state 0 and when the final state 4 is
reached, the search is successful.
A Complex Example :
For example, let us design a Finite Automata for accepting the keywords “ezhil”, “hills”
and “lssbus” in a text file. The Nondeterministic Finite Automata (NFA) can be built
quickly for the given problem. Based on the number of keywords and its length, the size
of the NFA may vary.
Formal definition of the NFA can be written as
N = (Q, 𝚺, δ, q0, F)
where
• Q → set of states {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}
• 𝚺 → input alphabet {a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z}
• q0 → initial state. 1
• F → set of final states {6, 11, 17}
• δ → transition function which is shown below as transition diagram and table
Transition Diagram :
State Transition Table :
Sample Input :
dr ezhilarasu umadevi went to nilgiri hills by lssbus. Ezhil visited many places in
that
hills. On the way, he saw one flex which has the word ezhillssbus
Starting from the initial state, taking the input character by character, if one of the final
states is reached, the input word will be accepted.
SAMPLE C PROGRAM :
return 0;
}
int TF[M+1][NO_OF_CHARS];
computeTF(pat, M, TF);
RESULT:
The conceptual model of the pattern searching system, the method for constructing
NFA for the required keywords and searching for the required keywords in a text
file are studied.
EXP NO : 8(C)
DATE :
VENDING MACHINE
AIM: To study and understand the formal design, specification and modelling of
Vending Machine using Finite State Machine
Vending machines (VM) are electronic devices used to provide different products such
as snacks, coffee, tickets, etc. Vending machines provide several different types of items
when money is inserted into it. The Vending machines are more practical, easy to use
and accessible for user than the standard purchasing method. The efficient
implementation of these machines can be in different ways by using microcontroller
and FPGA board. They are designed to be able to accept money and serve product
according to the amount of money inserted. The basic operation of VM is given below.
• The user inserts money and the money counter sends to the control unit, the amount
of money inserted in the VM by the user.
• The operation buttons are active to choose the products that people like. According
to the VM’s internal program, VM dispenses the products when people insert the
correct amount.
• If the program is designed to return the change, VM will return the change.
• When selected product is not available, VM will reject the service.
FLOW CHART FOR THE OPERATION OF SODA VENDINGMACHINE :
FORMAL DEFINITION OF THE FINITE AUTOMATA:
A DFA that describes the behaviour of a vending machine which accepts dollars and
quarters and charges $1.25 per soda. Once the machine receives at least $1.25,
corresponding to the final states, it will allow the user to select a soda. Self loops
represent ignored input. The machine will not dispense a soda until at least $1.25 has
been deposited and it will not accept more money once it has already received greater
than or equal to $1.25.
Transition Diagram :
RESULT:
The conceptual model of the vending machine is studied using FSM automata theory.
Constructing a FSM which uses fewer states enables the machine to provide fast
response serving.
EXP NO : 8(D)
DATE :
AIM: To study and understand the formal design, specification and modelling of Natural
Language Processing using Automata Theory
Natural language processing is a field of linguistics and computer science which focuses
on processing natural language. Natural languages are human spoken languages like
English, Telugu and Tamil, in opposition to artificial languages such computer languages
C or Java. The main goal of NLP is to make human languages automatically processable.
It implies finding techniques to convert an utterance which can be either spoken or
written into formal data. Formal data are a representation of that utterance that can be
processed using a computer and with no or minimal supervision. Some part of natural
language processing relies on automata theory.
Suppose we want to recognize dates (just day and month pairs) written in the format
day/month. The day and the month may be expressed as one or two digits (e.g. 11/2,
1/12 etc.). This format corresponds to the following simple FSA, where each character
corresponds to one transition:
This is a NFA. For example, an input starting with the digit 3 will move the FSA to both
state 2 and state 3.
Suppose we want to recognize a comma-separated list of such dates, the FSA can be
designed as shown below. It has a cycle and can accept a sequence of indefinite length.
Lexicon :
Constructing a Deterministic Finite Automata can improve the access and minimizing
the automata can reduce the number of states considerably.
The syntax of natural languages cannot be described by Finite Automata. Strings having
infinite recursion cannot be generated by a FSM. However, FSMs are very useful for
partial grammars which don’t require full recursion. For representing complex
structures, context free grammars are useful.
CONTEXT FREE GRAMMARS :
CFGs arise in linguistics where they are used to describe the structure of sentences and
words in a natural language, and they were in fact invented by the linguist Noam
Chomsky for this purpose.
In computer science, as the use of recursively-defined concepts increased, they are used
more and more. In an early application, grammars are used to describe the structure of
programming languages. In a newer application, they are used in an essential part of
the Extensible Markup Language (XML) called the Document Type Definition.
S -> NP VP
VP -> VP PP
VP -> V
VP -> V NP
VP -> V VP
NP -> NP PP
PP -> P NP
;;; lexicon
V -> can
V -> fish
NP -> fish
NP -> rivers
NP -> pools
NP -> December
NP -> Scotland
NP -> it
NP -> they
P -> in
The rules with terminal symbols on the RHS correspond to the lexicon. Here are some
strings which the grammar generates, along with their bracketings:
they fish
(S (NP they) (VP (V fish)))
Parse Tree
A CFG only defines a language. It does not say how to determine whether a given string
belongs to the language it defines. To do this, a parser can be used whose task is to map
a string of words to its parse tree. A parse tree or derivation tree is an ordered, rooted
tree that represents the syntactic structure of a string according to some context-free
grammar.
RESULT:
The application of finite automata and Context Free Grammars in the field of natural
language processing is studied.