北邮 编译原理 词法分析程序报告Word文档下载推荐.docx
《北邮 编译原理 词法分析程序报告Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《北邮 编译原理 词法分析程序报告Word文档下载推荐.docx(20页珍藏版)》请在冰豆网上搜索。
for(l=0;
num!
=0;
l++){
m=num%10;
//sdfafda
for(t=0;
t!
=l;
t++)
m=m*2;
//dafdaf
n=nm;
num=num/10;
/*dafdas2323*/
}
//theresultis%d//"
n);
return0;
}
窗口运行结果:
=============================================================
*词法分析系统*
请输入需要分析的文件名称:
code.txt
-------------------------------------------------------------
处理完毕。
共出现1个错误。
共有21行,33个单词,236个字符。
结果请在token_table.txt中查看。
请按任意键继续...
Token.txt;
单词记号
##
includeid
<
relop,LT
stdioid
hid
>
relop,GT
mainid
((
))
{{
intint
numid
,
nid
=relop,EQ
0num
mid
lid
tid
;
;
printfid
scanfid
&
&
forfor
!
=RELOP,UE
++
%%
10num
**
2num
nmid
//
}}
returnreturn
Error.txt:
1.在第1行第15列出现非法字符
Note.txt:
line6.双引号间字符:
line7.双引号间字符:
%d
line7.ddsfsdf
line10.ssdfafda
line12.ddafdaf
line14.dafdas2323
line17.双引号间字符:
//theresultis%d//
Count.txt:
四.源代码
头文件:
string>
cstdio>
cstdlib>
cstring>
fstream>
iostream>
usingnamespacestd;
全局变量:
constintMAXBUFFER=62;
//缓冲区容量
constintLB=30;
//左缓冲区大小
constintLRB=61;
//左+右缓冲区大小
constintKEY=32;
//关键字个数
fstreamcode_file;
intcnum;
//列数
intlb_end,rb_end,forward;
//左右缓冲区结束位置,向前指针
intlready,rready;
//标记左右缓冲区是否已经录入过内容
charbuffer[MAXBUFFER];
//缓冲区
charC;
//当前读入的字符
stringtoken;
//存放单词的字符串
intkeynum,errornum;
//关键字的序列号;
error的个数
intlnum,wordnum,charnum;
//语句数单词数字符数
char*key[KEY]={"
auto"
"
const"
double"
float"
int"
short"
struct"
"
unsigned"
break"
continue"
else"
for"
long"
signed"
switch"
void"
case"
default"
enum"
goto"
register"
static"
typedef"
volatile"
char"
do"
extern"
if"
return"
sizeof"
union"
while"
};
//关键字表
函数:
voidfillbuf(intx)
if(x==0){//填充左半区
if(lready==0){//左半区未填充
code_file.read(buffer,LB);
//读入LB个字符到buffer左半区中
if(code_file.gcount()!
=lb_end)
//如果读入的字符不足LB个在之后添加EOF
buffer[code_file.gcount()]=EOF;
else
lready=0;
else{//填充右半区
if(rready==0){
code_file.read(buffer+LB+1,LB);
//读入LB个字符到buffer右半区中
=LB)
buffer[code_file.gcount()+LB+1]=EOF;
}
rready=0;
}
voidget_nbc();
voidget_char()
C=buffer[forward];
//获取当前字符
if(C==EOF)
return;
elseif(C=='
\n'
){
cnum=0;
//列=0
lnum++;
//+1行
elseif(C>
=33&
C<
=126){
charnum++;
//字母或数字或符号的话+1字符
//cout<
第"
charnum<
字符------"
C<
endl;
cnum++;
forward++;
if(buffer[forward]==EOF){
if(forward==lb_end){
//到左区结束位置填充右半区
fillbuf
(1);
if(forward==rb_end){
//到右区结束位置填充左半区向前指针回到开始位置
fillbuf(0);
forward=0;
voidretract()
{//向前指针后退一个字符
charnum--;
cnum--;
if(forward==0){
lready=1;
//避免重新读取
forward=rb_end-1;
//后退一个字符
elseif(forward==lb_end){
rready=1;
forward--;
elseforward--;
voidget_nbc()
{//若C中的字符为空字符则反复调用直到非空字符为止
while(C=='
'
||C=='
\t'
\0'
||C=='
)
get_char();
retract();
intreserve(stringword)
{//查关键字表返回0表示token中的字符串是标识符1表示关键字
for(keynum=0;
keynum<
KEY;
keynum++){
if(pare(key[keynum])==0)
return1;
return0;
主函数:
main(){
cout<
============================================================="
cout<
*词法分析系统*"
<
=============================================================="
endl<
chars[30];
//存储文件名称
cin>
s;
code_file.open(s);
intp;
while(code_file==NULL){
无此文件,打开失败。
请重新输入:
//初始化
lb_end=LB;
rb_end=LRB;
lready=rready=0;
lnum=1;
wordnum=charnum=0;
buffer[lb_end]=buffer[rb_end]=EOF;
errornum=0;
-------------------------------------------------------------"
fstreamtoken_table,error,count,note;
error.open("
error.txt"
ios_base:
:
out);
//保存错误
count.open("
count.txt"
//保存语句数单词数字符数计数
note.open("
note.txt"
//保存注释
token_table.open("
token.txt"
//输出的记号
token_table<
单词\t\t记号"
while(C!
=EOF){
token="
if((C>
64&
91)||(C>
96&
123)||C=='
_'
){
//标示符判断字母或者下划线开头
token=token+C;
while((C>
123)
||(C>
47&
58)||C=='
//字母或数字或下划线
if(C!
='
C!
&
)
wordnum++;
//这是一个单词
if(reserve(token)==0)//这是一个标识符
token<
\t\tid"
else//这是一个关键字
\t\t"
'
note<
line"
lnum<
.双引号间字符:
"
get_nbc();
58){//数字判断
while(C>
58){
if(C=='
.'
if(C>
//小数点后必须有数字否则报错
E'
e'
+'
-'
//E后面可以是+-号
//+-后面必须有数字否则报错
//后退一位后退出
else{
errornum++;
error<
errornum<
.在第"
行"
cnum<
列出现错误"
//E后面也可以是数字其他情况则报错
else{//退出
else{//记录错误退出此if重新判断
列出现错误
){//E后面可以是+-号
58){//+-后面必须有数字否则报错
\t\tnum"
switch(C){
case'
//<
或者<
=或者<
=\t\trelop,LE"
\t\trelop,NE"
else{
\t\trelop,LT"
break;
//>
或者>
=
=\t\trelop,GE"
\t\trelop,GT"
//=
=\t\trelop,EQ"
//:
=或者:
\t\t:
//!
=
=\t\tRELOP,UE"
\t\t!
/'
//过滤注释
){//过滤掉//开头的注释
."
C;
et_char();
*'
){//过滤掉/*开头的注释
while
(1){
*"
/\t\t/"
case'
#'
('
)'
['
]'
%'
'
{'
}'
\t\t"
default:
列出现非法字符"