// SimpleFirstAnalyse.cpp: implementation of the SimpleFirstAnalyse class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "简单优先_While.h"
#include "SimpleFirstAnalyse.h"
#include "PtrStack.h"
#include "SymAnalyse.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//
//
//
//
/*
0----------------------------------S根
1----------------------------------while
2----------------------------------E 布尔表达式
3----------------------------------do
4----------------------------------s 赋值语句 例如:i= j+3
5----------------------------------id 变量名
6----------------------------------opL 逻辑运算符 < >
7----------------------------------const 整数 如: 1 2 3
8----------------------------------= 赋值运算符
9----------------------------------idC id 或 const
10----------------------------------opA 算术操作符 + - * /
11----------------------------------# 结束符
*/
/*
简单优先关系定义如下:
没有关系 -------------- 0
<. -------------- 1
.=. -------------- 2
.> -------------- 3
*/
SimpleFirstAnalyse::SimpleFirstAnalyse(PtrStack* state,PtrStack* word,HWND hWnd)
{
pState = state;
pWord = word;
flag = 0;
m_hWnd = hWnd;//::GetDlgItem(hWnd,IDC_EDIT2);
RECT rt;
::GetWindowRect(::GetDlgItem(m_hWnd,IDC_STATIC_R),&rt);
int x = rt.right - rt.left;
int y = rt.bottom - rt.top;
pt[0].x = x/4 + x/8; pt[0].y = 0;
pt[1].x = 0; pt[1].y = y/3;
pt[2].x = x/4 ; pt[2].y = y/3;
pt[3].x = x/2; pt[3].y = y/3;
pt[4].x = 3*x/4; pt[4].y = y/3;
pt[5].x = 0; pt[5].y = 2*y/3;
pt[6].x = x/7; pt[6].y =2*y/3 ;
pt[7].x = 2*x/7; pt[7].y = 2*y/3;
pt[8].x = 3*x/7; pt[8].y = 2*y/3;
pt[9].x = 4*x/7; pt[9].y = 2*y/3;
pt[10].x = 5*x/7; pt[10].y = 2*y/3;
pt[11].x = 6*x/7; pt[11].y = 2*y/3;
pt[12].x = x; pt[12].y = 2*y/3;
pt[13].x = 5*x/7; pt[13].y = y;
pt[14].x = x; pt[14].y = y;
//简单优先关系表:
// 0 1 2 3 4 5 6 7 8 9 10 11
int table[12][12] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, //0 Sroot
0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, //1 while
0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, //2 E
0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, //3 do
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, //4 s
0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 3, 3, //5 id
0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, //6 opL
0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 3, 3, //7 const
0, 0, 0, 0, 0, 1, 0, 1, 0, 2, 0, 0, //8 =
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, //9 idC
0, 0, 0, 0, 0, 1, 0, 1, 0, 2, 0, 0, //10 opA
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, //11 #
};
//memcpy((void*)m_table,(void*)table,12*12* sizeof(int));
for(int i =0; i < 12; i++)
{
for(int j = 0; j < 12; j++)
{
m_table[i][j] = table[i][j];
}
}
}
SimpleFirstAnalyse::~SimpleFirstAnalyse()
{
}
BOOL SimpleFirstAnalyse::Analyse()
{
::SetWindowText(GetDlgItem(m_hWnd,IDC_EDIT2),"");
HDC hDC = ::GetDC(::GetDlgItem(m_hWnd,IDC_STATIC_R));
HPEN hPen = ::CreatePen(PS_SOLID,0,RGB(255,0,0));
::SelectObject(hDC,hPen);
//HDC hDC = ::GetDC(m_hWnd);
pState->ClearAll();
TableStruct ts =
{
11,'#'
};
pState->Push((int)&ts);
TableStruct * p = (TableStruct*)(pWord->GetTop());
///////////////////////////
int a = p->KindID;
int len = pWord->GetLength();
////////////////////
while(true)
{
int wordID = p->KindID;
int stateID = ((TableStruct*)(pState->GetTop()))->KindID;
///////////////////////////
int ceshi = m_table[stateID][wordID];
////////////////
if(m_table[stateID][wordID] == 0)//错误
{
MyMessageBox("Syntax Error!");
return FALSE;
}
else if(m_table[stateID][wordID] == 1 || m_table[stateID][wordID] == 2)//移进
{
int p = pWord->Pop();
pState->Push(p);
}
else if(m_table[stateID][wordID] == 3)//归约
{
//临时栈
PtrStack tmpStack;
tmpStack.InitStack();
tmpStack.ClearAll();
//向前查找到句柄头
char JuBing[50] = {0};
//char strTmp[50] ={ 0 };
char buf[50] = {0};
tmpStack.Push(pState->GetTop());
int kind1 = ((TableStruct*)(pState->Pop()))->KindID;
itoa(kind1,buf,10);
strcat(buf,JuBing);
strcpy(JuBing,buf);
TableStruct* ts2 = ((TableStruct*)(pState->GetTop()));
int kind2 = ts2->KindID;
while(m_table[kind2][kind1] != 1)
{
tmpStack.Push(pState->GetTop());
kind1 = ((TableStruct*)(pState->Pop()))->KindID;
itoa(kind1,buf,10);
strcat(buf,JuBing);
strcpy(JuBing,buf);
ts2 = ((TableStruct*)(pState->GetTop()));
kind2 = ts2->KindID;
}
////////////////对句柄归约
//pState->Push((int)ts2);
/*
int strLen = strlen(JuBing);
for(int i = 0; i < strLen; i++)
{
strTmp[i] = JuBing[strLen - i - 1];
}
strcpy(JuBing,strTmp);
*/
int a= GuiYue(JuBing);
if( a == -1)
{
MyMessageBox("Syntax Error!");
return FALSE;
}
if(a == 0)
{
goto Exit;
}
TableStruct* tsTmp = new TableStruct;
tsTmp->KindID = a;
if(a == 9)
{
int ki = ((TableStruct*)(tmpStack.GetTop()))->KindID;
if(ki == 5)//id
{
strcpy(tsTmp->name,((TableStruct*)(tmpStack.Pop()))->name);
}
else //7
{
int a = ((TableStruct*)(tmpStack.Pop()))->value;
itoa(a,tsTmp->name,10);
}
// Draw Line to make tree
if(flag == 0)
{
::MoveToEx(hDC,pt[13].x,pt[13].y,0);
::LineTo(hDC,pt[10].x,pt[10].y);
::TextOut(hDC,pt[10].x+10,pt[10].y,"idC",3);
flag ++;
}
else
{
::MoveToEx(hDC,pt[14].x,pt[14].y,0);
::LineTo(hDC,pt[12].x,pt[12].y);
::TextOut(hDC,pt[12].x+10,pt[12].y,"idC",3);
}
}
if(a == 2)//E
{
strcpy(tsTmp->pE.id,((TableStruct*)(tmpStack.Pop()))->name);
tsTmp->pE.op = ((TableStruct*)(tmpStack.Pop()))->op;
tsTmp->pE.num = ((TableStruct*)(tmpStack.Pop()))->value;
CString str;
str.Format("(1) if E(%s %c %d).type = true goto 3\r\n(2) goto 5\r\n",\
tsTmp->pE.id,tsTmp->pE.op,tsTmp->pE.num);
AddToWindow(str);
//draw line
::MoveToEx(hDC,pt[5].x,pt[5].y,0);
::LineTo(hDC,pt[2].x,pt[2].y);
::MoveToEx(hDC,pt[6].x,pt[6].y,0);
::LineTo(hDC,pt[2].x,pt[2].y);
::MoveToEx(hDC,pt[7].x,pt[7].y,0);
::LineTo(hDC,pt[2].x,pt[2].y);
::TextOut(hDC,pt[2].x+10,pt[2].y,"E",1);
}
if (a == 4)//s
{
strcpy(tsTmp->ps.id,((TableStruct*)(tmpStack.Pop()))->name);
tmpStack.Pop(); // =
int ki = ((TableStruct*)(tmpStack.GetTop()))->KindID;
strcpy(tsTmp->ps.idA,((TableStruct*)(tmpStack.Pop()))->name);
tsTmp->ps.opA = ((TableStruct*)(tmpStack.Pop()))->op;//op
ki = ((TableStruct*)(tmpStack.GetTop()))->KindID;
strcpy(tsTmp->ps.idB,((TableStruct*)(tmpStack.Pop()))->name);
CString str;
str.Format("(3) %s = %s %c %s\r\n(4) goto 1\r\n",tsTmp->ps.id,tsTmp->ps.idA,\
tsTmp->ps.opA,tsTmp->ps.idB);
AddToWindow(str);
//draw line
::MoveToEx(hDC,pt[8].x,pt[8].y,0);
::LineTo(hDC,pt[4].x,pt[4].y);
::MoveToEx(hDC,pt[9].x,pt[9].y,0);
::LineTo(hDC,pt[4].x,pt[4].y);
::MoveToEx(hDC,pt[10].x,pt[10].y,0);
::LineTo(hDC,pt[4].x,pt[4].y);
::MoveToEx(hDC,pt[11].x,pt[11].y,0);
::LineTo(hDC,pt[4].x,pt[4].y);
::MoveToEx(hDC,pt[12].x,pt[12].y,0);
::LineTo(hDC,pt[4].x,pt[4].y);
::TextOut(hDC,pt[4].x+10,pt[4].y,"s",1);
}
pState->Push((int)tsTmp);
}
else
{
AfxMessageBox("程序发生了不可预知的错误!");
return FALSE;
}
p = (TableStruct*)(pWord->GetTop());
}
Exit:
if(((TableStruct*)(pWord->GetTop()))->KindID == 11)//字符�