⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compilerdlg.cpp

📁 一个词法分析编译器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -