BKHM的专栏

坚持就是胜利!

关于简单c的词法分析器

这段源码能在linux下运行!!! 能识别小数

 

#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
/*#define  NULL          0*/

/*    自定义变量      */
#define  sy_if         0
#define  sy_then       1
#define  sy_else       2
#define  sy_while      3
#define  sy_begin      4
#define  sy_do         5
#define  sy_end        6
#define  a             7
#define  semicolon     8
#define  e             9
#define  jinghao       10
#define  S             11
#define  L             12

#define  tempsy        15
#define  EA            18    /*E end*/
#define  EO            19    /*E or*/

#define  plus          34
#define  times         36
#define  becomes       38
#define  op_and        39
#define  op_or         40
#define  op_not        41
#define  rop           42

#define  lparent       48     //左括号
#define  rparent       49    //有括号
#define  ident         56     //变量
#define  intconst      57 

char ch='/0';  /*存储读入当前字符*/
int count=0;        //词法分析缓冲结果数
int count1=0;
static  char spelling[10]={""};    /*存放识别的字*/
static  char line[81]={""};        /*读入一行字符到缓冲区*/
char *pline;    /*字符缓冲区指针*/

/*struct array{
        int sy11;
        int pos11;
         }A[100]      cunfangcifajieguo*/

static char ntab1[100][10];  /*存放变量表*/

struct rwords{
        char sp[10];
        int  sy;    };   /*存放保留字,sp为保留字,sy为保留字种别*/

struct rwords reswords[10]={    {"if",sy_if},
                                {"do",sy_do},
                                {"else",sy_else},
                                {"while",sy_while},
                                {"then",sy_then},
                                {"begin",sy_begin},
                                {"end",sy_end},
                                {"and",op_and},
                                {"or",op_or},
                                {"not",op_not}  };

struct aa{   int sy1;     //种别
             int pos;     /*内码值*/
            }buf[1000];  /*词法分析结果的缓冲区  源程序*/

int nlength=0;  /*记录变量表的长度*/

int lnum=0;  /*源程序长度*/

int tt1=0;   /*变量表的起始位置*/
FILE *cfile;
FILE *mfile;

/*从文件读一行到缓冲区*/
void readline()
{
   char ch1;
   pline=line;
   ch1=getchar(cfile); //windows
  // ch1 = fgetc(cfile);          // Linux
   while(ch1!='/n')
   {   *pline=ch1;
       pline++;
       ch1=getchar(cfile);   // Windows
       //ch1 = fgetc(cfile);    // linux
   }
   *pline='/0';
   pline=line;
}                       /* read a line in the buffer */

/*从缓冲区读一个字符*/
void readch()
{  if(ch=='/0')
   {   readline();
       lnum++;
    }
    ch=*pline;
    pline++;
}                     /* read a char from buffer */

/*识别(标识符)字符串是否已收录进变量表 :若不存在就返回-1 反之 */
int find(char spel[])
{
    int ss1=0;
    int ii=0;
    while((ss1==0)&&(ii<nlength))
    {  if(!strcmp(spel,ntab1[ii]))
          ss1=1;
       ii++;   //顺序执行
    }
    if(ss1==1) return ii-1;
    else return-1;
}

// 识别标识符
void identifier()
{  int iii=0,j,k;
   int ss=0;
   k=0;
   do   //只识别了小写字母 和 数字
   {  spelling[k]=ch;
      k++;
      readch();
   }while(((ch>='a')&&(ch<='z'))||((ch>='0')&&(ch<='9')));
   pline--;                 // 回退
   spelling[k]='/0';       // 由于do while 中 k已加了一个  1  所以这里用'/0'做结束符
   while((ss==0)&&(iii<10))    //确认是否在保留字中(查找)
     {  if(!strcmp(spelling,reswords[iii].sp)) //strcmp相等或小于 返回 0
  ss=1;   // 如果能找到保留字 则ss值变 1 ,跳出循环
      iii++;
   }
          /* guanjianzipipei*/
   if(ss==1)   //若为保留字         
   {    buf[count].sy1=reswords[iii-1].sy;   //把保留字放在分析结果缓冲区
   }
   else
   {  buf[count].sy1=ident;     //标识符的种别
      j=find(spelling);
      if(j==-1)            //若不存在
      {  buf[count].pos=tt1;   //这里用变量在变量表的位置 来标记内码值
         strcpy(ntab1[tt1],spelling); //复制
         tt1++;                  //位置加一
         nlength++;              // 变量表的长度加一
      }
      else buf[count].pos=j;  // 若已存在这样的变量 ,内码值为 第一个出现的变量的位置
   }
   count++;            //词法分析缓冲结果数 加一
   for(k=0;k<10;k++)  spelling[k]=' ';  //清空
}               /*shuzideshibie*/
/*
void number()  // 识别常数
{   int ivalue=0;
    int digit;
    // 字符转换为数字
 do
    {  digit=ch-'0';       // [0-9]的大小
       ivalue=ivalue*10+digit;   //常数的值
       readch();                  // 读下一个字符
    }while((ch>='0')&&(ch<='9')); 
    buf[count].sy1=intconst;   //常数的种别
    buf[count].pos=ivalue;      // 常数值
    count++; 
    pline--; // 回退
}            
*/

void number()
{ float invalue = 0.0,index = 0.0,digit = 0.0;
  int flag = 0;
    do
    { 
      if((ch == '.')&&(flag = 0))
 {
   flag++;
   readch();
   continue;
 }
      if((ch >= '0')&&(ch <= '9'))
 {
   if(flag)
     {
       index = index*0.1;
       digit = ch - '0';
       invalue = invalue + digit*index;
     }
   else
     {
       digit = ch - '0';
       invalue = invalue*10 + digit;
     }
 }
      readch();
    }while(((ch >= '0')&&(ch <= '9'))||(ch == '.'));
  buf[count].sy1 = intconst;
  buf[count].pos = invalue;
  count++;
  pline--;
}

//扫描主函数
void scan()
{
   while(ch!='~')
   {  switch(ch)
      {  case' ':break;
         case'a':
         case'b':
         case'c':
         case'd':
         case'e':
         case'f':
         case'g':
         case'h':
         case'i':
         case'j':
         case'k':
         case'l':
         case'm':
         case'n':
         case'o':
         case'p':
         case'q':
         case'r':
         case's':
         case't':
         case'u':
         case'v':
         case'w':
         case'x':
         case'y':
         case'z':
         identifier();
         break;
         case'0':
         case'1':
         case'2':
         case'3':
         case'4':
         case'5':
         case'6':
         case'7':
         case'8':
         case'9':
         number();
         break;
         case'<':
         readch();
         if(ch=='=')
            buf[count].pos=0;
         else
         {  if(ch=='>')buf[count].pos=4;
            else
            {  buf[count].pos=1;
               pline--;
            }
         }
         buf[count].sy1=rop;
         count++;
         break;
         case'>':
         readch();
         if(ch=='=')
         {  buf[count].pos=2;
         }
         else
         {  buf[count].pos=3;
            pline--;
         }
         buf[count].sy1=rop;
         count++;
         break;
         case'(':
         buf[count].sy1=lparent;
         count++;
         break;
         case')':
         buf[count].sy1=rparent;
         count++;
         break;
         case'#':
         buf[count].sy1=jinghao;
         count++;
         break;
         case'+':
         buf[count].sy1=plus;
         count++;
         break;
         case'*':
         buf[count].sy1=times;
         count++;
         break;
         case':':
         readch();
         if(ch=='=')
         buf[count].sy1=becomes;
         count++;
         break;
         case'=':
         buf[count].sy1=rop;
         buf[count].pos=5;
         count++;
         break;
         case';':
         buf[count].sy1=semicolon;
         count++;
         break;
      }
   readch();
   }
   buf[count].sy1=-1;
   buf[count].pos=-1;
}

void disp1()
{  int temp1=0;
   printf("/n*********cifafenxijieguo**********/n");
   for(temp1=0;temp1<=count;temp1++)
   {
      printf("%d/t%d/n",buf[temp1].sy1,buf[temp1].pos);
      if(temp1==20)
      {  printf("Press any key to continue..../n");
         getchar();
      }
   }
   getchar();
}

void disp4()

{  int temp1=0;
   mfile=fopen("cf.txt","w");
   printf("/n******zidongshenchengwenjian*****/n");
   for(temp1=0;temp1<count;temp1++)
       fprintf(mfile,"%d/t%d/n",buf[temp1].sy1,buf[temp1].pos);
   fprintf(mfile,"~/n");
}


void disp3()
{
   int tttt;
   mfile=fopen("bl.txt","w");
   printf("/n/n%d,%d/n",lnum,count);
   getchar();
   printf("/n*********bianliaangbiao**********/n");
   for(tttt=0;tttt<tt1;tttt++)
   {   printf("%d/t%s/n",tttt,ntab1[tttt]);
       fprintf(mfile,"%d/t%s/n",tttt,ntab1[tttt]);
   }
   fprintf(mfile,"~/n");
   getchar();
}

int main()
{
   if((cfile=fopen("2.txt","r"))!=NULL)
      printf("open/n");
   else
      printf("close/n");
   readch();
      printf("%c/n",ch);
   scan();
   disp1();
   disp4();
   disp3();
   return 0;
}

阅读更多
个人分类: 编译原理
想对作者说点什么? 我来说一句

java语言写的简单词法分析器

2014年12月02日 8KB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭