首页 > 代码库 > 词法分析器:代码注释

词法分析器:代码注释

前沿:词法分析器是将一段程序的代码按照类别分开.
一般来说是将关键字, 变量名  , 常数 运算符( + _ * / )和界符分类
词法分析算是编译的基础把
今天上编译原理的实验课, 看了看  老师给的代码 添加了一些注释
大致的流程是这样的:
规定关键字的符号是10
数字的符号是数字本身
+ - *  = 这些符号代码中的case里面有(分别是13 14 ...),可以看懂的
首先, 把程序存到制定的内存区域, 这里是划出了一个连续的空间(放到字符数组);
然后再按字节读取里面的内容 , 当读到空格(" ")或者是换行符号(\n)的时候,就默认是一个单词啦,()
把这个单词放进一个另外一个数组里面,美其名曰token[];
获得这个token之后 ,
首先判断token中的每一个字符是不是属于a-z的字符里面(需要一个while循环遍历)
如果在读取的字符不是一个字母, 那在看看是不是数字(0-9),如果是的话,那就写成相应的标识符
如果读取的是+ 那么将syn(表示代号)为13
每次识别出来之后,都以 ("syn " , string )的形式输出
/**C语言的词法分析
**/
#include<stdio.h>
#include<string.h>

/**

程序规定:
1、关键字:"function","if","then","while","do","endfunc";
2、算术运算符:"+","-","*","/","=";
3、关系运算符:"<" ">" "<=" ">=" "==" "!=";
4、界符:"("  ")"   ";"   "#";
5、标识符规定以字母开头,字母均为小写;
6、空格和换行符跳过;

  **/
char prog[80];//把所有内容放进这个数组里面
char token[8];//存放每次的读取 的 单词
char ch;//  每次读取的 单词的字符的
int syn;//记录编码方式
int p;//指向 要读数字的下标
int m;
int n;
int sum;//求取数字的和
char * rwtab[6]={"function","if","then","while","do","endfunc"};// 关键字
void scaner();//函数 声明
void main(void)//
{
p=0;
printf("\n please input string:\n");
do///当读取字符#的时候代表结束,把输入的字符存储到数组里  ....
{
  scanf("%c",&ch);
  prog[++p]=ch;
}
while(ch!=‘#‘);

p=0;
do
{
  scaner();
  switch(syn)
  {
   case 11:printf("\n(%d,%d)",syn,sum);break;
   case -1:printf("\nerror");break;
   default:printf("\n(%d,%s)",syn,token);
  }
}
while(syn!=0);
}

void scaner()
{
for(n=0;n<8;n++)
  token[n]=NULL;////清空 token数组

  ch=prog[++p];//读取 prog 中 的 字符串的字符
    while(ch==‘\n‘ || ch==‘ ‘) //当读到 换行和空格的时候 说明字符已经结束或者是这个单词已经写完 开始把下一个读取的单词放入 prog中:缓冲区 :80个字符 存放的全是空格和换行符
  ch=prog[++p];

if(ch>=‘a‘&&ch<=‘z‘)//如果读取的 字符是一个小写字母
{
  m=0;
  while(ch>=‘a‘&&ch<=‘z‘)//把每次从 prog中 读取的字母 读取到 token中
  {
   token[m++]=ch;
   ch=prog[++p];
  }

  token[m]=‘\0‘;//C中的字符结束符号
  ch=prog[--p];//???????
  syn=10;//?????????
  for(n=0;n<6;n++)//检查是否含有关键字 ,如果有的话 ,
   if(strcmp(token,rwtab[n])==0)//    strcmp()函数,自左向右的按ASCII值比较 , 相等话是=0;
   {
    syn=n+1;//如果是关键字的话 +1??
    break;
   }
}
else //如果ch 不在 字符集中...
  if(ch>=‘0‘&&ch<=‘9‘)//考察是否在0-9的数字中
  {
   sum=0;
   while(ch>=‘0‘&&ch<=‘9‘)//
   {
    sum=sum*10+ch-‘0‘;//讲数字形式的字符从数字转化成 数字形式
    ch=prog[++p];//读取下一个数字
   }
   ch=prog[--p];//>因为前面是++,这里要--
   syn=11;
  }
else//如果既不在数字 也不在字母中的话.....
  switch(ch)
   {
    case ‘<‘:m=0;token[m++]=ch;
    ch=prog[++p];
    if(ch==‘=‘)
     {
      syn=21;
      token[m+1]=ch;
     }
    else
     {
      syn=20;
      ch=prog[--p];
     }
    break;
    case ‘>‘:m=0;token[m++]=ch;
    ch=prog[++p];
    if(ch==‘=‘)
     {
      syn=24;
      token[m++]=ch;
     }
    else
     {
      syn=23;
      ch=prog[--p];
     }
    break;
    case ‘=‘:m=0;token[m++]=ch;
    ch=prog[++p];
    if(ch==‘=‘)
     {
      syn=25;
      token[m++]=ch;
     }
    else
     {
      syn=18;
      ch=prog[--p];
     }
    break;
    case ‘!‘:m=0;token[m++]=ch;
    ch=prog[++p];
    if(ch==‘=‘)
     {
      syn=22;
      token[m++]=ch;
     }
    else
     syn=-1;
    break;
    case ‘+‘:syn=13;token[0]=ch;break;
    case ‘-‘:syn=14;token[0]=ch;break;
    case ‘*‘:syn=15;token[0]=ch;break;
    case ‘/‘:syn=16;token[0]=ch;break;
    case ‘;‘:syn=26;token[0]=ch;break;
    case ‘(‘:syn=27;token[0]=ch;break;
    case ‘)‘:syn=28;token[0]=ch;break;
    case ‘#‘:syn=0;token[0]=ch;break;
    default:syn=-1;
   }
}