Скачиваний:
28
Добавлен:
02.05.2014
Размер:
34.23 Кб
Скачать
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
#include "time.h"
#include "fstream.h"
#include "string.h"
#include "math.h"
#include "stdio.h"
#include "stdlib.h"
TForm1 *Form1;

String stack[256];
String terminal[32];
String input_line[256];
String rules[32];
String input_rules[256];
String input_lex[256];
int current_lex;
int index_rule;
int **mega_matrix;
int all_rules;
//----------------------номер терминального символа------------
int TForm1:: index_terminal(String trm)
{
        int i=0;
        if(trm=="bgn")
        {
                trm="over";
        }
        while(terminal[i]!="#")
        {
                if(trm==terminal[i])
                {
                        return i-1;
                }
                i++;
        }
        return -1;
}
//----------------------номер верхнего элемента в стеке--------
int TForm1::first_terminal(int n)
{
        for(int i=n;i!=0;i--)
        {
                if(index_terminal(stack[i])!=-1) return i;
        }
        return false;
}
//----------------------значение элемента матрицы предш--------
int TForm1::cmp_substr(String sub1, String sub2)
{
        int i,j;
        for(j=0;j<matrix->RowCount;j++)
        {
                if(matrix->Cells[0][j]==sub1)
                {
                        break;
                }
        }
        for(i=0;i<matrix->ColCount;i++)
        {
                if(matrix->Cells[i][0]==sub2)
                {
                        break;
                }
        }
        if(i<matrix->ColCount && j<matrix->RowCount)
        {
                return matrix->Cells[i][j].ToInt();
        }
        else
        {
                out->Lines->Add((AnsiString)sub1+"->"+sub2);
                return -1;
        }
}
//----------------------сдвиг----------------------------------
void TForm1::sdvig(int count_s,int count_l)
{
        stack[count_s+1]=input_line[count_l];
}
//----------------------считывание правил----------------------
int TForm1::AddRules()
{
        ruli->Items->LoadFromFile("rul'.txt");
        for(int i=0; i<ruli->Items->Count;i++)
        {
                rules[i]=ruli->Items->Strings[i].Trim();
                ruli->Items->Strings[i]=(AnsiString)ruli->Items->Strings[i]+" "+(i+1);
                while(rules[i].Pos(" ")) {rules[i].Delete(rules[i].Pos(" "),1);}
        }
        return ruli->Items->Count;
}
//----------------------ищем правило---------------------------
int TForm1::cmp_rules(String rls,int n)
{
        for(int i=0;i<n;i++)
        {
                if(rls==rules[i])
                {
                        return i;
                }
        }
        return -1;
}
//----------------------свертка--------------------------------
int TForm1::package(int count_st,int n)
{
        String trm,tV,Vt,VVt,V;
        int ftrm=first_terminal(count_st);
        int rez;
        trm=stack[ftrm];
        tV=trm+stack[ftrm+1];
        Vt=stack[ftrm-1]+trm;
        V=stack[ftrm-1]+trm+stack[ftrm+1];
        VVt=stack[ftrm-2]+stack[ftrm-1]+trm;

        rez=cmp_rules(trm,n);
        if(rez>=0)
        {
                stack[ftrm]="S";
                input_rules[index_rule]=IntToStr(rez);
                index_rule++;
                return 0;
        }
        rez=cmp_rules(V,n);
        if(rez>=0)
        {
                String right_empty=stack[ftrm+1];
                stack[ftrm-1]="S";
                stack[ftrm]="";
                stack[ftrm+1]="";
                input_rules[index_rule]=IntToStr(rez);
                index_rule++;
                if(right_empty=="")
                {
                        return 1;
                }
                else
                {
                        return 2;
                }
        }
        rez=cmp_rules(Vt,n);
        if(rez>=0)
        {
                stack[ftrm-1]="S";
                stack[ftrm]="";
                input_rules[index_rule]=IntToStr(rez);
                index_rule++;
                return 1;
        }
        rez=cmp_rules(tV,n);
        if(rez>=0)
        {
                stack[ftrm]="S";
                stack[ftrm+1]="";
                input_rules[index_rule]=IntToStr(rez);
                index_rule++;
                return 1;
        }
        rez=cmp_rules(VVt,n);
        if(rez>=0)
        {
                stack[ftrm-2]="S";
                stack[ftrm-1]="";
                stack[ftrm]="";
                input_rules[index_rule]=IntToStr(rez);
                index_rule++;
                return 2;
        }
        return -1;
}
//---------------------------------------------------------------------------
int search_ac(int current_ac,int line_index)
{
        int i;
        for(i=current_ac;i>0;--i)
        {
                if(input_line[i]=="a" || input_line[i]=="c")
                {
                        break;
                }
        }
        return i;
}
//----------------------новая ветвь дерева---------------------
void TForm1::AddChild(String child,int ind_item, int line_index)
{
        int lenght=child.Length();
        char *rezult_child;
        String temp_string="";
        rezult_child=new char [lenght];
        TTreeNode *Node1;
        Node1=tree->Items->Item[ind_item];
        strcpy(rezult_child,child.c_str());

        for(int i=0;i<lenght;i++)
        {
                temp_string = temp_string + rezult_child[i];
                if(temp_string=="S")
                {
                        tree->Items->AddChild(Node1,temp_string);
                        temp_string="";
                }
                if(rezult_child[i+1]!='.')
                {
                        if(index_terminal(temp_string)>=0)
                        {
                                if(temp_string!="c" && temp_string!="a")
                                {
                                        tree->Items->AddChild(Node1,temp_string);
                                }
                                else
                                {
                                        current_lex=search_ac(current_lex, line_index);
                                        tree->Items->AddChild(Node1, input_lex[current_lex]);
                                        current_lex=current_lex-1;
                                }
                                temp_string="";
                        }
                }
        }
}
bool Check_Ident(String Ident[], int count, String current_ident)
{
        int i;
        for(i=0;i<count;++i)
        {
                if(Ident[i]==current_ident)
                {
                        return true;
                }
        }
        return false;
}

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
int TForm1::rehash(int i)
{
        int rnd;
        rnd=rand()%512;
        arr->Items->Add(rnd);
        return (reh->Cells[1][i].ToInt()+rnd)%512;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
        if(OpenDialog1->Execute())
        {
                int j,i,k=0,rnd;
                ListBox1->Items->LoadFromFile(OpenDialog1->FileName);
                Memo1->Lines->Add("открыт Файл: "+OpenDialog1->FileName);
                fname->Caption=OpenDialog1->FileName;
                reh->RowCount=ListBox1->Count+1;
                arr->Clear();
                randomize();
                for(i=0,k=0;i<ListBox1->Count;i++)
                {
                        reh->Cells[0][i+1]=i+1;
                        reh->Cells[2][i+1]=ListBox1->Items->Strings[i];
                        reh->Cells[1][i+1]=(int)reh->Cells[2][i+1].c_str()[0]+(int)reh->Cells[2][i+1].c_str()[1];
                        for(j=0;j<i;j++)
                        {
                                if(reh->Cells[1][i+1]==reh->Cells[1][j+1])
                                {
                                        reh->Cells[1][i+1]=rehash(i+1);
                                        j=0;
                                        k++;
                                }
                        }
                }

                Memo1->Lines->Add("создана таблица идентификаторов методом рехеширования с использованием псевдослучайных чисел");
                Memo1->Lines->Add((AnsiString)"найдено "+k+" коллизий");
                list->RowCount=ListBox1->Count+1;
                for(i=0;i<ListBox1->Count;i++)
                {
                        list->Cells[0][i+1]=i+1;
                        list->Cells[1][i+1]=ListBox1->Items->Strings[i];
                }
                for(i=0;i<ListBox1->Count;i++)
                {
                        for(j=i+1;j<ListBox1->Count;j++)
                        {
                                if((int)list->Cells[1][i+1].c_str()[0]+(int)list->Cells[1][i+1].c_str()[1]==(int)list->Cells[1][j+1].c_str()[0]+(int)list->Cells[1][j+1].c_str()[1])
                                {
                                        list->Cells[2][i+1]=j+1;
                                        break;
                                }
                        }
                }
                Memo1->Lines->Add("создана таблица идентификаторов методом цепочек");
        }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::TabSheet5Show(TObject *Sender)
{
        Close();         
}
//---------------------------------------------------------------------------
void __fastcall TForm1::TabSheet1Show(TObject *Sender)
{
                reh->Cells[0][0]="#";
                reh->Cells[1][0]="хэш код";
                reh->Cells[2][0]="идентификатор";
                list->Cells[0][0]="#";
                list->Cells[1][0]="идентификатор";
                list->Cells[2][0]="ссылка";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N6Click(TObject *Sender)
{
        if(ListBox1->ItemIndex>=0)
        {
                Edit1->Text=ListBox1->Items->Strings[ListBox1->ItemIndex];
        }
}
//---------------------------------------------------------------------------


void __fastcall TForm1::BitBtn2Click(TObject *Sender)
{
        int i,j,k,S,St;
        bool fl=false;
        int z=-1;
        if(all->Checked)
        {
                for(j=1,k=0;j<=ListBox1->Count;j++)
                {
                        St=S=reh->Cells[1][j].ToInt();
                        for(z=-1;z<arr->Items->Count;z++)
                        {
                                if(z>=0)
                                {
                                        St=(S+arr->Items->Strings[z].ToInt())%512;
                                }
                                if(RadioGroup1->ItemIndex==1)
                                {
                                        z=arr->Items->Count;
                                }
                                for(i=1;i<=ListBox1->Count;i++)
                                {
                                        if(St==reh->Cells[1][i].ToInt() && RadioGroup1->ItemIndex==0)
                                        {
                                                if(Edit1->Text==reh->Cells[2][i])
                                                {
                                                        arr->ItemIndex=z;
                                                }
                                                else
                                                {
                                                        k++;
                                                }
                                                break;
                                        }
                                        else if(S==((int)list->Cells[1][i].c_str()[0]+list->Cells[1][i].c_str()[1]) && RadioGroup1->ItemIndex==1)
                                        {
                                                if(Edit1->Text==list->Cells[1][i])
                                                {
                                                        break;
                                                }
                                                else if(list->Cells[2][i].Length()>0)
                                                {
                                                        i=list->Cells[2][i].ToInt()-1;
                                                }
                                                else
                                                {
                                                        break;
                                                }
                                                k++;
                                        }
                                }
                        }
                }
        }
        else
        {
                St=S=((int)Edit1->Text.c_str()[0]+(int)Edit1->Text.c_str()[1])%512;
                for(z=-1,k=0;z<arr->Items->Count;z++)
                {
                        if(z>=0)
                        {
                                St=(S+arr->Items->Strings[z].ToInt())%512;
                        }
                        if(RadioGroup1->ItemIndex==1)
                        {
                                z=arr->Items->Count;
                        }
                        for(i=1;i<=ListBox1->Count;i++)
                        {
                                if(St==reh->Cells[1][i].ToInt() && RadioGroup1->ItemIndex==0)
                                {
                                        if(Edit1->Text==reh->Cells[2][i])
                                        {
                                                fl=true;
                                                arr->ItemIndex=z;
                                        }
                                        else
                                        {
                                                k++;
                                        }
                                        break;
                                }
                                else if(S==((int)list->Cells[1][i].c_str()[0]+list->Cells[1][i].c_str()[1]) && RadioGroup1->ItemIndex==1)
                                {
                                        if(Edit1->Text==list->Cells[1][i])
                                        {
                                                fl=true;
                                                break;
                                        }
                                        else if(list->Cells[2][i].Length()>0)
                                        {
                                                i=list->Cells[2][i].ToInt()-1;
                                        }
                                        else
                                        {
                                                break;
                                        }
                                        k++;
                                }
                        }
                        if(fl)
                        {
                                break;
                        }
                }
                if(!fl)
                {
                        Memo1->Lines->Add("идентификатор не найден");
                }
                else
                {
                        Memo1->Lines->Add((AnsiString)"найдено в "+i+" строке");
                }
        }
        Memo1->Lines->Add((AnsiString)k+" коллизий");
}
//---------------------------------------------------------------------------

void __fastcall TForm1::N2Click(TObject *Sender)
{
        RadioGroup1->ItemIndex=0;
        if(ListBox1->ItemIndex>=0)
        {
                Edit1->Text=ListBox1->Items->Strings[ListBox1->ItemIndex];
        }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::N3Click(TObject *Sender)
{
        RadioGroup1->ItemIndex=1;
        if(ListBox1->ItemIndex>=0)
        {
                Edit1->Text=ListBox1->Items->Strings[ListBox1->ItemIndex];
        }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::allClick(TObject *Sender)
{
        if(all->Checked)
        {
                Edit1->Enabled=false;
                Edit1->Text="";
        }
        else
        {
                Edit1->Enabled=true;
        }

}
//---------------------------------------------------------------------------

void __fastcall TForm1::Edit1Change(TObject *Sender)
{
        if(all->Checked)
        {
                Edit1->Text="";
        }
}
//---------------------------------------------------------------------------
struct ls
{
        char txt[100];
        ls *next;
};
struct mtmp
{
        char txt[20];
        mtmp *next;
};
void __fastcall TForm1::BitBtn3Click(TObject *Sender)
{
        out->Clear();        
        if(OpenDialog2->Execute())
        {
                ifstream in(OpenDialog2->FileName.c_str());
                int k=1;
                bool fl=true;
                char tmp[100];
                lex->Cells[0][0]="#";
                lex->Cells[1][0]="лексема";
                lex->Cells[2][0]="значение лексемы";
                lex->RowCount=2;
                fname2->Caption=OpenDialog2->FileName;
                fname3->Caption=OpenDialog2->FileName;
                Memo2->Lines->LoadFromFile(OpenDialog2->FileName);
                Memo3->Lines->LoadFromFile(OpenDialog2->FileName);
                while(in>>tmp)
                {
                        if(fl)
                        {
                                if((AnsiString)tmp=="(*")
                                {
                                        fl=false;
                                }
                                else if((AnsiString)tmp=="prog")
                                {
                                        lex->Cells[2][k]="ключевою слово";
                                }
                                else if((AnsiString)tmp=="end.")
                                {
                                        lex->Cells[2][k]="ключевою слово";
                                }
                                else if((AnsiString)tmp=="end")
                                {
                                        lex->Cells[2][k]="ключевою слово";
                                }
                                else if((AnsiString)tmp=="else")
                                {
                                        lex->Cells[2][k]="ключевою слово";
                                }
                                else if((AnsiString)tmp=="if")
                                {
                                        lex->Cells[2][k]="ключевою слово";
                                }
                                else if((AnsiString)tmp=="then")
                                {
                                        lex->Cells[2][k]="ключевою слово";
                                }
                                else if((AnsiString)tmp=="begin")
                                {
                                        lex->Cells[2][k]="ключевою слово";
                                }
                                else if((AnsiString)tmp=="for")
                                {
                                        lex->Cells[2][k]="ключевою слово";
                                }
                                else if((AnsiString)tmp=="not")
                                {
                                        lex->Cells[2][k]="логическое отрицание";
                                }
                                else if((AnsiString)tmp=="and")
                                {
                                        lex->Cells[2][k]="логическое \"И\"";
                                }
                                else if((AnsiString)tmp=="or")
                                {
                                        lex->Cells[2][k]="логическое \"ИЛИ\"";
                                }
                                else if((AnsiString)tmp=="to")
                                {
                                        lex->Cells[2][k]="ключевою слово";
                                }
                                else if((AnsiString)tmp=="downto")
                                {
                                        lex->Cells[2][k]="ключевою слово";

                                }
                                else if((AnsiString)tmp=="do")
                                {
                                        lex->Cells[2][k]="ключевою слово";
                                }
                                else if((AnsiString)tmp==":=")
                                {
                                        lex->Cells[2][k]="оператор присваивания";
                                }
                                else if((AnsiString)tmp=="+" ||(AnsiString)tmp=="-" || (AnsiString)tmp=="*" || (AnsiString)tmp=="/")
                                {
                                        lex->Cells[2][k]="знак арифметическое операции";

                                }
                                else if((AnsiString)tmp==";")
                                {
                                        lex->Cells[2][k]="точка с запятой";
                                }
                                else if((AnsiString)tmp=="(" || (AnsiString)tmp==")")
                                {
                                        lex->Cells[2][k]="скобка";
                                }
                                else if((AnsiString)tmp==">>")
                                {
                                        lex->Cells[2][k]="дополнительные операции";
                                }
                                else if((AnsiString)tmp=="<<")
                                {
                                        lex->Cells[2][k]="дополнительные операции";
                                }
                                else if((AnsiString)tmp=="<")
                                {
                                        lex->Cells[2][k]="оператор сравнения";
                                }
                                else if((AnsiString)tmp==">")
                                {
                                        lex->Cells[2][k]="оператор сравнения";
                                }
                                else if((AnsiString)tmp=="=")
                                {
                                        lex->Cells[2][k]="оператор сравнения";
                                }
                                else
                                {
                                        bool num=true, id=true;
                                        for(int i=0;tmp[i]!='\0';i++)
                                        {
                                                if(!(isdigit(tmp[i]) && (tmp[i]=='1' || tmp[i]=='0')))
                                                {
                                                        num=false;
                                                        break;
                                                }
                                                else if(i>7)
                                                {
                                                        id=false;
                                                        num=false;
                                                        break;
                                                }
                                        }
                                        if(num)
                                        {
                                                lex->Cells[2][k]="число";
                                        }
                                        else
                                        {
                                                if((int)tmp[0]>0 && (int)tmp[0]<256)
                                                {
                                                        for(int i=1;i<tmp[i]!='\0';i++)
                                                        {
                                                                if(!((int)tmp[i]>0 && (int)tmp[i]<256 ||isdigit(tmp[i])))
                                                                {
                                                                        id=false;
                                                                        break;
                                                                }
                                                        }
                                                        if(id)
                                                        {
                                                                        lex->Cells[2][k]="переменная";
                                                        }
                                                        else
                                                        {
                                                                lex->Cells[2][k]="ошибка";
                                                        }
                                                }
                                                else
                                                {
                                                        lex->Cells[2][k]="ошибка";
                                                }
                                        }
                                }
                                if(fl)
                                {
                                        lex->RowCount=k+1;
                                        lex->Cells[1][k]=(AnsiString)tmp;
                                        lex->Cells[0][k]=k;
                                        k++;
                                }
                        }
                        else
                        {
                                if((AnsiString)tmp=="*)")
                                {
                                        fl=true;
                                }
                        }
                }
        }
//----------------------заполнение массива input_line _lex-----
        int j=0;
        String Ident[100];
        iden->RowCount=2;
        iden->Cells[0][0]="#";
        iden->Cells[1][0]="хэш";
        iden->Cells[2][0]="идентификатор";
        for(int i=0;i<lex->RowCount-1;i++)
        {
                if(lex->Cells[2][i+1]=="переменная")
                {
                        input_line[i]="a";
                        if(!Check_Ident(Ident,j,lex->Cells[1][i+1]))
                        {
                                Ident[j]=lex->Cells[1][i+1];
                                j++;
                                if(j>1)
                                {
                                        iden->RowCount=j;
                                }
                                iden->Cells[2][j]=Ident[j-1];
                                iden->Cells[1][j]=(int)Ident[j-1].c_str()[0];
                                for(int z=1;z<j;z++)
                                {
                                        if(iden->Cells[1][j]==iden->Cells[1][z])
                                        {
                                                iden->Cells[1][j]=(iden->Cells[1][j].ToInt()+123)%512;
                                        }
                                }
                                iden->Cells[0][j]=j;
                        }
                }
                else if(lex->Cells[2][i+1]=="число")
                {
                        input_line[i]="c";
                }
                else
                {
                        input_line[i]=lex->Cells[1][i+1];
                }
                input_lex[i]=lex->Cells[1][i+1];
        }
        input_line[lex->RowCount-1]="over";
        input_lex[lex->RowCount-1]="over";



//----------------------матрица предшестваования---------------
        ifstream in("matrix.txt");
        char tmp[10];
        mtmp *beg,*q,*q0;
        int i=0;
        beg=new mtmp;
        beg->next=beg;
        q0=beg;
        q=new mtmp;        
        while(in>>q->txt)
        {
                q->next=beg;
                q0->next=q;
                q0=q;
                q=new mtmp;
                i++;
        }
        in.close();
        int n;
        n=sqrt(i);
        mega_matrix=new int *[n-1];
        for(i=0;i<n-1;i++)
        {
                mega_matrix[i]=new int[n-1];
        }
        matrix->ColCount=n;
        matrix->RowCount=n;
        q=beg->next;
        i=j=0;
        while(q!=beg)
        {
                matrix->Cells[i][j]=q->txt;
                q=q->next;
                i++;
                if(i>=n)
                {
                        i=0;
                        j++;
                }
        }
        for(i=1;i<n;i++)
        {
                for(j=1;j<n;j++)
                {
                        if(matrix->Cells[i][j]=="<")
                        {
                                mega_matrix[j-1][i-1]=1;
                        }
                        else if(matrix->Cells[i][j]==">")
                        {
                                mega_matrix[j-1][i-1]=2;
                        }
                        else if(matrix->Cells[i][j]=="=")
                        {
                                mega_matrix[j-1][i-1]=0;
                        }
                        else
                        {
                                mega_matrix[j-1][i-1]=-1;
                        }
                }
        }
        for(i=0;i<n-1;i++)
        {
                for(j=0;j<n-1;j++)
                {
                        matrix->Cells[i+1][j+1]=mega_matrix[j][i];

                }
        }
//----------------------создание терминалов--------------------
        for(i=1;i<matrix->ColCount;i++)
        {
                terminal[i]=matrix->Cells[i][0];
        }
        terminal[i]="#";
//----------------------построение дерева----------------------
        all_rules = AddRules();
        int count_stack;
        stack[0] = "bgn";
        int stack_index = 0;
        int lines_index = 0;
        stack[0]="bgn";
        String temp;
        int cmp_rez;
        int left;
        int fl = 0;
        int t;
        while(1)
        {
                if((input_line[lines_index]=="over") && (stack[1]=="S") && (stack[2]==""))
                {
                        break;
                }
                cmp_rez=cmp_substr(stack[first_terminal(stack_index)],input_line[lines_index]);
                if(cmp_rez==1 || cmp_rez==0)
                {
                        sdvig(stack_index,lines_index);
                        lines_index++;
                        stack_index++;
                }
                else if(cmp_rez==2)
                {
                        left=package(stack_index,all_rules);
                        if(left==-1)
                        {
                                fl=1;
                                break;
                        }
                        else
                        {
                                stack_index=stack_index-left;
                        }
                }
                else
                {
                        fl=1;
                        break;
                }
        }
        if(fl==1)
        {
                out->Lines->Add("неправильная конструкция");
        }
        else
        {
                for(int k=0;k<index_rule;k++)
                {
                        temp += IntToStr(StrToInt(input_rules[k])+1) + "=>";
                        if(out->Lines->Strings[out->Lines->Count-1]!=IntToStr(StrToInt(input_rules[k])+1))
                        {
                                out->Lines->Strings[out->Lines->Count-1]=(AnsiString)out->Lines->Strings[out->Lines->Count-1]+" "+IntToStr(StrToInt(input_rules[k])+1);
                        }
                }
        }
        current_lex=lines_index;
        TTreeNode *Node1;
        tree->Items->Clear();
        tree->Items->Add(NULL, "S");
        Node1 = tree->Items->Item[0];
        for(int j=index_rule;j>0;j--)
        {
                int n = tree->Items->Count;
                for (int i=n-1;i>=0;i--)
                {
                        if(tree->Items->Item[i]->HasChildren==false)
                        {
                                if(tree->Items->Item[i]->Text=="S")
                                {
                                        AddChild(rules[StrToInt(input_rules[j-1])],i, lines_index);
                                        break;
                                }
                        }
                }
        }
}
//---------------------------------------------------------------------------






Соседние файлы в папке Курсовой проект [вариант 14]