登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

秒大刀 博客

好好学习 天天向上

 
 
 

日志

 
 
 
 

词法分析程序  

2006-02-25 21:59:58|  分类: 技术积累 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

//词法分析器
#include<iostream>
#include<ctype.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>

#define ID 6   
#define INT 7
#define LT 8
#define LE 9
#define EQ 10
#define NE 11
#define GT 12
#define GE 13
#define FZ 14       
#define DEV 15

using namespace std;


struct KeyWord        //关键字结构
{
 char *word;
 int id;
};

KeyWord keyword[]={    //关键字数组
 {"begin",1},
 {"end",2},
 {"if",3},
 {"then",4},
 {"else",5},
 {"integer",16},
 {"float",17},
 {"double",18}
};


char TOKEN[20];
int graphnum=1;     //记录错误所在的位置(行数)


int lookup(char *string);//给定字符串得到对应的ID
void out(int id ,char *string);//输出ID和字符串
void report_error(char ERR_CH);//输出错误的位置
bool isalpha(char c) ; //合法字符的判断(字母)
bool isdigit(char c);//合法字符的判断(数字)
bool isalnum(char c);//合法字符的判断
void scanner_example(FILE *fp);//主分析程序

 

int lookup(char *string)//给定字符串得到对应的ID
{
 for(int i=0;i<(sizeof(keyword)/sizeof(KeyWord));i++)
 {
  if(strcmp(string,keyword[i].word)==0)
   return keyword[i].id;
 }
 return 0;
}

void out(int id ,char *string)//输出ID和字符串
{
 printf("(%d,%s)\n",id,string);
}

void report_error(char ERR_CH)        //错误处理程序
{
 printf("undeclared identifler %c int %d line!\n",ERR_CH,graphnum);
}

bool isalpha(char c)   //合法字符的判断(字母)
{
 if( (c>='a'&&c<='z') || (c>='A'&&c<='Z') )
  return true;
 else
  return false;
}

bool isdigit(char c) //合法字符的判断(数字)
{
 if(c>='0'&&c<='9')
  return true;
 else
  return false;
}

bool isalnum(char c)//合法字符的判断
{
 if( isalpha(c) || isdigit(c) )
  return true;
 else
  return false;
}

void scanner_example(FILE *fp)//主分析程序
{
 char ch;
 int i,c;
 
 while(!feof(fp))
 {
  
  ch=fgetc(fp);
  if(isalpha(ch))//首字符是字母
  {
   TOKEN[0]=ch;
   ch=fgetc(fp);
   i=1;
   //连续读取只到出现非法字符
   while(isalnum(ch))  //注意!TOKEN只有20长,若不加检测可能使程序崩溃
   {
    TOKEN[i]=ch;
    i++;
    ch=fgetc(fp);
   }
   TOKEN[i]='\0';
   fseek(fp,-1,1);
   c=lookup(TOKEN);//得到ID
   //输出词法分析的结果
   if(c==0)
    out (ID,TOKEN);
   else
    out (c,"");
  }
  else if(isdigit(ch))//首字符是数字
  {
   TOKEN[0]=ch;
   ch=fgetc(fp);
   i=1;
   while(isdigit(ch))
   {
    TOKEN[i]=ch;
    i++;
    ch=fgetc(fp);
   }
   TOKEN[i]='\0';
   fseek(fp,-1,1);
   out(INT,TOKEN);
  }
  else//特殊字符
  switch(ch)
  {
  case '<': ch=fgetc(fp);
   if(ch=='=')
    out(LE," ");
   else if(ch=='>')
    out(NE," ");
   else
   {
    fseek(fp,-1,1);
    out(LT," ");
   }
   break;
  case '=': out(EQ, " ");
   break;
  case '>': ch=fgetc(fp);
   if(ch=='=')
    out(GE," ");
   else
   {
    fseek(fp,-1,1);
    out(GT," ");
   }
   break;
  case ':': ch=fgetc(fp);
   if(ch=='=')              // := 为赋值语句
    out(FZ," ");
   else
   {
    fseek(fp,-1,1);
    report_error(ch);
   }
   break;
  case '/': ch=fgetc(fp);   //删除程序中的注释
   if(ch=='/')
   {
    do
    {
     ch=fgetc(fp);
    }while(ch!='\n');
    graphnum++;
   }
   else
   {
    fseek(fp,-1,1);
    out(DEV," ");
   }
   break;
  case ' ' : break;                 //删除程序中的空格             
  case '\n': graphnum++; break;   //删除程序中的回车,并记录程序编译到第几行           
  case '\t': break;      //删除程序中的横向制表符
  case -1 : break;      //删除文件尾符号
  default : report_error(ch);
   break;
  }
  
 }
 return;
}
void main(int argc,char *argv[])
{
 FILE *fp;
 //采用标准的C++错误处理
 try
 {
  if(argc!=2)
   throw argc;
  fp=fopen(argv[1],"r");
  if(!fp)
   throw argv[1];
  
 }
 
 catch(char *str)
 {
  cout<<"打开文件 : "<<str<<" 时发生错误!"<<endl;
  exit(1);
 }
 
 catch(int)
 {
  cout<<"请输入一个文件名!"<<endl;
  exit(1);
 }
 
 
 scanner_example(fp);
 
 fclose (fp);
}

 

  评论这张
 
阅读(2025)| 评论(3)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018