📄 scan.c
字号:
#include "scan.h"
#include "globals.h"
#include "stdio.h"
void Do_Tag(char *strSource);
void Do_Digit(char *strSource);
void Do_NDigit(char *strSource);
void Do_EndOfTag(char *strSource);
void Do_EndOfDigit(char *strSource);
void Do_EndOfEqual(char *strSource);
void Do_EndOfPlus(char *strSource);
void Do_EndOfSubtraction(char *strSource);
void Do_EndOfMutiply(char *strSource);
void Do_EndOfDivide(char *strSource);
void Do_EndOfLParen(char *strSource);
void Do_EndOfRParen(char *strSource);
void Do_EndOfLeftBracket1(char *strSource);
void Do_EndOfRightBracket1(char *strSource);
void Do_EndOfLeftBracket2(char *strSource);
void Do_EndOfRihtBracket2(char *strSource);
void Do_EndOfColon(char *strSource);
void Do_EndOfComma(char *strSource);
void Do_EndOfSemicolon(char *strSource);
void Do_EndOfMore(char *strSource);
void Do_EndOfLess(char *strSource);
void Do_EndOfEnd(char *strSource);
void PrintError(int nColumn,int nRow,char chInput);
void Scaner(void);
char *strSource; char a;
FILE *fw;
FILE *inpute_file;
int gnColumn,gnRow,gnLocate,gnLocateStart;
Word uWord;
char *KEY_WORDS[20]={"main","int","char","if","else","for","while","void","float","long",_KEY_WORD_END};
int IsDigit(char chInput)
{
if(chInput <= '9' && chInput >= '0') return 1;
else return 0;
}
int IsChar(char chInput)
{
if((chInput <= 'z' && chInput >= 'a') || (chInput <= 'Z' && chInput >= 'A')) return 1;
else return 0;
}
void Do_Start(char *strSource)
{
gnLocateStart = gnLocate;
switch(strSource[gnLocate]){
case'+': Do_EndOfPlus(strSource); break;
case'-':
{ if ( strSource[gnLocate-1]=='=' || strSource[gnLocate-1]=='(')
{
gnLocate++;
gnRow++;
uWord.value.T2 = -(strSource[gnLocate]-'0');
Do_NDigit(strSource);
break;
}
else Do_EndOfSubtraction(strSource); break;
}
case'*': Do_EndOfMutiply(strSource); break;
case'/':
{
if( strSource[gnLocate+1] == '*')
{
int j=0;
uWord.value.T1[j++]='/';
uWord.value.T1[j++]='*';
gnLocate+=2;
gnRow+=2;
do
{
printf("%c",strSource[gnLocate]);
uWord.value.T1[j++]=strSource[gnLocate++];
gnRow++;
}while (!((strSource[gnLocate]=='*') && (strSource[gnLocate+1]=='/')));
uWord.value.T1[j++]='*';
uWord.value.T1[j++]='/';
uWord.value.T1[j++]='\0';
uWord.syn=1122;
gnLocate+=2;
gnRow+=2;
break;
}
else Do_EndOfDivide(strSource); break;
}
case'(': Do_EndOfLParen(strSource); break;
case')': Do_EndOfRParen(strSource); break;
case'[': Do_EndOfLeftBracket1(strSource); break;
case']': Do_EndOfRightBracket1(strSource); break;
case'{': Do_EndOfLeftBracket2(strSource); break;
case'}': Do_EndOfLeftBracket2(strSource); break;
case':': Do_EndOfColon(strSource); break;
case',': Do_EndOfComma(strSource); break;
case';': Do_EndOfSemicolon(strSource); break;
case'>': Do_EndOfMore(strSource); break;
case'<': Do_EndOfLess(strSource); break;
case'=': Do_EndOfEqual(strSource); break;
case'\0': Do_EndOfEnd(strSource); break;
default:
if(IsChar(strSource[gnLocate])){
Do_Tag(strSource);
}
else if (IsDigit(strSource[gnLocate])){ uWord.value.T2 = strSource[gnLocate]-'0';
Do_Digit(strSource);
}
else{
if(strSource[gnLocate] != '\n' &&
strSource[gnLocate] != '\t' &&
strSource[gnLocate] != '\r' &&
strSource[gnLocate] != ' ' ){
PrintError( gnColumn, gnRow,strSource[gnLocate]);
}
if (strSource[gnLocate] == '\n' || strSource[gnLocate] != '\r'){
gnColumn++;
gnRow=1;
}
else if (strSource[gnLocate] != '\t'){
gnColumn += _TAB_LEGNTH;
}
else gnRow++;
gnLocate++;
Do_Start(strSource);
}
break;
}
return;
}
void Do_Tag(char *strSource) /* 识别标示符的中间状态 */
{
gnLocate++;
gnRow++;
if (IsChar(strSource[gnLocate])||IsDigit(strSource[gnLocate])){
Do_Tag(strSource);
}
else Do_EndOfTag(strSource);
return;
}
void Do_Digit(char *strSource) /* 识别整数的中间状态 */
{
gnLocate++;
gnRow++;
if (IsDigit(strSource[gnLocate])){
uWord.value.T2=uWord.value.T2*10+strSource[gnLocate]-'0';
Do_Digit(strSource);
}
else Do_EndOfDigit(strSource);
return;
}
void Do_NDigit(char *strSource) /* 识别整数的中间状态 */
{
gnLocate++;
gnRow++;
if (IsDigit(strSource[gnLocate])){
uWord.value.T2=uWord.value.T2*10-(strSource[gnLocate]-'0');
Do_NDigit(strSource);
}
else Do_EndOfDigit(strSource);
return;
}
void Do_EndOfTag(char *strSource) /* 标示符的最后状态 */
{
int nLoop;
uWord.syn=_SYN_ID;
strncpy(uWord.value.T1,strSource+gnLocateStart,gnLocate-gnLocateStart);
uWord.value.T1[gnLocate-gnLocateStart]='\0';
nLoop=0;
while(strcmp(KEY_WORDS[nLoop],_KEY_WORD_END)) {
if (!strcmp(KEY_WORDS[nLoop],uWord.value.T1)) {
uWord.syn=nLoop+1;
break;
}
nLoop++;
}
return;
}
void Do_EndOfDigit(char *strSource) /* 识别数字的最后状态 */
{
uWord.syn=_SYN_NUM;
return;
}
void Do_EndOfEqual(char *strSource) /* = */
{
if (strSource[gnLocate+1]!='='){
uWord.syn=_SYN_ASSIGN;
uWord.value.T3=strSource[gnLocate];
}
else{
gnLocate++;
gnRow++;
uWord.syn=_SYN_EQ;
strcpy(uWord.value.T1,"==");
}
gnLocate++;
gnRow++;
return;
}
void Do_EndOfPlus(char *strSource) /* + */
{
uWord.syn=_SYN_PLUS;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfSubtraction(char *strSource) /* - */
{
uWord.syn=_SYN_MINUS;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfMutiply(char *strSource) /* * */
{
uWord.syn=_SYN_TIMES;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfDivide(char *strSource) /* / */
{
uWord.syn=_SYN_DIVIDE;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfLParen(char *strSource) /* ( */
{
uWord.syn=_SYN_LPAREN;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfRParen(char *strSource) /* ) */
{
uWord.syn=_SYN_RPAREN;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfLeftBracket1(char *strSource) /* [ */
{
uWord.syn=_SYN_LEFTBRACKET1;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfRightBracket1(char *strSource) /* ] */
{
uWord.syn=_SYN_RIGHTBRACKET1;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfLeftBracket2(char *strSource) /* { */
{
uWord.syn=_SYN_LEFTBRACKET2;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfRightBracket2(char *strSource) /* } */
{
uWord.syn=_SYN_RIGHTBRACKET2;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfColon(char *strSource) /* : */
{
uWord.syn=_SYN_COLON;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfComma(char *strSource) /* , */
{
uWord.syn=_SYN_COMMA;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfSemicolon(char *strSource) /* ; */
{
uWord.syn=_SYN_SEMICOLON;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfMore(char *strSource) /* >= */
{
if (strSource[gnLocate+1]!='='){ /* > */
uWord.syn=_SYN_LG;
uWord.value.T3=strSource[gnLocate];
}
else{ /* >= */
gnLocate++;
gnRow++;
uWord.syn=_SYN_ME;
strcpy(uWord.value.T1,">=");
}
gnLocate++;
gnRow++;
return;
}
void Do_EndOfLess(char *strSource) /* <= */
{
if (strSource[gnLocate+1]!='='){ /* < */
uWord.syn=_SYN_LT;
uWord.value.T3=strSource[gnLocate];
}
else{ /* <= */
gnLocate++;
gnRow++;
uWord.syn=_SYN_LE;
strcpy(uWord.value.T1,"<=");
}
gnLocate++;
gnRow++;
return;
}
void Do_EndOfEnd(char *strSource) /* 读到/0,源文件结束 */
{
uWord.syn=_SYN_END;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void PrintWord(Word uWord) /* 打印二元组 */
{
if (uWord.syn<=_SYN_ID || uWord.syn==_SYN_ME || uWord.syn==_SYN_LE || uWord.syn==_SYN_EQ || uWord.syn==1122) {
fprintf(fw,"\n(%d,\t%s)",uWord.syn,uWord.value.T1);
}
else if (uWord.syn==_SYN_NUM) {
fprintf(fw,"\n(%d,\t%d)",uWord.syn,uWord.value.T2);
}
else{
fprintf(fw,"\n(%d,\t%c)",uWord.syn,uWord.value.T3);
}
return;
}
void ApartWord(char *strSource) /* 根据输入的程序识别所有的单词 */
{
gnColumn=gnRow=1;
gnLocate=gnLocateStart=0;
printf("%s",strSource);
while (strSource[gnLocate]) {
printf("%c",strSource[gnLocate]);
Scaner();
}
return;
}
void Scaner(void) /* 词法扫描函数 */
{
Do_Start(strSource);
PrintWord(uWord);
return;
}
void PrintError (int nColumn, int nRow, char chInput) /* 打印词法发现的错误 */
{
fprintf(fw,"\nError-->Col:%d\t Row:%d\t Char:%c",nColumn,nRow,chInput);
}
int main()
{
char input_array[255];
char content;
char filename[20];
int p=0;
if((fw=fopen("result.txt","w+"))==NULL)
{
printf("file open error");
exit(0);
}
printf("Enter filename:");
scanf("%s",filename);
if((inpute_file=fopen(filename,"r"))==NULL)
{
printf("file open error");
getchar();
exit(0);
}
while ((content = fgetc(inpute_file)) != EOF){
input_array[p++]=content;
}
input_array[p]='\0';
fclose(inpute_file);
strSource = input_array;
ApartWord(strSource);
fclose(fw);
getchar();
/*getchar(); */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -