Скачиваний:
34
Добавлен:
02.05.2014
Размер:
227.33 Кб
Скачать

Пример разбора предложения

Пример: a:=-(a+a)*a/a;

{a:=-(a+a)*a/a;⊥K; ⊥H; λ} {;⊥K; ⊥H a:=E/a; 9 9 2 8 9 4}

{:=-(a+a)*a/a;⊥K; ⊥H a; λ} {;⊥K; ⊥H a:=E /E; 9 9 2 8 9 4 9}

{ -(a+a)*a/a;⊥K; ⊥H a:=; λ} {;⊥K; ⊥H a:=E; 9 9 2 8 9 4 9 5}

{ (a+a)*a/a;⊥K; ⊥H a:=-; λ} {⊥K; ⊥H a:=E; ; 9 9 2 8 9 4 9 5}

{ a+a)*a/a;⊥K; ⊥H a:=-(; λ} {⊥K; ⊥ H E; 9 9 2 8 9 4 9 5 1}

{ +a)*a/a;⊥K; ⊥H a:=-(a; λ}

{ +a)*a/a;⊥K; ⊥H a:=-(E; 9}

{ a)*a/a;⊥K; ⊥H a:=-(E+; λ}

{)*a/a;⊥K; ⊥H a:=-(E+a; λ}

{)*a/a;⊥K; ⊥H a:=-(E+E; 9 9}

{)*a/a;⊥K; ⊥H a:=-(E; 9 9 2}

{*a/a;⊥K; ⊥H a:=-(E); 9 9 2}

{*a/a;⊥K; ⊥H a:=E; 9 9 2 8}

{a/a;⊥K; ⊥H a:=E*; 9 9 2 8}

{ /a;⊥K; ⊥H a:=E*a; 9 9 2 8}

{ /a;⊥K; ⊥H a:=E*E; 9 9 2 8 9}

{ /a;⊥K; ⊥H a:=E; 9 9 2 8 9 4}

{ a;⊥K; ⊥H a:=E/; 9 9 2 8 9 4}

Листинг программы

// LabSPODlg.cpp : implementation file

//

#include "stdafx.h"

#include "LabSPO.h"

#include "LabSPODlg.h"

#include "MyLab2_func.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CLabSPODlg dialog

CLabSPODlg::CLabSPODlg(CWnd* pParent /*=NULL*/)

: CDialog(CLabSPODlg::IDD, pParent)

{

//{{AFX_DATA_INIT(CLabSPODlg)

//}}AFX_DATA_INIT

// Note that LoadIcon does not require a subsequent DestroyIcon in Win32

m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

void CLabSPODlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CLabSPODlg)

DDX_Control(pDX, IDC_LIST_ABOUT_TREE, m_AbTr);

DDX_Control(pDX, IDC_TREE1, m_TreeOut);

DDX_Control(pDX, IDC_LIST_SYN_ERR, m_SynErr);

DDX_Control(pDX, IDC_LIST_LT_PROP, m_ListProp);

DDX_Control(pDX, IDC_LIST_LT_ID, m_ListID);

DDX_Control(pDX, IDC_LIST_RULE, m_RuleList);

DDX_Control(pDX, IDC_LIST_ERR, m_MsgErr);

DDX_Control(pDX, IDC_MY_LIST, m_List);

//}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(CLabSPODlg, CDialog)

//{{AFX_MSG_MAP(CLabSPODlg)

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

ON_BN_CLICKED(ID_GEN_OUT, OnGenOut)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CLabSPODlg message handlers

BOOL CLabSPODlg::OnInitDialog()

{

CDialog::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically

// when the application's main window is not a dialog

SetIcon(m_hIcon, TRUE); // Set big icon

SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here

return TRUE; // return TRUE unless you set the focus to a control

}

// If you add a minimize button to your dialog, you will need the code below

// to draw the icon. For MFC applications using the document/view model,

// this is automatically done for you by the framework.

void CLabSPODlg::OnPaint()

{

if (IsIconic())

{

CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

// Center icon in client rectangle

int cxIcon = GetSystemMetrics(SM_CXICON);

int cyIcon = GetSystemMetrics(SM_CYICON);

CRect rect;

GetClientRect(&rect);

int x = (rect.Width() - cxIcon + 1) / 2;

int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon

dc.DrawIcon(x, y, m_hIcon);

}

else

{

CDialog::OnPaint();

}

}

// The system calls this to obtain the cursor to display while the user drags

// the minimized window.

HCURSOR CLabSPODlg::OnQueryDragIcon()

{

return (HCURSOR) m_hIcon;

}

void CLabSPODlg::OnGenOut()

{

// TODO: Add your control notification handler code here

UpdateData();

char ch, ID[64][40], buffer[64][40];

char Del[1][20]={'d','e','l','i','m','e','t','e','r'};

char Oper[1][20]={'o','p','e','r','a','t','i','o','n',' ','s','i','g','n'};

char Brack[1][20]={'b','r','a','c','k','e','t'};

char Cons[1][20]={'c','o','n','s','t'};

char Sl[1][40]; for(int i=0; i<40; i++) Sl[0][i]=NULL; Sl[0][0]='/';

char Appr[1][20]={'a','p','p','r','o','p','r','i','a','t','i','o','n'};

char Identi[1][20]={'i','d','e','n','t','i','f','i','e','r'};

for (int j=0; j<64; j++)

{for (int i=0; i<64; i++) buffer[j][i]=NULL;}

Table TLex(64); int codeEr=0;

bool errlex=false, errsynt=false;

enum State { STATE_A, STATE_B, STATE_M, STATE_N, STATE_D, STATE_E, STATE_O, STATE_V,

STATE_W, STATE_H, STATE_S, STATE_C, STATE_C1, STATE_C2};

char FileName[7]={'e','x','.','t','x','t'};

ifstream ReadFromFile(FileName);

State St; St=STATE_H; int d=0, e=0;

while (ReadFromFile.get(ch))

{

if (St==STATE_E){ if(ch!=' ') continue;

else {St=STATE_H;for(i=0; i<40; i++) buffer[d][i]=NULL;e=0;continue;}};

if (ch!=' ') {if(ch!='\r'){if(ch!='\n') {if(ch!='/') {if(St!=STATE_C)

{if(St!=STATE_C1) {if (St!=STATE_C2)

{buffer[d][e]=ch; e++;};}}}}}}

switch (St)

{

case (STATE_H):

{

switch(ch){

case 'a':St=STATE_V; break; case 'b':St=STATE_V; break;

case 'c':St=STATE_V; break; case 'd':St=STATE_V; break;

case 'e':St=STATE_V; break; case 'f':St=STATE_V; break;

case 'g':St=STATE_V; break; case 'h':St=STATE_V; break;

case 'i':St=STATE_V; break; case 'j':St=STATE_V; break;

case 'k':St=STATE_V; break; case 'l':St=STATE_V; break;

case 'm':St=STATE_V; break; case 'n':St=STATE_V; break;

case 'o':St=STATE_V; break; case 'p':St=STATE_V; break;

case 'q':St=STATE_V; break; case 'r':St=STATE_V; break;

case 's':St=STATE_V; break; case 't':St=STATE_V; break;

case 'u':St=STATE_V; break; case 'v':St=STATE_V; break;

case 'w':St=STATE_V; break; case 'x':St=STATE_V; break;

case 'y':St=STATE_V; break; case 'z':St=STATE_V; break;

case (':'): St=STATE_A; break;

case '*' : St=STATE_O; break; case '-' : St=STATE_O; break;

case '+' : St=STATE_O; break; case '=' : St=STATE_O; break;

case '0' : St=STATE_N; break; case '1' : St=STATE_N; break;

case '2' : St=STATE_N; break; case '3' : St=STATE_N; break;

case '4' : St=STATE_N; break; case '5' : St=STATE_N; break;

case '6' : St=STATE_N; break; case '7' : St=STATE_N; break;

case '8' : St=STATE_N; break; case '9' : St=STATE_N; break;

case 'A': St=STATE_N; break; case 'B': St=STATE_N; break;

case 'C': St=STATE_N; break; case 'D': St=STATE_N; break;

case 'E': St=STATE_N; break; case 'F': St=STATE_N; break;

case '(' : St=STATE_M; break; case ')': St=STATE_M; break;

case ';' : St=STATE_D; break;

case '/' : St=STATE_C; break; case ' ': St=STATE_H;break;

default: errlex=true;codeEr=1;St=STATE_E;break;}; break;

};break;

case (STATE_D): if(ch==' ') {m_ListID.AddString(buffer[d]); m_ListProp.AddString(Del[0]);

TLex.createRec(d, buffer[d], Del[0] );d++; e=0; St=STATE_H; break; }

else {errlex=true;codeEr=2;St=STATE_E; break;}; break;

case (STATE_V):

{

switch(ch){

case 'a':St=STATE_V; break; case 'b':St=STATE_V; break;

case 'c':St=STATE_V; break; case 'd':St=STATE_V; break;

case 'e':St=STATE_V; break; case 'f':St=STATE_V; break;

case 'g':St=STATE_V; break; case 'h':St=STATE_V; break;

case 'i':St=STATE_V; break; case 'j':St=STATE_V; break;

case 'k':St=STATE_V; break; case 'l':St=STATE_V; break;

case 'm':St=STATE_V; break; case 'n':St=STATE_V; break;

case 'o':St=STATE_V; break; case 'p':St=STATE_V; break;

case 'q':St=STATE_V; break; case 'r':St=STATE_V; break;

case 's':St=STATE_V; break; case 't':St=STATE_V; break;

case 'u':St=STATE_V; break; case 'v':St=STATE_V; break;

case 'w':St=STATE_V; break; case 'x':St=STATE_V; break;

case 'y':St=STATE_V; break; case 'z':St=STATE_V; break;

case '0' : St=STATE_W; break; case '1' : St=STATE_W; break;

case '2' : St=STATE_W; break; case '3' : St=STATE_W; break;

case '4' : St=STATE_W; break; case '5' : St=STATE_W; break;

case '6' : St=STATE_W; break; case '7' : St=STATE_W; break;

case '8' : St=STATE_W; break; case '9' : St=STATE_W; break;

case ' ' : TLex.createRec(d, buffer[d], Identi[0]);

m_ListID.AddString(buffer[d]); m_ListProp.AddString(Identi[0]);

d++;e=0;St=STATE_H; break;

default: errlex=true;codeEr=3;St=STATE_E;break;}

} ;break;

case (STATE_A): if(ch=='=') { St=STATE_B; break;} else {St=STATE_E;break;}

case (STATE_B): if(ch==' ') {TLex.createRec(d, buffer[d], Appr[0]);

m_ListID.AddString(buffer[d]); m_ListProp.AddString(Appr[0]);

e=0;d++; St=STATE_H;break;}

else {errlex=true;codeEr=4;St=STATE_E; break;}

case (STATE_W):

{

switch(ch){

case '0' : St=STATE_W; break; case '1' : St=STATE_W; break;

case '2' : St=STATE_W; break; case '3' : St=STATE_W; break;

case '4' : St=STATE_W; break; case '5' : St=STATE_W; break;

case '6' : St=STATE_W; break; case '7' : St=STATE_W; break;

case '8' : St=STATE_W; break; case '9' : St=STATE_W; break;

case ' ': TLex.createRec(d, buffer[d], Identi[0] );

m_ListID.AddString(buffer[d]); m_ListProp.AddString(Identi[0]);

d++; e=0;St=STATE_H; break;

default: errlex=true;codeEr=3;St=STATE_E;break;}

}; break;

case (STATE_N):

{

switch(ch){

case '0' : St=STATE_N; break; case '1' : St=STATE_N; break;

case '2' : St=STATE_N; break; case '3' : St=STATE_N; break;

case '4' : St=STATE_N; break; case '5' : St=STATE_N; break;

case '6' : St=STATE_N; break; case '7' : St=STATE_N; break;

case '8' : St=STATE_N; break; case '9' : St=STATE_N; break;

case 'A' : St=STATE_N; break; case 'D' : St=STATE_N; break;

case 'B' : St=STATE_N; break; case 'E' : St=STATE_N; break;

case 'C' : St=STATE_N; break; case 'F' : St=STATE_N; break;

case ' ': TLex.createRec(d, buffer[d], Cons[0] ); m_ListID.AddString(buffer[d]); m_ListProp.AddString(Cons[0]);

d++; e=0;St=STATE_H; break;

default: errlex=true;codeEr=5;St=STATE_E;}

}; break;

case (STATE_O): if(ch==' ') {TLex.createRec(d, buffer[d], Oper[0] );

m_ListID.AddString(buffer[d]); m_ListProp.AddString(Oper[0]);

d++;e=0;St=STATE_H; break;}

else {errlex=true;codeEr=4;St=STATE_E; break;}

case (STATE_M): if(ch==' ') {TLex.createRec(d, buffer[d], Brack[0] );

m_ListID.AddString(buffer[d]); m_ListProp.AddString(Brack[0]);

d++;e=0;St=STATE_H; break;}

else {errlex=true;codeEr=4;St=STATE_E;break;}

case (STATE_S): break;

case (STATE_C):

{switch(ch){

case '*': St=STATE_C1; break;

case ' ': TLex.createRec(d, Sl[0], Oper[0] );d++;e=0;St=STATE_H; break;

default: errlex=true;codeEr=6;St=STATE_E; break;}

}; break;

case (STATE_E): St=STATE_H; break;

case (STATE_C1): if (ch=='*') {St=STATE_C2; break;} else {St=STATE_C1; break;}

case (STATE_C2): if (ch=='/')

{St=STATE_H; break;}

else {St=STATE_C1; break;}

default: St=STATE_E; break;

}

}

ReadFromFile.close();

CString msgNE("Lex errors are absent in file"); CString msg1("Error lex");CString msg2("Error delimiter");

CString msg3("Error identifier");CString msg4("Error sign");CString msg5("Error const");

CString msg6("Error comment");

if (errlex==false) {m_MsgErr.AddString(msgNE);}

else

{switch(codeEr)

{

case 1: m_MsgErr.AddString(msg1); break;

case 2: m_MsgErr.AddString(msg2); break;

case 3: m_MsgErr.AddString(msg3); break;

case 4: m_MsgErr.AddString(msg4); break;

case 5: m_MsgErr.AddString(msg5); break;

case 6: m_MsgErr.AddString(msg6); break;

}

}

//////////////////////////синтаксический анализатор////////////////////////////

bool vi=true;

char Inp_Str[64], Stack[64];

CString msgNSE("Syntax errors are absent in file."),

msgSE("Syntax error occured!");

for( e=0; e<64; e++) Inp_Str[e]=NULL; for( e=0; e<64; e++) Stack[e]=NULL;

int r=0; char SeqRule[20]; for(e=0; e<20; e++) SeqRule[e]=NULL; int sch=0;

char sign, strBuff[10]; for(e=0; e<10; e++) strBuff[e]=NULL;

while(TLex.GetRecEF(sch)==false) {sch++;}

for(e=0; e<sch;e++)

{

if(TLex.GetRecProp(e)[0]=='c' ||TLex.GetRecProp(e)[0]=='i') Inp_Str[e] = 'a';

else Inp_Str[e] = TLex.GetRecId(e)[0];

//во входную строку записываю вх.цепочку,заменяя идент-ры и константы на а

}

Inp_Str[sch]='L';//заносим в конец вх.цепочки маркер конца строки

Stack[0]='F';

int t=0; // t-указатель на текущий анализируемый символ во вх.цепочке

int s=0; //счетчик символов в стеке

int k=0, y=0;

do

{

m_List.AddString(Stack);

if(Stack[0]!='E') sign=OPM(Stack[0], Inp_Str[t]);

else sign=OPM(Stack[1], Inp_Str[t]);

if(sign==' ') { vi=false; break;}

if(sign=='<' || sign == '=') // сдвиг

{

for(e=s; e>=0; e--) {Stack[e+1]=Stack[e]; s++;};

Stack[0]=Inp_Str[t];

t++;

} //конец сдвига

if(sign=='>') // свертка

{

if (Stack[0]=='E')

{ y=0;

while(Stack[y]=='E') y++; //если в вершине стека нетермю символ, то ищем

strBuff[0]=Stack[y-1]; //след. терм.

strBuff[1]=Stack[y];

strBuff[2]=Stack[y+1];

y=3;

}

else

{

j=0; y=0;

strBuff[j]=Stack[0]; j++;

while(true)

{

if(Stack[y+1]=='E') y=y+2; else y++;

if(OPM(Stack[y], strBuff[j-1]) == '=')

{

for(e=1; e<10; e++) strBuff[e]=NULL;

for(e=1; e<=y; e++) strBuff[e]=Stack[e];

j=y+1;

}

else break;

}

}

r=Grammar(strBuff);

if ( r>='1' && r<='9' ){

SeqRule[k]=r; k++;

for(e=0;e<y;e++) Stack[e]=NULL;

Stack[y-1]='E';

while(Stack[0]==NULL) for(e=0; e<=s; e++) {Stack[e]=Stack[e+1]; Stack[e+1]=NULL; s--;}}

else {vi=false; break;}

}

for(e=0; e<10; e++) {strBuff[e]=NULL;};

Inp_Str[t-1]=NULL;

}while(Stack[1]!='F' || Inp_Str[t]!='L');

if(vi!=false)

{

m_List.AddString(Stack);

m_RuleList.AddString(SeqRule); m_SynErr.AddString(msgNSE);

}

else {m_SynErr.AddString(msgSE);}

///////////////////////////////вывод дерева/////////////////////////////////////////////////

if (vi!=false)

{

CString q1(" This tree was built:"); m_AbTr.AddString(q1);

TVINSERTSTRUCT myTree;

HTREEITEM ParStore[20];

int a=0, pPS=0; k--;

myTree.hParent=TVI_ROOT;

myTree.hInsertAfter=TVI_LAST;

myTree.item.mask=TVIF_TEXT;

myTree.item.pszText="E";

ParStore[pPS]=m_TreeOut.InsertItem(&myTree);

char numRul=SeqRule[k];//номер правила

myTree.hParent=ParStore[pPS];

for(e=k;e>=0;e--)

{

myTree.hParent=ParStore[pPS];//сделать родителем текущий эл-т стека

pPS++; ParStore[pPS]=0;//поставить разделитель м/у уровнями

numRul=SeqRule[e]; a=0;

while(Output(SeqRule[e])[a]!=NULL)

{

CString S1=Output(SeqRule[e])[a];

LPSTR S2=S1.GetBuffer(S1.GetLength());

myTree.item.pszText=S2;

//если в правиле Е,то этот узел будет родителем

if(S1=="E")

{

pPS++;

ParStore[pPS]=m_TreeOut.InsertItem(&myTree);

}

else

{

m_TreeOut.InsertItem(&myTree);

}

a++;

}

while(pPS)

{

if(ParStore[pPS]==0)

{

ParStore[pPS]=0; pPS--;

ParStore[pPS]=0; pPS--;

}

else {break;}

}

}

}

else {CString q("Tree can't be built because of error!"); m_AbTr.AddString(q);}

}