合肥工业大学编译原理实验报告(完整代码版)
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
关系运算符
(1,3)
12
0
( 5,0 )
常数
(1,4)
then
( 1,then)
关键字
(1,5)
n
(6,n )
标识符
(1,6)
++
Error
Error
(1,7)
;
( 2, ; )
分界符
(1,8)
a
(6,a )
标识符
(2,1)
﹤=
(4,<= )
关系运算符
(2,2)
3b
Error
Error
(2,4)
%
Error
else searcht(2,sn); }
}; void split(string s)//分割字符串 { // cout<<s<<endl;
string now[max]; string sn; int nowpointer=0;
int i=0; int x; int sign=2;//非法数字标志 int diannumber=0;//数中点的个数
const char* salaryfile="salaryfile.txt"; const int max=40; string id[max]={"do","end","for","if","printf","scanf","then","while"};// 关 键 字表
string s[max]={",",";","(",")","[","]","+","-","*","/","<","<=","=",">",">=","<>"}; //分界符表 算数运算符表 关系运算符表 string k[max];// 标识符 string ci[max];// 常数 int fjfpoint=5;//分界符表尾 int mathpoint=9;//算数运算符表尾 int cipointer=0;//常数表尾 int idpointer=0;//关键字表尾 int kpointer=0;//标识符表尾 int fjf;//0 不是分界符 1 是
计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和
清楚的
理解,并能正确地、熟练地运用
二、 实验要求
1、编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。
2、将标识符填写的相应符号表须提供给编译程序的以后各阶段使用。
3、根据测试数据进行测试。测试实例应包括以下三个部分:
全部合法的输入。
{ sn=s.substr(x-i+1,i); // cout<<sn<<"运算符 i="<<i<<endl; cout<<sn<<" "; outkey=1; wordlook(sn[0],sn); rowx++; i=0;
} } if(fjf==1) {
if((s[x-1]>64&&s[x-1]<91)||(s[x-1]>96&&s[x-1]<123)||(s[x-1]>=48&&s[x-1]<=57))
}
else sign=0; }
} i++; if(x==(s.length()-1)) { sn=s.substr(x-i+1,i);
if(i>0)
{
// cout<<sn<<" i="<<i<<endl;
cout<<sn<<" ";
if(sign==0)//数字后有字母的情况
cout<<"
("<<rowy<<","<<rowx<<")"<<endl;
同时
进行标识符登记符号表的管理。
以下是实现词法分析设计的主要工作: (1)从源程序文件中读入字符。 (2)统计行数和列数用于错误单词的定位。 (3)删除空格类字符,包括回车、制表符空格。 (4)按拼写单词,并用(内码,属性)二元式表示。(属性值——token 的机内 表示) (5)如果发现错误则报告出错 7 (6)根据需要是否填写标识符表供以后各阶段使用。
{ sn=s.substr(x-i,i); if(i>0)
{ // cout<<sn<<" i="<<i<<endl;
cout<<sn<<" "; if(sign==0) cout<<" Error Error ("<<rowy<<","<<rowx<<")"<<endl; else { // cout<<" true"<<endl;
outkey=0;
}
fjf=0;
}
}
Βιβλιοθήκη Baidu};
void wordlook(char t,string sn)//识别首字符,分类识别字符串 {
if(t>=48&&t<=57) searcht(1,sn);
else {
if((t>64&&t<91)||(t>96&&t<123)) searcht(0,sn);
}
}
if(x==max)//不是关键字再识别标识符
{
for(x=0;x<max;x++)
{
if(k[x]==m)
{
cout<<"(6,"<<m<<")
"<<"
标
识
符
("<<rowy<<","<<rowx<<")"<<endl;
break;
}
}
if(x==max)//标识符表没有时插入标识符
{
cout<<"(6,"<<m<<")
int rowy=1;//识别输入行位置 int rowx=1;//识别输入列位置
int outkey=0;//打印控制 0 为数字后有字母 其他可以
void searcht(int i,string m)//根据已识别的首字母识别字符串
{
// cout<<"enter searcht!!"<<endl;
{
if(outkey==1)
{
cout<<"(4,"<<s[x]<<") 关 系 运 算 符
("<<rowy<<","<<rowx<<")"<<endl;
outkey=0;
}
fjf=0;
}
if(x==max)
{
if(outkey==1)
{
cout<<"Error Error ("<<rowy<<","<<rowx<<")"<<endl;
四、实验步骤 1、根据流程图编写出各个模块的源程序代码上机调试。 2、 编制好源程序后,设计若干用例对系统进行全面的上机测试,并通过所设计 的词法分析程序;直至能够得到完全满意的结果。 3、书写实验报告 ;实验报告正文的内容:
功能描述:该程序具有什么功能? 程序结构描述:函数调用格式、参数含义、返回值描述、函数功能;函数 之间的调用关系图。 详细的算法描述(程序总体执行流程图) 。 给出软件的测试方法和测试结果。 实验总结 (设计的特点、不足、收获与体会)。 五、实验截图
break; } // x--;
if(x<6) {
fjf=1;
}
if(x>5&&x<10)
{
if(outkey==1)
{
cout<<"(3,"<<s[x]<<")
算数运算符
("<<rowy<<","<<rowx<<")"<<endl;
outkey=0;
}
fjf=0;
}
if(x>9&&x<max-1)
计算机与信息学院 编译原理 实验报告
专业班级 学生姓名及学号 课程教学班号 任课教师 实验指导教师 实验地点
信息安全 13-1 班 马骏 2013211869
李宏芒 李宏芒 实验楼机房
2015 ~2016 学年第 二 学期
实验 1 词法分析设计
一、 实验目的
通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设
for(x=0;x<s.length();x++) {
if((s[x]>64&&s[x]<91)||(s[x]>96&&s[x]<123)||(s[x]>=48&&s[x]<=57)||(x>0& &s[x]==46&&sign==1))//判断数字后跟字母还是字母后有数字
{ if(i==0) { if(s[x]>=48&&s[x]<=57) sign=1; else sign=2; } else { if(sign==1) { if(s[x]>=48&&s[x]<=57||s[x]==46) { if(s[x]==46) { if(diannumber==0) diannumber++; else sign=0; }
int x;
if(i==0)//首字符是字母识别关键字
{
//
cout<<" a word!!"<<endl;
for(x=0;x<max;x++)
{
if(id[x]==m)
{
cout<<"(1,"<<id[x]<<")"<<"
关
键
字
("<<rowy<<","<<rowx<<")"<<endl;
break;
else //字母开头的字符串
{
//
cout<<" true"<<endl;
wordlook(sn[0],sn);
rowx++;
}
}
}
Error
Error
} else {
if(x>0&&(s[x-1]>64&&s[x-1]<91)||(s[x-1]>96&&s[x-1]<123)||(s[x-1]>=48&& s[x-1]<=57))//遇到分界符运算符 如果前面是数字或字母
各种组合的非法输入。
由记号组成的句子。
4、词法分析程序设计要求输出形式:
例:输入 VC++语言的实例程序:
If i=0 then n++;
a﹤= 3b %);
输出形式为:
单词
二元序列
类型
位置(行,列)
(单词种别,单词属性)
for
(1,for )
关键字
(1,1)
i
( 6,i )
标识符
(1,2)
=
( 4,= )
先创建 salaryfile.txt 文件 输入 If i=0 then n++; a<= 3b %);
六、核心代码 #include<iostream>
#include<string> #include<fstream> #include <sstream>
using namespace std;
wordlook(sn[0],sn); rowx++;
} }
i=0; }
string ll=s.substr(x,1);//判断是运算符还是分界符 wordlook(s[x],ll); if(fjf==0)//是运算符 {
i++;
if((s[x+1]>64&&s[x+1]<91)||(s[x+1]>96&&s[x+1]<123)||(s[x+1]>=48&&s[x+1] <=57))//如果后面是数字或字母
分界符
("<<rowy<<","<<rowx<<")"<<endl;
rowx++;
/* if(ll==";")
} }
{ rowy++; rowx=1;
} */
}
}; int main() {
int x; string instring;//读入一行 string sn;
/* getline(cin,sn);// string 带空格输入 cout<<sn<<endl; char t=sn[0]; if(t>=48&&t<=57) searcht(1,sn); else { if((t>64&&t<91)||(t>96&&t<123)) searcht(0,sn); else searcht(2,sn); }
Error
(2,4)
)
( 2, ) )
分界符
(2,5)
;
( 2, ; )
分界符
(2,6)
三、 实验内容
用 VC++/VB/JAVA 语言实现对 C 语言子集的源程序进行词法分析。通过
输
入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编
码及单
词符号自身值;若遇到错误则显示“Error”,然后跳过错误部分继续显示 ;
"<<"
标
识
符
("<<rowy<<","<<rowx<<")"<<endl;
k[kpointer]=m;
kpointer++;
} }
} if(i==1)//识别常数 { // cout<<" a number!!"<<endl;
for(x=0;x<max;x++) {
if(ci[x]==m) {
cout<<"(5,"<<x<<")"<<endl; break; } } if(x==max) {
cout<<"(5,"<<m<<") 常数 ("<<rowy<<","<<rowx<<")"<<endl; ci[cipointer]=m; cipointer++; } } if(i==2)//识别 分界符 算数运算符 关系运算符 { // cout<<" a signal!!"<<endl; for(x=0;x<max;x++) { if(s[x]==m)
//如果前面是数字或字母
{
}
else if(i>0)
{
sn=s.substr(x-i,i);
// cout<<sn<<"运算符 i="<<i<<endl;
cout<<sn<<" ";
outkey=1;
wordlook(sn[0],sn);
rowx++;
i=0;
}
cout<<s[x]<<" (2,"<<s[x]<<")