通行证│用户名: 密码: 验证码: 验证码,看不清楚?请点击刷新验证码 电信网通铁通移动   在线
资源搜索:
热门搜索:Linux VB C语言 PhotoShop Flash TCP/IP
   首页 | 文章 | 软件 | 动画 | 资源 | 励志 | 骗术 | 论坛 | 邮箱 | 会员中心 | 军事 | 科技 | 博客 | 图片 | 商城 | 最新更新 | 800g资源 | 爱心黑客
您现在的位置: 爱国者黑客 >> 资源 >> 程序设计 >> C#语言 >> 数据库编程 >> 文章正文
一个小语言的词法分析程序
责任编辑:ncic   更新日期:2007-4-2

本文示例源代码下载

  前些天写了个小语言的词法分析程序,因为前些天在VC知识库看到一个pascal词法分析的程序,觉得写得挺复杂的。其实词法分析程序的原理都是一样的,所以我想只要搞明白了简单的词法分析程序,再写复杂的就不难了,无非是多加几个关键字,多写几个条件判断语句而已。词法分析是编译程序的基础,也是最简单的。好,现在让我们看程序吧。

  先让我们看看这个小语言的文法吧。

  G[<程序>]:

  <程序>∷=<程序首部>;<分程序>.

  <程序首部>∷=program<标识符>

  <分程序>∷=<复合语句>

  <复合语句>∷=begin<语句序列>end

  <语句序列>∷=<语句>{;<语句>}

  <语句>∷=<赋值语句>|<复合语句>|<条件语句>

  <赋值语句>∷=<标识符>:=<表达式>

  <条件语句>∷=if <布尔表达式> then <语句> else <语句>

  <表达式>∷=<项>{(+|-)<项>}

  <项>∷=<因式>{(*|/)<因式>}

  <因式>∷=<标识符>|<无正负号常量>|’(’<表达式>’)’

  <布尔表达式>∷=<表达式><关系运算符><表达式>

  <关系运算符>∷= =|<|<=|>|>=|<>

  <标识符>∷=<字母>{<字母>|<数字>}

  <无正负号常量>∷=<数字>{<数字>}[.<数字>{<数字>}]

  <字母>∷=a|b|c|d|e|f|g|……|u|v|w|x|y|z

  <数字>∷=0|1|2|3|4|5|6|7|8|9

  根据此文法,构造一词法分析程序。输入以“#”为结束符

  按照这个文法,找出该语言的关键字,如program,begin,end ,if,then,else,以及其他一些特殊符号,然后再构造一个分析表,如下表: 单词符号 类别编号标识符1常数2if3then4else5program6begin7end8+9-10*11/12(13)14>15>=16<17<=18<>19:=20;21.22,23

  根据这个表来构造程序,程序的核心是下面的这个函数,

/********************************************************************
以下为主分析函数
从输入文件里面读,把分析结果写到输出文件中
参数:fpin :输入文件指针 fpout: 输出文件指针
********************************************************************/
void parse(FILE* fpin,FILE* fpout)
{
  char arr[MAXBUF];//读出的最长的字符串不超过MAXBUF,MAXBUF定义为255,够长了我想
  int i=0;//分析含字母的字符串用
  int j=0;//分析纯数字的字符串用
  
  while(1)
  {
  fscanf(fpin,"%c",&ch);//从输入文件中读入一个字符
    if( ch=='' ''|| ch ==''  '')//过滤掉空格和tab
      ;
    else if( ch==''
'')//回车换行符,为下面进行错误判断
      lineno++;
    else if( IsDigit(ch))//读入的是数字
    {
      while(IsDigit(ch))
      {
        
        arr[j] = ch;
        j++;
        fscanf(fpin,"%c",&ch);
        
      }
      
      fseek(fpin,-1L,SEEK_CUR);//文件指针后退一个字节
      char* temp1 =(char*)malloc(j+1);/
      memcpy(temp1,arr,j);
      temp1[j] ='''';//把数组里面的内容拷贝到连外一个数组里面,因为我定义的
      //arr为255个字节,实际上写不到那么多,所以只拷贝实际上有数据
      j=0;//恢复初始状态,以备下次使用
      fprintf(fpout,"%s    %d
",temp1,2);//常数
    
      free(temp1);//释放内存
      
      
    }
    else if(IsAlpha(ch))//是字母开头的
    {
    
      while(IsAlpha(ch) || IsDigit(ch))
      {
        arr[i] =ch;
        i++;
        fscanf(fpin,"%c",&ch);
        
      }
      fseek(fpin,-1L,SEEK_CUR);
      
      char* temp = (char*)malloc(i+1) ;
      memcpy(temp,arr,i);
      temp[i] ='''';
      i=0;
      /*基本思想同处理数字的*/
    
     if(FindOK(temp))//FindOK函数在关键字表中查找和temp字符串相同的,找到就返回类别编号
     {
      
       fprintf(fpout,"%s    %d
",temp,FindOK(temp));
      
     }
     else
     {
       fprintf(fpout,"%s    %d
",temp,1);//标示符号
       
     }
     free(temp);
    }
  
    //以下为2字节的运算符号
    else if( ch=='':'')//符号“:=”
    {
      fscanf(fpin,"%c",&ch);
      if(ch==''='')
        fprintf(fpout,"%s    %d
",":=",20);
      
    else   
      fprintf(fpout,"error in compileing %d lines unknown character %c
",lineno,ch);//出错了
    }
    else if(ch==''>'')//符号 “> “ 和”>=”
    { 
      fscanf(fpin,"%c",&ch);
      if(ch==''='')
      fprintf(fpout,"%s    %d
",">=",16);
      else
      fprintf(fpout,">    15
");
    }
    else if( ch==''<'') //符号 “< “ 和”<=”
    {
      fscanf(fpin,"%c",&ch);
      if(ch==''='')
      {fprintf(fpout,"<=    18
");}
      else if( ch==''>'')
      {fprintf(fpout,"<>    19");}
      else
      {fprintf(fpout,"<    19
");}
    }
  
    else {
      //以下为一个字节的运算符号
    if(ch==''-'') {fprintf(fpout,"%s    %d
",''-'',10);continue;}//在文件中输出为“-  10”
    if(ch=='';'') {fprintf(fpout,";    21
");continue;}
    if(ch==''+'') {fprintf(fpout,"+    9
");continue;}
    if(ch==''*'') {fprintf(fpout,"*    11
");continue;}
    if(ch==''/'') {fprintf(fpout,"/     12
");continue;}
    if(ch==''('') {fprintf(fpout,"(    13
");continue;}
    if(ch=='')'') {fprintf(fpout,")    14
");continue;}
    if(ch==''.'') {fprintf(fpout,".    22
");continue;}
    if(ch=='','') {fprintf(fpout,",    23
");continue;}
    if(ch==''#'') break;//分析结束
    else fprintf(fpout,"error in compileing %d lines unknown character %c
",lineno,ch);//出错了,输出出错信息
    }
  }
}
其他请看源代码,注释很详细,但是肯定有不足的地方,请大家吝赐教。有什么问题,可以给我发邮件。这是我第一次向VC知识库投稿,以后将会陆续写一些VC方面的程序来和大家共享。我的email:brilliant_zhang@21cn.com,QQ:110902663, 谢谢大家。

  • 上一篇文章:
  • 下一篇文章:
  • 热门文章
    Olldbg常见问题
    汇编语言的艺术(组合语言的艺术)--观
    汇编语言的艺术(组合语言的艺术)--准
    汇编语言的艺术(组合语言的艺术)--基
    汇编语言的艺术(组合语言的艺术)--基
    汇编语言---程式设计 (4)
    虚拟8086模式
    SYS命令使用说明
    javascript + CSS 实现动态菜单显
    推荐文章
    自制Windows XP SP2自动安装光盘
    SQLServer注入工具改进版 v1.02
    使用photoshop CS进行自然美肤
    Photoshop绘制诺基亚手机
    PHOTOSHOP制作秋日之梦
    PHOTOSHOP鼠绘名模王爱萍
    Photoshop制作晶莹飞溅的水珠
    教你用PHOTOSHOP做放大镜
    鼠绘美女及服装修画全过程