📄 main.cpp
字号:
#include <windows.h>
#include <commctrl.h>
#include "resource.h"
#include "commendef.h"
void GetProgramFile(HWND);
BOOL CALLBACK DlgWndProc(HWND,UINT,WPARAM,LPARAM);
void WordAnalyse(HWND,HWND);
void InitOutputList(HWND hList);
bool RecogniseString(char** pStr,RECOG_RESULT* pResult);
bool RecogniseOtherChar(char** pStr,RECOG_RESULT* pResult);
bool RecogniseOperator(char** pStr,RECOG_RESULT* pResult);
bool RecogniseNumber(char** pStr,RECOG_RESULT *pResult);
bool RecogniseIdentifier(char** pStr,RECOG_RESULT *pResult);
bool IsValidOperatorChar(char ch);
extern STACK_NODE* g_pStackTop;
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR lpCmdLine,int nShowCmd)
{
DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG1),NULL,DlgWndProc);
return 0;
}
BOOL CALLBACK DlgWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
HICON hIcon;
switch(msg)
{
case WM_INITDIALOG:
hIcon = LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_ICON1));
SendMessage(hwnd,WM_SETICON,ICON_SMALL,(LPARAM)hIcon);
SendMessage(GetDlgItem(hwnd,IDC_EDIT1),WM_SETFONT,
(WPARAM)GetStockObject(SYSTEM_FIXED_FONT),FALSE);
return FALSE;
case WM_COMMAND:
if (LOWORD(wParam) == IDC_OPEN)// 打开程序文件
GetProgramFile(GetDlgItem(hwnd,IDC_EDIT1));
else if (LOWORD(wParam) == IDC_ANALYSE) // 词法分析
WordAnalyse(GetDlgItem(hwnd,IDC_EDIT1),GetDlgItem(hwnd,IDC_LIST1));
return TRUE;
case WM_CLOSE:
EndDialog(hwnd,0);
return TRUE;
}
return FALSE;
}
// 取得源程序文件名(显示打开文件对话框)
BOOL GetProgramFileName(HWND hwnd,LPTSTR pstrFileName,LPTSTR pstrTitleName)
{
OPENFILENAME ofn ;
TCHAR szFilter[] = TEXT ("C程序(*.c)\0*.c\0C++程序(*.cpp)\0*.cpp\0");
ofn.lStructSize = sizeof (OPENFILENAME) ;
ofn.hInstance = NULL ;
ofn.lpstrFilter = szFilter ;
ofn.lpstrCustomFilter = NULL ;
ofn.nMaxCustFilter = 0 ;
ofn.nFilterIndex = 0 ;
ofn.nMaxFile = MAX_PATH ;
ofn.nMaxFileTitle = MAX_PATH ;
ofn.lpstrInitialDir = NULL ;
ofn.lpstrTitle = TEXT("打开程序文件");
ofn.nFileOffset = 0 ;
ofn.nFileExtension = 0 ;
ofn.lpstrDefExt = TEXT (".c") ;
ofn.lCustData = 0L ;
ofn.lpfnHook = NULL ;
ofn.lpTemplateName = NULL ;
ofn.hwndOwner = hwnd ;
ofn.lpstrFile = pstrFileName ;
ofn.lpstrFileTitle = pstrTitleName ;
ofn.Flags = 0 ;
return GetOpenFileName(&ofn);
}
// 读取程序文件到编辑控件中
void GetProgramFile(HWND hEdit)
{
TCHAR szFileName[MAX_PATH],szTitleName[MAX_PATH];
HANDLE hFile;
TCHAR* pText;
DWORD dwSize,dwSizeHigh;
ZeroMemory(szFileName,sizeof(TCHAR) * MAX_PATH);
ZeroMemory(szTitleName,sizeof(TCHAR) * MAX_PATH);
if (GetProgramFileName(hEdit,szFileName,szTitleName))
{
hFile = CreateFile(szFileName,GENERIC_READ,FILE_SHARE_READ,
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
dwSize = GetFileSize(hFile,&dwSizeHigh);
pText = (TCHAR *)GlobalAlloc(GPTR,dwSize + 2);
ZeroMemory(pText,dwSize + 2);
if (pText == NULL)
{
MessageBox(hEdit,TEXT("内存不足,无法完成操作!"),TEXT("错误"),MB_OK | MB_ICONWARNING);
CloseHandle(hFile);
}
else
{
if (ReadFile(hFile,pText,dwSize,&dwSizeHigh,NULL) && dwSizeHigh == dwSize)
{
SetWindowText(hEdit,pText);
GlobalFree(pText);
CloseHandle(hFile);
}
else
{
GlobalFree(pText);
MessageBox(hEdit,TEXT("读文件过程中发生错误!"),TEXT("错误"),MB_OK | MB_ICONWARNING);
CloseHandle(hFile);
}
}
}
else
MessageBox(hEdit,TEXT("打开文件失败!"),TEXT("错误"),MB_OK | MB_ICONWARNING);
}
}
// 初始化输出列表
void InitOutputList(HWND hList)
{
LVCOLUMN colinfo;
int count;
HWND hHead;
// 清除所有内容和表头
ListView_DeleteAllItems(hList);
hHead = ListView_GetHeader(hList);
count = Header_GetItemCount(hHead);
if (count == 0)
{
colinfo.mask = LVCF_TEXT | LVCF_WIDTH;
colinfo.cx = 0;
colinfo.pszText = TEXT("");
ListView_InsertColumn(hList,0,&colinfo);
}
else
{
for(int i = 0; i < count - 1; i++)
ListView_DeleteColumn(hList,1);
}
// 设置表头
colinfo.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
colinfo.fmt = LVCFMT_CENTER;
colinfo.cx = 75;
colinfo.pszText = TEXT("单词类型");
ListView_InsertColumn(hList,1,&colinfo);
colinfo.cx = 130;
colinfo.pszText = TEXT("值");
ListView_InsertColumn(hList,2,&colinfo);
colinfo.cx = 75;
colinfo.pszText = TEXT("说明");
ListView_InsertColumn(hList,3,&colinfo);
// Windows XP 才支持
//ListView_SetSelectedColumn(hList,1);
}
// 添加一个分析结果到输出列表中
void AddWordToList(HWND hList,RECOG_RESULT Result)
{
RECOG_RESULT* pWord;
TCHAR szType[MAX_PATH];
TCHAR szValue[MAX_PATH];
TCHAR szNote[MAX_PATH];
LVITEM item;
int count;
count = ListView_GetItemCount(hList);
pWord = &Result;
ZeroMemory(szType,sizeof(TCHAR) * MAX_PATH);
ZeroMemory(szValue,sizeof(TCHAR) * MAX_PATH);
ZeroMemory(szNote,sizeof(TCHAR) * MAX_PATH);
switch(pWord->WordType)
{
case WORD_ID:
wsprintf(szType,TEXT("标识符"));
wsprintf(szValue,TEXT("%s"),pWord->Value.Identifier);
wsprintf(szNote,(pWord->ChildType == CHILD_KEYWORD) ? TEXT("关键字") : TEXT("用户标识符"));
break;
case WORD_NUM:
wsprintf(szType,TEXT("常数"));
if (pWord->ChildType == CHILD_INT)
wsprintf(szValue,TEXT("%d"),pWord->Value.IntValue);
else
wsprintf(szValue,TEXT("%e"),pWord->Value.RealValue);
wsprintf(szNote,(pWord->ChildType == CHILD_INT) ? TEXT("整数") : TEXT("浮点数"));
break;
case WORD_STR:
wsprintf(szType,TEXT("字符常量"));
wsprintf(szValue,TEXT("%s"),pWord->Value.String);
if (pWord->ChildType == CHILD_ESC)
wsprintf(szNote,TEXT("转义字符"));
else if (pWord->ChildType == CHILD_CHAR)
wsprintf(szNote,TEXT("单字符"));
else
wsprintf(szNote,TEXT("字符串"));
break;
case WORD_OP:
wsprintf(szType,TEXT("运算符"));
wsprintf(szValue,TEXT("%s"),pWord->Value.Operator);
break;
case WORD_OTHER:
wsprintf(szType,TEXT("其它符号"));
wsprintf(szValue,TEXT("%s"),pWord->Value.OtherSymbol);
break;
}
// 增加列表项
item.mask = LVIF_TEXT;
item.iItem = count;
item.iSubItem = 0;
item.pszText = TEXT("");
ListView_InsertItem(hList,&item);
item.iSubItem = 1;
item.pszText = szType;
ListView_SetItem(hList,&item);
item.iSubItem = 2;
item.pszText = szValue;
ListView_SetItem(hList,&item);
item.iSubItem = 3;
item.pszText = szNote;
ListView_SetItem(hList,&item);
}
// 对编辑控件 hEdit 中的程序进行词法分析,分析结果放到 hList 列表控件中
void WordAnalyse(HWND hEdit,HWND hList)
{
int Len;
bool AllRight;
char *pInput,*pText,ch;
RECOG_RESULT RegResult;
Len = GetWindowTextLengthA(hEdit);
pText = (char *)GlobalAlloc(GPTR,sizeof(char) * (Len + 1));
if (pText == NULL)
{
MessageBox(hList,TEXT("内存不足,无法完成操作!"),TEXT("错误"),MB_OK | MB_ICONWARNING);
return;
}
ZeroMemory(pText,sizeof(char) * (Len + 1));
GetWindowTextA(hEdit,pText,Len + 1);
InitOutputList(hList);
pInput = pText;
AllRight = true;
while(*pInput && AllRight)
{
ch = *pInput; // 回车 换行 Tab
while (*pInput && (ch == ' ' || ch == RETURN || ch == NEWLINE || ch == TAB))
ch = *(++pInput);
if (*pInput == NULL) continue;
if (ch == '_' || IsAlpha(ch))
RecogniseIdentifier(&pInput,&RegResult);
else if (IsDigit(ch))
RecogniseNumber(&pInput,&RegResult);
else if (IsValidOperatorChar(ch))
RecogniseOperator(&pInput,&RegResult);
else if (ch == '\'' || ch == '\"') // 单双引号
RecogniseString(&pInput,&RegResult);
else
RecogniseOtherChar(&pInput,&RegResult);
if (RegResult.Right)
{
if (RegResult.WordType != WORD_REMARK)
AddWordToList(hList,RegResult);
}
else AllRight = false;
}
GlobalFree(pText);
if (AllRight)
{
if (g_pStackTop == NULL)
MessageBox(hList,TEXT("程序通过词法分析!"),
TEXT("词法分析"),MB_OK | MB_ICONINFORMATION);
else
MessageBox(hList,TEXT("括号不匹配!"),TEXT("词法分析"),MB_OK | MB_ICONWARNING);
}
else
MessageBox(hList,TEXT("程序存在词法错误!"),TEXT("词法分析"),MB_OK | MB_ICONWARNING);
// 释放堆栈内存
STACK_NODE* pNode;
while(g_pStackTop != NULL)
{
pNode = g_pStackTop->next;
delete g_pStackTop;
g_pStackTop = pNode;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -