📄 compilerdlg.cpp
字号:
// CompilerDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Compiler.h"
#include "CompilerDlg.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
typedef int token;
#define NONE -1
#define STRMAX 1000
#define SYMMAX 100
#define NONE -1
#define KEYWORD 0
#define WHILE 1
#define DO 2
#define BEGIN 3
#define END 4
#define IF 5
#define THEN 6
#define ELSE 7
#define AND 8
#define OR 9
#define NOT 10
#define SEMICOLON 11 // ;
#define EVALUATE 12 // :=
#define OPERATOR 1
#define PLUS 13 // +
#define MUL 14 // *
#define LEFTBRACKET 15 // (
#define RIGHTBRACKET 16 // )
#define RELOP 2
#define LE 17 // <=
#define NE 18 // <>
#define LT 19 // <
#define EQ 20 // =
#define GE 21 // >=
#define GT 22 // >
#define ID 3
#define INT 4
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define $ 0
#define S 100
#define L 101
#define M 102
#define A 103
#define B 104
#define C 105
#define D 106
#define E 107
#define F 108
#define id 17
#define ROP 18
#define PROLEN 22
typedef struct SymTable{
char *lexptr;
int token;
int attribute;
}SYMTABLE, *LPSYMTABLE;
SYMTABLE symtable[SYMMAX];
SYMTABLE keywords[] = {
"while", WHILE, KEYWORD,
"do", DO, KEYWORD,
"begin", BEGIN, KEYWORD,
"end", END, KEYWORD,
"if", IF, KEYWORD,
"then", THEN, KEYWORD,
"else", ELSE, KEYWORD,
"and", AND, KEYWORD,
"or", OR, KEYWORD,
"not", NOT, KEYWORD,
";", SEMICOLON, KEYWORD,
":=", EVALUATE, KEYWORD,
0, 0, KEYWORD
};
typedef struct TupleType{
int line;
int kind;
int value;
}TUPLETYPE, *LPTUPLETYPE;
TUPLETYPE tuple[1000];
typedef struct{
int *base;
int *top;
int stacksize;
}STACK, LPSTACK;
bool InputFile = false;
char lexemes[STRMAX];
int lastchar = -1;
int lastentry = 0;
int lasttuple = -1;
int KeyNum = 12;
char buffer[1000];
char *lexeme_beginning;
char *forward;
FILE *fp; //the source program file
int state = 0, start = 0;
int lexical_value;
int lineno = 1;
char c; //store character
int nIndexTuple = 0; //当前分析到的tuple的位置
STACK Stack;
int szProduction[10];
bool aaa = false;
char buffer1[1000];
char *lpProduction[PROLEN]= {
"",
"S->if B then S else S",
"S->while B do S",
"S->begin L end",
"S->A",
"L->S M",
"M->; L",
"M->ε",
"A->i := E",
"B->not B C",
"B->( B ) C",
"B->i D",
"C->and B C",
"C->or B C",
"C->ε",
"D->rop i C",
"D->C",
"E->( E ) F",
"E->i F",
"F->+ E F",
"F->* E F",
"F->ε"
};
char *szToken[] = {
"while","do", "begin", "end", "if",
"then", "else", "and", "or", "not",
";", ":=", "+", "*", "(",
")", "i", "rop", "S", "L",
"M", "A", "B", "C", "D",
"E", "F", "rop", "$"
};
int szpredictiveTable[9][20] = {
//predictive table for top-down parsing
{0, 2, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0},
{0, 5, 0, 5, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0},
{0, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0,10, 0,11, 0, 0},
{0, 0,14, 0,14, 0,14, 0,12,13, 0, 0, 0, 0, 0, 0,14, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0,16,16, 0, 0, 0, 0, 0, 0, 0, 0,15, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,17, 0,18, 0, 0},
{0, 0, 0, 0,21, 0, 0,21, 0, 0, 0,21, 0,19,20, 0,21, 0, 0,21}
};
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCompilerDlg dialog
CCompilerDlg::CCompilerDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCompilerDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CCompilerDlg)
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCompilerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCompilerDlg)
DDX_Control(pDX, IDC_LIST_SOURCEFILE, m_SourceFile);
DDX_Control(pDX, IDC_LIST_LEXICAL, m_ListLexical);
DDX_Control(pDX, IDC_LIST_SYNTAX, m_ListSyntax);
DDX_Control(pDX, IDC_STATIC_SYMTABLE, m_symtable);
DDX_Control(pDX, IDC_EDIT_DIRECTORY, m_PathName);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CCompilerDlg, CDialog)
//{{AFX_MSG_MAP(CCompilerDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_CHOOSE_FILE, OnChooseFile)
ON_BN_CLICKED(IDC_BUTTON_COMPILE, OnButtonCompile)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCompilerDlg message handlers
BOOL CCompilerDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
m_symtable.SetWindowText ("KEYWORD: 0");
//m_symTable.SetWindowText ("KEYWORD: 0\n");
//m_symTable.SetWindowText ("KEYWORD: 0 WHILE:1 DO:2 BEGIN:3 END:4 IF:5 THEN:6 ELSE:7");
// 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
}
void CCompilerDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// 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 CCompilerDlg::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 CCompilerDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CCompilerDlg::OnChooseFile()
{
// TODO: Add your control notification handler code here
CFileDialog FDialog (TRUE, NULL, NULL, 0, "所有文件|*.*", NULL);
if (FDialog.DoModal() == IDOK){
int nCount = m_SourceFile.GetCount ();
for (int k = 0; k < nCount; k++){
m_SourceFile.DeleteString (0);
}
nCount = m_ListLexical.GetCount ();
for (k = 0; k < nCount; k++){
m_ListLexical.DeleteString (0);
}
nCount = m_ListSyntax.GetCount ();
for (k = 0; k < nCount; k++){
m_ListSyntax.DeleteString (0);
}
m_strPathName = FDialog.GetPathName ();
m_strFileName = FDialog.GetFileName ();
m_PathName.SetWindowText (m_strPathName);
if ((fp = fopen (m_strFileName, "r")) == NULL){
::MessageBox (NULL, "文件打开失败!", "提示", 48);
exit (0);
}
//for (int i = 0; i < m_SourceFile.GetCount (); i++)
// m_SourceFile.DeleteItem
lexeme_beginning = buffer;
forward = buffer - 1;
lastchar = -1;
lastentry = 0;
lasttuple = -1;
state = 0;
start = 0;
lineno = 1;
nIndexTuple = 0; //当前分析到的tuple的位置
//read the source program buffer
int numread;
numread = fread (buffer, sizeof (char), 999, fp);
int i = 0, j = 0;
char szSource[100];
int line = 1;
char str[100];
while (i < numread){
if (buffer[i] == '\n' || buffer[i] == EOF){
sprintf (str, "%d", line);
strcat (str, " ");
szSource[j] = '\0';
m_SourceFile.AddString (strcat (str, szSource));
j = 0;
i++;
line++;
}
else
szSource[j++] = buffer[i++];
}
InputFile = true;
}
}
void Insert (char s[], int tok)
{
int len;
len = strlen (s);
lastentry += 1;
symtable[lastentry].token = tok;
symtable[lastentry].lexptr = &lexemes[lastchar + 1];
lastchar = lastchar + len + 1;
strcpy (symtable[lastentry].lexptr, s);
}
void Initialization ()
{
LPSYMTABLE p;
for (p = keywords; p->token; p++)
Insert (p->lexptr, p->token);
}
char NextChar ()
{
forward += 1;
return *forward;
}
int Fail ()
{
forward = lexeme_beginning;
switch (start){
case 0:
start = 9;
break;
case 9:
start = 12;
break;
case 12:
start = 15;
break;
case 15:
start = 22;
break;
case 22:
break;
}
return start;
}
void Retract ()
{
forward -= 1;
}
int Install_relop ()
{ //handle relop
int i, len;
char lexm[32];
len = forward - lexeme_beginning + 1;//the length of lexeme
if (lastentry + 1 >= SYMMAX){
//if symbol table is full then exit
::MessageBox (NULL, "符号表已满!", "提示", 48);
exit (0);
}
if (lastchar + len + 1 >= STRMAX){
//if lexemes array is full then exit
::MessageBox (NULL, "lexemes array is full!", "提示", 48);
exit (0);
}
for (i = 0; i < len; i++){
lexm[i] = *(lexeme_beginning + i);
}
lexm[i] = '\0';
lastentry += 1;
symtable[lastentry].token = RELOP;
symtable[lastentry].lexptr = &lexemes[lastchar + 1];
lastchar = lastchar + len + 1;
strcpy (symtable[lastentry].lexptr, lexm);
lexeme_beginning = forward + 1;
switch (state){
case 2: // <=
symtable[lastentry].attribute = LE;
break;
case 3: // <>
symtable[lastentry].attribute = NE;
break;
case 4: // <
symtable[lastentry].attribute = LT;
break;
case 5: // =
symtable[lastentry].attribute = EQ;
break;
case 7: // >=
symtable[lastentry].attribute = GE;
break;
case 8: // >
symtable[lastentry].attribute = GT;
break;
}
tuple[++lasttuple].line = lineno;
tuple[lasttuple].kind = symtable[lastentry].token;
tuple[lasttuple].value = symtable[lastentry].attribute;
return lastentry;
return 0;
}
int Install_id ()
{ //handle the keyword and identity
int i, len;
char lexm[32];
len = forward - lexeme_beginning + 1;//the length of lexeme
if (lastentry + 1 >= SYMMAX){
//if symbol table is full then exit
::MessageBox (NULL, "符号表已满!", "提示", 48);
exit (0);
}
if (lastchar + len + 1 >= STRMAX){
//if lexemes array is full then exit
::MessageBox (NULL, "lexemes array is full!", "提示", 48);
exit (0);
}
for (i = 0; i < len; i++){
lexm[i] = *(lexeme_beginning + i);
}
lexm[i] = '\0';
for (i = 1; i <= KeyNum; i++)//if the lexeme is keyword then return 0
if (strcmp (symtable[i].lexptr, lexm) == 0){
tuple[++lasttuple].line = lineno;
tuple[lasttuple].kind = symtable[i].attribute;
tuple[lasttuple].value = symtable[i].token;
lexeme_beginning = forward + 1;
return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -