大工软院编译上机1词法分析.docx
《大工软院编译上机1词法分析.docx》由会员分享,可在线阅读,更多相关《大工软院编译上机1词法分析.docx(9页珍藏版)》请在冰点文库上搜索。
![大工软院编译上机1词法分析.docx](https://file1.bingdoc.com/fileroot1/2023-8/3/6d1c6ffa-7785-4150-9c5b-b4d2d1f893a5/6d1c6ffa-7785-4150-9c5b-b4d2d1f893a51.gif)
大工软院编译上机1词法分析
大连理工大学软件学院编译技术课程——词法分析上机实验
//注意:
需要建立test文档,文档内为输入
实验目的:
对循环语句和条件判断语句编写词法分析编译程序,只能通过一遍扫描完成。
(用c++实现)
实验要求:
(1)关键字:
forifthenelsewhiledo
所有关键字都是小写。
(2)运算符和分隔符:
:
=+-*/<><=<>>=;()#
(3)其他标识符(ID)和整型常数(NUM),通过以下正规式定义:
ID=letter(letter|digit)*
NUM=digitdigit*
(4)空格由空白、制表符和换行符组成。
空格一般用来分隔ID、NUM、运算符、分隔符和关键字,词法分析阶段通常被忽略。
各种词法单元对应的词法记号如下:
词法单元
词法记号
词法单元
词法记号
for
1
:
17
if
2
:
=
18
then
3
<
20
else
4
<>
21
while
5
<=
22
do
6
>
23
letter(letter+digit)*
10
>=
24
digitdigit*
11
=
25
+
13
;
26
-
14
(
27
*
15
)
28
/
16
#
0
词法分析程序的功能
输入:
源程序
输出:
二元组(词法记号,属性值/其在符号表中的位置)构成的序列。
例如:
对源程序
x:
=5;if(x>0)thenx:
=2*x+1/3;elsex:
=2/x;#
经词法分析后输出如下序列:
(10,’x’)(18,:
=)(11,5)(26,;)(2,if)(27,()……
1.几点说明:
(1)关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符,查关键字表。
如能查到匹配的单词,则该单词的关键字,否则为一般标识符。
关键表为一个字符串数组,其描述如下:
char*keyword[6]={”for”,”if”,”then”,”else”,”while”,”do”};
(2)程序中需要用到的主要变量为token,id和num.
1)id用来存放构成词法单元的字符串;
2)num用来存放整数(可以扩展到浮点数和科学计数法表示);
3)token用来存放词法单元的词法记号。
可以参考下面的代码:
do{
lexical();//将词法单元对应的记号保存到token中,属性值保存到num或者id中
switch(token){
case11:
printf("(token,%d\n)",num);break;
case-1:
printf("error!
\n");break;
default:
printf("(%d,%s)\n",token,id);
}
}while(token!
=0);
#include
#include
#include
#include
#include
usingnamespacestd;
stringkeyword[6]={"for","if","then","else","while","do"};
boolisLETTER(chartemp)
{
if(temp>='a'&&temp<='z')
returntrue;
else
returnfalse;
}
boolisDIGIT(chartemp)
{
if(temp>='0'&&temp<='9')
returntrue;
else
returnfalse;
}
boolisID(stringtemp)
{
boolflag=true;
if(!
isLETTER(temp[0]))
flag=false;
for(inti=1;i{
if(!
(isLETTER(temp[i])||isDIGIT(temp[i])))
flag=false;
}
returnflag;
}
boolisNUM(stringtemp)
{
boolflag=true;
for(inti=0;i{
if(!
(temp[i]>='0'&&temp[i]<='9'))
flag=false;
}
returnflag;
}
voidgetkey(stringtemp,int&key)
{
if(temp=="for")key=1;
elseif(temp=="if")key=2;
elseif(temp=="then")key=3;
elseif(temp=="else")key=4;
elseif(temp=="while")key=5;
elseif(temp=="do")key=6;
elseif(isID(temp))key=10;
elseif(isNUM(temp))key=11;
elseif(temp=="+")key=13;
elseif(temp=="-")key=14;
elseif(temp=="*")key=15;
elseif(temp=="/")key=16;
elseif(temp==":
")key=17;
elseif(temp==":
=")key=18;
elseif(temp=="<")key=20;
elseif(temp=="<>")key=21;
elseif(temp=="<=")key=22;
elseif(temp==">")key=23;
elseif(temp==">=")key=24;
elseif(temp=="=")key=25;
elseif(temp==";")key=26;
elseif(temp=="(")key=27;
elseif(temp==")")key=28;
elseif(temp=="#")key=0;
elsekey=-1;
}
intmain()
{
stringtemp;
chara;
intkey;
queueaqueue;
char*array=newchar[20];
boolflag=true;
ifstreamfile;
file.open("test.txt");
if(!
file)
{
cout<<"can'topen'test.txt'"<exit
(1);
}
a=file.get();
while(!
file.eof())
{
while(a=='')
{
a=file.get();
}
flag=true;
inti=0;
array[i++]=a;
while(isDIGIT(a))
{
a=file.get();
if(isDIGIT(a))
array[i++]=a;
else
flag=false;
}
if(isLETTER(a)&&flag)
{
while(isLETTER(a)||isDIGIT(a))
{
a=file.get();
if(isLETTER(a)||isDIGIT(a))
array[i++]=a;
else
flag=false;
}
}
if(flag)
{
switch(a)
{
case':
':
a=file.get();
if(a=='=')
{
array[i++]=a;
a=file.get();
}
break;
case'<':
a=file.get();
if(a=='>'||a=='=')
{
array[i++]=a;
a=file.get();
}
break;
case'>':
a=file.get();
if(a=='=')
{
array[i++]=a;
a=file.get();
}
break;
default:
a=file.get();break;
}
}
stringt(array,i);
aqueue.push(t);
}
while(!
aqueue.empty())
{
temp=aqueue.front();
aqueue.pop();
getkey(temp,key);
switch(key)
{
case-1:
cout<<"error!
"<//case0:
cout<<"("<default:
cout<<"("<}
}
return0;
}