C语言做的词法分析器。。。请教高手
用C语言做的词法分析器,如果要识别浮点数,怎么修改程序啊?请教高手#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <assert.h>
#include "lex.h"
char strToken[30]; //字符数组,存放构成单词符号的字符串。
int lvalue; //单词的内码值
keyword keywords[]={
"switch",$SWITCH,
"case",$CASE,
"if",$IF,
"else",$ELSE,
"do",$DO,
"while",$WHILE,
"stop",$STOP,
"end",$END,
"var",$VAR,
"dim",$DIM,
0,0,
}; //关键字表
symbol ctable[200]; //常数表
symbol vtable[200]; //符号表(标识符)
char inbuf[300]; //扫描缓冲区
int sp; //起点指示器
int ep; //扫描指示器
int lineno; //行计数器
FILE *fsrc;
char GetChar()
{
//从扫描缓冲区中读一个字符,实现双输入缓冲。
//第一个缓冲区从inbuf[0]到inbuf[149],第二个缓冲区从inbuf[150]到inbuf[299],
//每次从源文件读一个缓冲区大小的内容,分析完当前工作缓冲区内容时把源文件读入
//另一个缓冲区,另一个缓冲区成为工作缓冲区
int i = 0;
char ch;
if ((ep == 150)||(ep == 300))
{
ep = ep%300;
while (((inbuf[i+ep]=fgetc(fsrc))!=NULL) && (i<150))
i++;
}
ch = inbuf[ep];
ep++;
return ch;
}
char GetBC()
{
//从扫描缓冲区读字符,过滤空格、制表和回车符号
char ch = GetChar();
while ((ch==' ') || (ch=='\n') || (ch=='\t'))
{
if (ch=='\n')
lineno++;
ch = GetChar();
}
return ch;
}
void Concat(char str[], char ch)
{
//将字符ch添加到符号串str的尾部
str[strlen(str)] = ch;
}
bool isLetter(char ch)
{
//判断ch是否字母
if (((ch>='A')&&(ch<='Z')) || ((ch>='a')&&(ch<='z')))
return true;
return false;
}
bool isDigit(char ch)
{
//判断ch是否数字
if ((ch>='0')&&(ch<='9'))
return true;
return false;
}
int Reserve(char* str)
{
//如str是保留字,返回保留字种别号
//否则返回0
int i = 0;
while (keywords[i].code != 0)
{
if (strcmp(str,keywords[i].name) == 0)
return keywords[i].code;
i++;
}
return 0;
}
void Retract()
{
//从扫描输入缓冲区回退一个字符
if (ep==0)
ep = 299;
else
ep--;
}
int InsertID(char *str)
{
//如符号表中已有str标识符,返回记录号,
//否则将str加到符号表中,返回记录号
int i = 0;
while ((vtable[i].number!=0) && (i<200))
{
if (strcmp(str,vtable[i].name) == 0)
return vtable[i].number;
i++;
}
if (i<200)
{
vtable[i].number = i+1;
strcpy(vtable[i].name, str);
return vtable[i].number;
}
return 0;
}
int InsertConst(char *str)
{
//如常数表中已有str常数,返回记录号,
//否则将str加到常数表中,返回记录号
int i = 0;
while ((ctable[i].number!=0) && (i<200))
{
if (strcmp(str,ctable[i].name) == 0)
return ctable[i].number;
i++;
}
if (i<200)
{
ctable[i].number = i+1;
strcpy(ctable[i].name, str);
return ctable[i].number;
}
return 0;
}
void ProcError()
{
printf("%i 行有错误\n", lineno);
}
int Lex()
{
//从扫描缓冲区中识别出一个单词,返回单词种别号,
//构成的单词的符号串保留在strToken中,
//单词的值保留在lvalue中。strToken和lvalue为全局变量。
int code;
char ch;
memset(strToken, 0, 30);
ch = GetBC();
sp = ep-1;
lvalue = 0;
if (isLetter(ch))
{
while (isLetter(ch) || isDigit(ch))
{
Concat(strToken, ch);
ch = GetChar();
}
Retract();
code = Reserve(strToken);
if (code == 0)
{
lvalue = InsertID(strToken);
return $ID;
}
return code;
}
else if (isDigit(ch))
{
while (isDigit(ch))
{
Concat(strToken, ch);ch = GetChar();
}
Retract();
lvalue = InsertConst(strToken);
return $INT;
}
else if (ch == '=')
{
ch = GetChar();
if (ch == '=')
return $EQ;
Retract();
return $ASSIGN;
}
else if (ch == '+') return $PLUS;
else if (ch == ';') return $SEMICOLON;
else if (ch == '(') return $LPAR;
else if (ch == ')') return $RPAR;
else if (ch == '{') return $LBRACE;
else if (ch == '}') return $RBRACE;
else if (ch == '*')
{
ch = GetChar();
if (ch == '*')
return $POWER;
Retract();
return $STAR;
}
else if (ch == EOF) return $END;
else
{
ProcError();
return $END;
}
}
void main()
{
token aToken;
int i = 0;
char strName[256];
FILE *fcon = fopen("const.txt","w+");
FILE *ftoken = fopen("token.txt","w+");
FILE *fsym = fopen("symbol.txt","w+");
printf("请输入源文件名(enter结束):\n");
scanf("%s",strName);
fsrc = fopen(strName,"r");
if (fsrc == NULL)
{
printf("找不到源文件src.txt\n");
exit(1);
}
if ((ftoken == NULL) || (fcon == NULL) || \
(fsym == NULL))
{
printf("不能创建输出文件const.txt,token.txt,symbol.txt\n");
exit(1);
}
/*读源文件入缓冲区*/
while ((i<150) && ((inbuf[i]=fgetc(fsrc)) != EOF))
i++;
/*词法分析开始*/
ep = 0;
lineno = 1;
aToken.label = 0;
aToken.code = Lex();
aToken.addr = lvalue;
printf("单词序列:\n");
while (aToken.code != $END)
{
//单词输出到文件
fprintf(ftoken, "(%3d,%3d)", aToken.code, aToken.addr);
//单词输出到屏幕
printf("(%3d,%3d) ", aToken.code, aToken.addr);
aToken.label++;
aToken.code = Lex();
aToken.addr = lvalue;
}
/*词法分析结束,输出符号表和常数表到symbol.txt、const.txt文件并显示在屏幕*/
i = 0;
printf("\n符号表:\n");
while (vtable[i].number != 0)
{
fprintf(fsym, "(%3d,%s)", vtable[i].number, vtable[i].name);
printf("(%3d,%s)", vtable[i].number, vtable[i].name);
i++;
}
i = 0;
printf("\n常数表:\n");
while (ctable[i].number != 0)
{
fprintf(fcon, "(%3d,%s)", ctable[i].number, ctable[i].name);
printf("(%3d,%s)", ctable[i].number, ctable[i].name);
i++;
}
fclose(fsrc);
fclose(fsym);
fclose(fcon);
fclose(ftoken);
printf("\n词法分析结束,按任意键\n");
getch();
}