?? lexdemoview.cpp
字號:
// lexDemoView.cpp : implementation of the CLexDemoView class
//
#include "stdafx.h"
#include "lexDemo.h"
#include "lexDemoDoc.h"
#include "lexDemoView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CLexDemoView
IMPLEMENT_DYNCREATE(CLexDemoView, CView)
BEGIN_MESSAGE_MAP(CLexDemoView, CView)
//{{AFX_MSG_MAP(CLexDemoView)
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
ON_COMMAND(IDM_LL_ONE, OnLlOne)
ON_COMMAND(IDM_REVERSE_POLAND, OnReversePoland)
ON_COMMAND(IDM_LR_ZERO, OnLrZero)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CLexDemoView construction/destruction
CLexDemoView::CLexDemoView()
{
// TODO: add construction code here
m_analTable = NULL;
}
CLexDemoView::~CLexDemoView()
{
if (m_analTable != NULL)
delete []m_analTable;
}
BOOL CLexDemoView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CLexDemoView drawing
void CLexDemoView::OnDraw(CDC* pDC)
{
CLexDemoDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
/////////////////////////////////////////////////////////////////////////////
// CLexDemoView printing
BOOL CLexDemoView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CLexDemoView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CLexDemoView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CLexDemoView diagnostics
#ifdef _DEBUG
void CLexDemoView::AssertValid() const
{
CView::AssertValid();
}
void CLexDemoView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CLexDemoDoc* CLexDemoView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CLexDemoDoc)));
return (CLexDemoDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CLexDemoView message handlers
//功能描述: 打開指定文件,對文件內容進行分析
void CLexDemoView::OnFileOpen()
{
}
/////////////////////////////////////////////////////////////////////////////
// CLexDemoView::LexAnal
//功能描述: 打開指定文件,對文件內容進行分析
Status CLexDemoView::LexAnal()
{
char chInput;
char * szTop = NULL;
char * szOut = NULL;
CString strTop;
CString strOut;
CString strVal;
LElem nextElem = NULL;
int i = 0;
Status sRet = OK;
InitAnalTable();
InitAnalStack();
do
{
sRet = GetNextInput(chInput);
if (END_OF_INPUT == sRet) //輸入字符已經讀取完畢, 但分析棧仍不為空,出錯
{
LexUtil::ErrMsg("error: end of Input while analStack is not empty");
break;
}
sRet = m_analStack.Top(strTop);
if (IsTerminals(strTop)) //判斷分析棧棧頂元素是否為終結符
{
if (strTop[0] == chInput) //如果棧頂的終結符與輸入的字符相同的話,則出棧否則報錯
{
m_analStack.Pop(strOut);
}
else
{
LexUtil::ErrMsg("Parse error");
break;
}
}
else //分析棧棧頂元素不是終結符的話
{
nextElem = FindNextState((LPTSTR)(LPCTSTR)strTop, chInput);
if (nextElem != NULL)
{
strVal.Format("%d:%s---", i++, nextElem->replace);
if (P == nextElem->nextStep)
{
strVal.Insert(strVal.GetLength(), "P");
}
else if (N == nextElem->nextStep)
{
strVal.Insert(strVal.GetLength(), "N");
}
else if (ACC == nextElem->nextStep)
{
strVal.Insert(strVal.GetLength(), "ACC");
}
m_analStack.Pop(strOut);
SplitPush(nextElem->replace);
if (P ==nextElem->nextStep) //如果下一動作是P的話
{
UnGetInput();
}
}
else
{
CString strMsg;
strMsg.Format("%s: %c", strTop, chInput);
LexUtil::ErrMsg(strMsg);
LexUtil::ErrMsg("在分析表中沒有匹配動作序列");
break;
}
}
m_lstToken.AddString(strVal);
AddToListForLL(m_analStack);
} while (!m_analStack.IsEmpty());
return OK;
}
/////////////////////////////////////////////////////////////////////////////
// CLexDemoView::InitAnalTable
//功能描述: 構造LL(1)語法分析表
//分析表的來源:教材159頁的練習題6.6中的文法所對應的分析表
//這個表與教材134頁的表6-6中的分析表比很相象,只不過增加了
// 對 *, /的支持
Status CLexDemoView::InitAnalTable()
{
if (NULL != m_analTable)
return OK;
m_analTable = new Elem[TABLE_LENGTH];
if (NULL == m_analTable)
return FAIL;
strcpy(m_analTable[0].notTerminals, "E");
m_analTable[0].terminal = '(';
strcpy(m_analTable[0].replace, "E1T");
m_analTable[0].nextStep = P;
strcpy(m_analTable[1].notTerminals, "E");
m_analTable[1].terminal = 'i';
strcpy(m_analTable[1].replace, "E1T");
m_analTable[1].nextStep = P;
strcpy(m_analTable[2].notTerminals, "E1");
m_analTable[2].terminal = '+';
strcpy(m_analTable[2].replace, "E1T");
m_analTable[2].nextStep = N;
strcpy(m_analTable[3].notTerminals, "E1");
m_analTable[3].terminal = '-';
strcpy(m_analTable[3].replace, "E1T");
m_analTable[3].nextStep = N;
strcpy(m_analTable[4].notTerminals, "E1");
m_analTable[4].terminal = ')';
strcpy(m_analTable[4].replace, "e"); //e means empty
m_analTable[4].nextStep = P;
strcpy(m_analTable[5].notTerminals, "E1");
m_analTable[5].terminal = '#';
strcpy(m_analTable[5].replace, "e"); //e means empty
m_analTable[5].nextStep = P;
strcpy(m_analTable[6].notTerminals, "T");
m_analTable[6].terminal = '(';
strcpy(m_analTable[6].replace, "T1F");
m_analTable[6].nextStep = P;
strcpy(m_analTable[7].notTerminals, "T");
m_analTable[7].terminal = 'i';
strcpy(m_analTable[7].replace, "T1F");
m_analTable[7].nextStep = P;
strcpy(m_analTable[8].notTerminals, "T1");
m_analTable[8].terminal = '+';
strcpy(m_analTable[8].replace, "e");
m_analTable[8].nextStep = P;
strcpy(m_analTable[9].notTerminals, "T1");
m_analTable[9].terminal = '-';
strcpy(m_analTable[9].replace, "e");
m_analTable[9].nextStep = P;
strcpy(m_analTable[10].notTerminals, "T1");
m_analTable[10].terminal = '*';
strcpy(m_analTable[10].replace, "T1F");
m_analTable[10].nextStep = N;
strcpy(m_analTable[11].notTerminals, "T1");
m_analTable[11].terminal = '/';
strcpy(m_analTable[11].replace, "T1F");
m_analTable[11].nextStep = N;
strcpy(m_analTable[12].notTerminals, "T1");
m_analTable[12].terminal = ')';
strcpy(m_analTable[12].replace, "e");
m_analTable[12].nextStep = P;
strcpy(m_analTable[13].notTerminals, "T1");
m_analTable[13].terminal = '#';
strcpy(m_analTable[13].replace, "e");
m_analTable[13].nextStep = P;
strcpy(m_analTable[14].notTerminals, "F");
m_analTable[14].terminal = '(';
strcpy(m_analTable[14].replace, "F1P");
m_analTable[14].nextStep = P;
strcpy(m_analTable[15].notTerminals, "F");
m_analTable[15].terminal = 'i';
strcpy(m_analTable[15].replace, "F1P");
m_analTable[15].nextStep = P;
strcpy(m_analTable[16].notTerminals, "F1");
m_analTable[16].terminal = '+';
strcpy(m_analTable[16].replace, "e");
m_analTable[16].nextStep = P;
strcpy(m_analTable[17].notTerminals, "F1");
m_analTable[17].terminal = '-';
strcpy(m_analTable[17].replace, "e");
m_analTable[17].nextStep = P;
strcpy(m_analTable[18].notTerminals, "F1");
m_analTable[18].terminal = '*';
strcpy(m_analTable[18].replace, "e");
m_analTable[18].nextStep = P;
strcpy(m_analTable[19].notTerminals, "F1");
m_analTable[19].terminal = '/';
strcpy(m_analTable[19].replace, "e");
m_analTable[19].nextStep = P;
strcpy(m_analTable[20].notTerminals, "F1");
m_analTable[20].terminal = ')';
strcpy(m_analTable[20].replace, "e");
m_analTable[20].nextStep = P;
strcpy(m_analTable[21].notTerminals, "F1");
m_analTable[21].terminal = '#';
strcpy(m_analTable[21].replace, "e");
m_analTable[21].nextStep = P;
strcpy(m_analTable[22].notTerminals, "P");
m_analTable[22].terminal = '(';
strcpy(m_analTable[22].replace, ")E");
m_analTable[22].nextStep = N;
strcpy(m_analTable[23].notTerminals, "P");
m_analTable[23].terminal = 'i';
strcpy(m_analTable[23].replace, "e");
m_analTable[23].nextStep = N;
strcpy(m_analTable[24].notTerminals, ")");
m_analTable[24].terminal = ')';
strcpy(m_analTable[24].replace, "e");
m_analTable[24].nextStep = N;
strcpy(m_analTable[25].notTerminals, "+");
m_analTable[25].terminal = '+';
strcpy(m_analTable[25].replace, "e");
m_analTable[25].nextStep = ACC;
strcpy(m_analTable[25].notTerminals, "#");
m_analTable[25].terminal = '#';
strcpy(m_analTable[25].replace, "e");
m_analTable[25].nextStep = ACC;
return OK;
}
/////////////////////////////////////////////////////////////////////////////
// CLexDemoView::InitAnalStack
//功能描述: 構造語法分析棧
Status CLexDemoView::InitAnalStack()
{
//m_analStack.InitStack(40);
m_analStack.Push("#");
m_analStack.Push("E");
return OK;
}
/////////////////////////////////////////////////////////////////////////////
// CLexDemoView::GetNextInput()
//功能描述: 獲得下一個輸入流中的字符
Status CLexDemoView::GetNextInput(char& valOut)
{
if (m_szInput[m_lInputPos] != '\0')
{
valOut = m_szInput[m_lInputPos++];
return OK;
}
else
{
return END_OF_INPUT;
}
}
/////////////////////////////////////////////////////////////////////////////
// CLexDemoView::UnGetInput
//功能描述: 回退輸入流指針到前一個字符
Status CLexDemoView::UnGetInput()
{
if (m_lInputPos <= 0)
{
return BEGINNING_OF_INPUT;
}
else
{
m_lInputPos--;
return OK;
}
}
/////////////////////////////////////////////////////////////////////////////
// CLexDemoView::IsTerminals
//功能描述:判斷參數字符串是否為終結符元素
bool CLexDemoView::IsTerminals(CString strVal)
{
if (!strcmp(strVal, "i"))
{
return true;
}
if (!strcmp(strVal, "("))
{
return true;
}
if (!strcmp(strVal, "+"))
{
return true;
}
if (!strcmp(strVal, "-"))
{
return true;
}
if (!strcmp(strVal, "*"))
{
return true;
}
if (!strcmp(strVal, "/"))
{
return true;
}
if (!strcmp(strVal, ")"))
{
return true;
}
return false;
}
/////////////////////////////////////////////////////////////////////////////
// CLexDemoView::FindNextState
//功能描述:根據當前棧頂元素和輸入元素查分析表取得下一個狀態動作
LElem CLexDemoView::FindNextState(char * szTop, char chInput)
{
for (int i = 0; i < TABLE_LENGTH; i++)
{
if(!strcmp(m_analTable[i].notTerminals, szTop) && m_analTable[i].terminal == chInput) //換到匹配的狀態動作的話
{
return &m_analTable[i];
}
}
return NULL;
}
/////////////////////////////////////////////////////////////////////////////
// CLexDemoView::Splitpush
//功能描述:
Status CLexDemoView::SplitPush(char * szVal)
{
char szIn[3];
if (strlen(szVal) > 2)
{
szIn[0] = szVal[0];
szIn[1] = szVal[1];
szIn[2] = '\0';
m_analStack.Push(szIn);
szIn[0] = szVal[2];
szIn[1] = '\0';
m_analStack.Push(szIn);
}
else
{
if (strcmp(szVal, "e"))
{
strcpy(szIn, szVal);
m_analStack.Push(szIn);
}
}
return OK;
}
//功能描述:模擬LL(1)語法分析方法
//分析的字符串:i*i-i/i
void CLexDemoView::OnLlOne()
{
InitListBox();
m_lstResult.AddString("分析棧");
m_lstToken.AddString("分析動作");
strcpy(m_szInput, "i*i-i/i#");
m_lInputPos = 0;
LexAnal();
}
//功能描述:模擬逆波蘭轉換過程
void CLexDemoView::OnReversePoland()
{
CString strSrc, strDst, strAsmOut;
Status sRet = OK;
strSrc = "(a+b)*c-d/2";
//進行逆波蘭轉換
sRet = PolandRConvert(strSrc, strDst);
//根據逆波蘭式生成asm Code
MakeAsmCode(strDst, strAsmOut);
AfxMessageBox(strAsmOut);
}
//功能描述:逆波蘭轉換
//@arg: CString strSrc
//@arg: CString& strDst
//@return:Status
Status CLexDemoView::PolandRConvert(CString strSrc, CString& strDst)
{
Status sRet = OK;
int i = 0;
int nPRI = 0; //運算符優先級
int length = strSrc.GetLength();
char chInput;
char chTop;
char chOut;
Stack<char> stack;
while(i < length)
{
chInput = strSrc.GetAt(i);
//如果是操作數的話.直接輸出
if (IsOperand(chInput) && chInput != '(' && chInput != ')' )
{
strDst.Insert(strDst.GetLength(), chInput);
}
else
{
//當前字符是運算符的話
if (IsOperator(chInput))
{
//如果運算符棧為空的話,直接將運算符入棧
if (stack.IsEmpty())
{
stack.Push(chInput);
}
//如果運算符棧不為空的話,就需要比較棧頂運算符與當前輸入運算符的優先級
else
{
nPRI = GetPRI(chInput);
do
{
sRet = stack.Top(chTop);
//如果當前運算符優先級>棧頂運算符優先級的話.入棧,退出循環
if (nPRI > GetPRI(chTop) || STACK_EMPTY == sRet )
{
stack.Push(chInput);
break;
}
//如果當前運算符優先級<=棧頂運算符優先級的話.棧頂運算符出棧,進輸出流,繼續循環
else
{
stack.Pop(chOut);
strDst.Insert(strDst.GetLength(), chOut);
}
} while (1);
}
} //end of if (IsOperator(chInput))
//當前字符是左括號的話
else if ('(' == chInput)
{
stack.Push(chInput);
}
//當前字符是右括號的話
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -