一、 词法分析器
词法分析器的任务是清除源文件中多余的空格、换行、制表符等,识别文法符号。按顺序输出识别的标识符及其种别编号,供语法分析器调用。
代码如下:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define BOOL int
#define TRUE 1
#define FALSE 0
#define MAXSIZE 50
typedef char datatype;
typedef struct /*定义缓冲队列*/
{
datatype data[MAXSIZE*2];
int front,rear;
}Queue;
void setnull(Queue *q) /*队列初始化*/
{
q->front = MAXSIZE*2 - 1;
q->rear = MAXSIZE*2 - 1;
}
BOOL empty(Queue *q) /*判队空*/
{
if(q->front==q->rear)
return TRUE;
return FALSE;
}
BOOL full(Queue *q) /*判队满*/
{
if(q->front == (q->rear+1) % (MAXSIZE*2))
return TRUE;
return FALSE;
}
int quantity(Queue *q) /*求队列中元素个数*/
{
int n;
n = q->rear - q->front;
if(n<0)
n += MAXSIZE*2;
return n;
}
datatype front(Queue *q) /*取队头元素*/
{
int n;
if(empty(q))
return 0;
n = (q->front+1) % (MAXSIZE*2);
return q->data[n];
}
BOOL enqueue(Queue *q,datatype x) /*入队*/
{
if(full(q))
return FALSE;
q->rear = ++q->rear % (MAXSIZE*2);
q->data[q->rear]=x;
return TRUE;
}
datatype dequeue(Queue *q) /*出队*/
{
if(empty(q))
return 0;
q->front = ++q->front % (MAXSIZE*2);
return q->data[q->front];
}
char token[MAXSIZE];
char* rwtab[6]={"begin","if","then","while","do","end"};
int syn;
Queue prog;
BOOL letter(char ch) /*判断是否字母*/
{
if(ch>='a'&&ch<='z' || ch>='A'&&ch<='Z')
return TRUE;
return FALSE;
}
BOOL digit(char ch) /*判断是否数字*/
{
if(ch>='0'&&ch<='9')
return TRUE;
return FALSE;
}
void saner() /*扫描器*/
{
int i;
char ch;
for(i=0;i<50;i++)
token[i]=0;
i=0;
do /*去除多余空格、换行及制表符*/
{
ch=dequeue(&prog);
}while(ch==' ' || ch=='\n' || ch=='\t');
if(letter(ch)) /*识别标识符(编号10)*/
{
while(1)
{
token[i++]=ch;
ch=front(&prog);
if(letter(ch) || digit(ch))
dequeue(&prog);
else
break;
}
token[i]='\0';
syn=10;
for(i=0;i<6;i++)
if(!strcmp(token,rwtab[i]))
syn=i+1; /*识别关键字(编号1到6)*/
}
else if(digit(ch)) /*识别无符号整数(编号11)*/
{
while(1)
{
token[i++]=ch;
ch=front(&prog);
if(digit(ch))
dequeue(&prog);
else
break;
}
token[i]='\0';
syn=11;
}
else
switch(ch)
{
case '#': /*识别结束符‘#’(编号0)*/
syn=0;
token[i++]='#';
token[i]='\0';
break;
case '+': /*识别‘+’(编号13)*/
syn=13;
token[i++]='+';
token[i]='\0';
break;
case '-': /*识别‘-’(编号14)*/
syn=14;
token[i++]='-';
token[i]='\0';
break;
case '*': /*识别‘*’(编号15)*/
syn=15;
token[i++]='*';
token[i]='\0';
break;
case '/': /*识别‘/’(编号16)*/
syn=16;
token[i++]='/';
token[i]='\0';
break;
case ':':
token[i++]=':';
ch=front(&prog);
switch(ch)
{
case '=': /*识别‘:=’(编号18)*/
syn=18;
token[i++]='=';
token[i]='\0';
dequeue(&prog);
break;
default: /*识别‘:’(编号17)*/
syn=17;
token[i]='\0';
break;
}
break;
case '<':
token[i++]='<';
ch=front(&prog);
switch(ch)
{
case '>': /*识别‘<>’(编号21)*/
syn=21;
token[i++]='>';
token[i]='\0';
dequeue(&prog);
break;
case '=': /*识别‘<=’(编号22)*/
syn=22;
token[i++]='=';
token[i]='\0';
dequeue(&prog);
break;
default: /*识别‘<’(编号20)*/
syn=20;
token[i]='\0';
break;
}
break;
case '>':
token[i++]='>';
ch=front(&prog);
switch(ch)
{
case '=': /*识别‘>=’(编号24)*/
syn=24;
token[i++]='=';
token[i]='\0';
dequeue(&prog);
break;
default: /*识别‘>’(编号23)*/
syn=23;
token[i]='\0';
break;
}
break;
case '=': /*识别‘=’(编号25)*/
syn=25;
token[i++]='=';
token[i]='\0';
break;
case ';': /*识别‘;’(编号26)*/
syn=26;
token[i++]=';';
token[i]='\0';
break;
case '(': /*识别‘(’(编号27)*/
syn=27;
token[i++]='(';
token[i]='\0';
break;
case ')': /*识别‘)’(编号28)*/
syn=28;
token[i++]=')';
token[i]='\0';
break;
default: /*出错!*/
syn=-1;
break;
}
}
main(int argc,char* argv[])
{
FILE *in,*out;
int i;