伤城文章网 > 理学 > 编译原理 词法分析实验一

编译原理 词法分析实验一


华北水利水电学院
2010~2011 学年 班级: xxxxx 第 二 学号:

编译原理
学期 xxxxx xxxx 姓名:

实验报告
级 xxx 计算机 专业

一、

实验目的
通过设计调试词法分析程序,实现从源程序中分出各种单词的方法;加深对课堂 教学的理解,深刻理解词法分析的整个过程,提高词法分析方法的实践能力。

二、实验要求
(1)从源程序文件中读取有效字符和并将其转换成二元组机内表示形式输出。 (2)掌握词法分析的实现方法。 (3)实验要求独立完成,不允许有抄袭现象。 (4)实验完成后,要上交实验报告(包括源程序清单) 。 (附:实验报告格式)

三、实验内容
1、主程序设计考虑。 2、词法分析过程考虑。 3、功能要求: 输出源程序对应的二元组; 对错误单词能够报错,并提示出错误所在行; 常量和变量要求存在符号表中。

四、程序源代码
#include "stdafx.h" #include "词法分析.h" #include "词法分析 Dlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // CAboutDlg dialog used for App About // ClassWizard generated virtual function overrides class CAboutDlg : public CDialog { -1//{{AFX_VIRTUAL(CAboutDlg) protected: // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA public: CAboutDlg();

virtual DoDataExchange(CDataExchange* pDX); DDX/DDV support //}}AFX_VIRTUAL

void //

/////////////////////////////////////////// ////////////////////////////////// // CMyDlg dialog

CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/) // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; { //{{AFX_DATA_INIT(CMyDlg) m_source = _T(""); m_result = _T(""); //}}AFX_DATA_INIT // Note that LoadIcon does not require a CAboutDlg::CAboutDlg() CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void pDX) void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CMyDlg, CDialog) BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() //{{AFX_MSG_MAP(CMyDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_COMMAND(IDM_Fenxi, OnFenxi) ON_COMMAND(IDM_Eryuanzu, OnEryuanzu) } { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CMyDlg) DDX_Text(pDX, IDC_EDIT1, m_source); DDX_Text(pDX, IDC_EDIT2, m_result); //}}AFX_DATA_MAP CMyDlg::DoDataExchange(CDataExchange* : subsequent DestroyIcon in Win32 m_hIcon AfxGetApp()->LoadIcon(IDR_MAINFRAME); } = : CDialog(CMyDlg::IDD, pParent)

-2-

ON_COMMAND(IDM_Cuowu, OnCuowu) ON_COMMAND(IDM_Bianliang, OnBianliang) ON_COMMAND(IDM_Changliang, OnChangliang) //}}AFX_MSG_MAP END_MESSAGE_MAP() // Set the icon for this dialog. /////////////////////////////////////////// ////////////////////////////////// // CMyDlg message handlers framework does this automatically // when the application's main window is The } pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); }

not a dialog SetIcon(m_hIcon, TRUE); // Set

BOOL CMyDlg::OnInitDialog() { CDialog::OnInitDialog();

big icon SetIcon(m_hIcon, FALSE); small icon // Set

// Add "About..." menu item to system menu.

// TODO: Add extra initialization here

return TRUE; // return TRUE // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); & 0xFFF0) == set the focus to a control }

unless you

void CMyDlg::OnSysCommand(UINT nID, LPARAM lParam) {

CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu;

if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); }

strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) {

else { CDialog::OnSysCommand(nID, lParam);

pSysMenu->AppendMenu(MF_SEPARATOR);

}

-3-

}

else {

// If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications } }

CDialog::OnPaint();

using the document/view model, // this is automatically done for you by the // The system calls this to obtain the cursor to display while the user drags // void CMyDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting void CMyDlg::OnFenxi() { SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); here UpdateData(true); // Center icon in client rectangle int cxIcon = if (m_source=="") { m_result==""; = UpdateData(false); return; } CString s,strToken=""; int x=0; m_nLine=1; int y = (rect.Height() - cyIcon + 1) / 2; m_nword=0; m_nBianliang=0; m_nChangliang=0; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } for (int i=0;i<m_source.GetLength();i++) { s=m_source.GetAt(i); // TODO: Add your command handler code } the minimized window.

framework.

HCURSOR CMyDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon;

GetSystemMetrics(SM_CXICON); int cyIcon

GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2;

-4-

if ((s>64&&s<91)||(s>96&&s<123)||s=="_") { if (x==1||x==4) { strToken+=s; } else if(x==2) { strToken+=s; x=4; } else { lexical(strToken); strToken=s; x=1; } } else if (s>47&&s<58) { if (x==1||x==2||x==4) { strToken+=s; } else { lexical(strToken); strToken=s; x=2; } } else if (s==" "||s=="\t") { }

if(x==4) { m_word[m_nword]=strToken; m_t[m_nword]=0; m_i[m_nword]=m_nLine; m_nword++; strToken=""; x=0; } else { lexical(strToken); strToken=""; x=0; }

else if (s==13) { if(x==4) { m_word[m_nword]=strToken; m_t[m_nword]=0; m_i[m_nword]=m_nLine; m_nword++; strToken=s; x=0; } else { lexical(strToken); strToken=""; x=0; m_nLine++; }

-5-

} else if (s==10) { } else { if (x==3) { strToken+=s; } else if(x==4) { m_word[m_nword]=strToken; m_t[m_nword]=0; m_i[m_nword]=m_nLine; m_nword++; strToken=""; x=0; } else { lexical(strToken); strToken=s; x=3; } } } if(x==4) { m_word[m_nword]=strToken; m_t[m_nword]=0; m_i[m_nword]=m_nLine; m_nword++; } }

else { lexical(strToken); }

void CMyDlg::lexical(CString strToken) { if (strToken=="") return; CString s=strToken.GetAt(0); int i,m; if ((s>64&&s<91)||(s>96&&s<123)||s=="_") { m=reserve(strToken); if (m) { m_word[m_nword]=strToken; m_t[m_nword]=1; m_i[m_nword]=m; m_nword++; return; } for (i=0;i<=m_nBianliang;i++) { if (m_Bianliang[i]==strToken) { m_word[m_nword]=strToken; m_t[m_nword]=2; m_i[m_nword]=i; m_nword++; return;

-6-

} }

{ int n=0; while (n<strToken.GetLength())

m_Bianliang[m_nBianliang]=strToken; m_nBianliang++; m_word[m_nword]=strToken; m_t[m_nword]=2; m_i[m_nword]=m_nBianliang; m_nword++; return; } else if (s>47&&s<58) { for (i=0;i<=m_nChangliang;i++) { if (m_Changliang[i]==strToken) { m_word[m_nword]=strToken; m_t[m_nword]=3; m_i[m_nword]=i; m_nword++; return; } }

{ s=strToken.Mid(n,2); m=reserve(s); if (m) { m_word[m_nword]=s; if (m>30&&m<39) m_t[m_nword]=5; else m_t[m_nword]=4; m_i[m_nword]=m; m_nword++; n+=2; continue; } s=strToken.Mid(n,1); m=reserve(s); if (m) { m_word[m_nword]=s; if (m>30&&m<39) m_t[m_nword]=5;

m_Changliang[m_nChangliang]=strToken; m_nChangliang++; m_word[m_nword]=strToken; m_t[m_nword]=3; m_i[m_nword]=m_nChangliang; m_nword++; return; } else }

else m_t[m_nword]=4; m_i[m_nword]=m; m_nword++; n+=1; continue;

m_word[m_nword]=strToken.Mid(n,1);

-7-

m_t[m_nword]=0; m_i[m_nword]=m_nLine; m_nword++; n+=1; } } }

else if (strToken==">=") n=24; else if (strToken=="<=") n=25; else if (strToken=="&&") n=26; else if (strToken=="||") n=27; else if (strToken=="!") n=28; else if (strToken=="(") n=30; else if (strToken==")") n=31; else if (strToken=="{") n=32;

int CMyDlg::reserve(CString strToken) { int n=-1; if (strToken=="int") n=0; else if (strToken=="char") n=1; else if (strToken=="float") n=2; else if (strToken=="void") n=3; else if (strToken=="const") n=4; else if (strToken=="if") n=5; else if (strToken=="else") n=6; else if (strToken=="do") n=7; else if (strToken=="while") n=8; else if (strToken=="scanf") n=9; else if (strToken=="printf") n=10; else if (strToken=="return") n=11; else if (strToken=="main") n=12; else if (strToken=="+") n=14; else if (strToken=="-") n=15; else if (strToken=="*") n=16; else if (strToken=="/") n=17; else if (strToken=="%") n=18; else if (strToken=="=") n=19; else if (strToken=="==") n=20; else if (strToken==">") n=21; else if (strToken=="<") n=22; else if (strToken=="!=") n=23; here }

else if (strToken=="}") n=33; else if (strToken==";") n=34; else if (strToken==":") n=35; else if (strToken=="\"") n=36; else if (strToken=="\'") n=37; else if (strToken=="++") n=38; else if (strToken=="--") n=39; return n+1;

void CMyDlg::OnEryuanzu() { // TODO: Add your command handler code

CString s,strText=""; for (int i=0;i<m_nword;i++) { if (m_t[i]) { s.Format("%20s (%d,%d)\r\n",m_word[i],m_t[i],m_i[i]); strText+=s; } } m_result=strText; UpdateData(false);

-8-

}

void CMyDlg::OnBianliang() {

void CMyDlg::OnCuowu() { // TODO: Add your command handler code here CString s,strText=""; for (int i=0;i<m_nword;i++) { if (!m_t[i]) { s.Format(" 不 可 识 别 的 字 符 : \'%s\' 行:%d\r\n",m_word[i],m_i[i]); strText+=s; } } if (strText=="") { strText="无错误..."; } m_result=strText; UpdateData(false); } } here } here

// TODO: Add your command handler code

m_result=""; for (int i=0;i<m_nBianliang;i++) { m_result+=m_Bianliang[i]+"\r\n"; } UpdateData(false);

void CMyDlg::OnChangliang() { // TODO: Add your command handler code

m_result=""; for (int i=0;i<m_nChangliang;i++) { m_result+=m_Changliang[i]+"\r\n"; } UpdateData(false);

五、运行结果
此次实验我采取的是 VC++6.0 平台编译程序,见面力求简洁,以满足实验功能为主。

-9-

运行之后的界面如上, 两列菜单项 “文件”—开始分析, “查看”—二元组、错误信息、 变量表、常量表。

10

“二元组”和“变量表”结果如上

错误信息

常量表

11

六、小结(不少于 100 字)
这次实验的主要目的是通过设计调试词法分析程序, 实现从源程序中分出各种单词的方 法; 加深对课堂教学的理解, 深刻理解词法分析的整个过程, 提高词法分析方法的实践能力。 我在仔细学习并听讲之后决定采用 VC++6.0 的编译平台; 力求以简洁的风格 首要任务是做 出满足词法分析的功能要求的程序。所以没有追求程序的可视化界面的美观。 在实际编写过程中遇到的主要问题就是如何正确分析一段程序代码的有效字符并正确 结合二元组的表示;另外一点就是“错误信息”的功能,此项功能不但需要程序识别出“不 可识别的字符” 更需要统计出错误所在的行数。在编写过程中主要精力在于这两项功能的 算法实现;最后经过和同学讨论以及查阅资料使得问题得到了解决。 总的来说, 这一次类 C 语言的词法分析程序有一定的难度, 但是并非难道无法做出来; 关键的难题在于 如何将 编译原理课程所学的知识与实际编程操作结合起来, 这次实验也主 要锻炼了我这一方面的能力,确实需要进一步加强和有待提高。我认为在今后的学习中,不 但需要努力学习掌握好编译原理的理论知识, 在课余时间还需要经常加以练习才可以得到更 好的提高和更深层次的理解。

12


搜索更多“编译原理 词法分析实验一”

网站地图

All rights reserved Powered by 伤城文章网 5xts.com

copyright ©right 2010-2021。
伤城文章网内容来自网络,如有侵犯请联系客服。zhit325@126.com