?? scanner.cpp
字號:
#include "scanner.h"
#define TOKEN_LEN 100 //記號最大長度
unsigned int LineNo; //跟蹤源文件記號
static FILE* InFile; //輸入文件流
static char TokenBuffer[TOKEN_LEN]; //記號字符緩沖
//--------------初始化詞法分析器
extern int InitScanner(const char *FileName)
{
LineNo=1;
InFile=fopen(FileName,"r");
if(InFile!=NULL)return 1;
else return 0;
}
//--------------關(guān)閉詞法分析器
extern void CloseScanner(void)
{
if(InFile!=NULL)
fclose(InFile);
}
//--------------從輸入源程序中讀入一個字符
static char GetChar(void)
{
int Char=getc(InFile);
return toupper(Char);
}
//-------------把預(yù)讀入的字符退回到輸入源程序中
static void BackChar(char Char)
{
if(Char!=EOF)
{
ungetc(Char,InFile);
}
}
//------------加入記號到字符緩沖區(qū)
static void AddCharTokenString(char Char)
{
int TokenLength=strlen(TokenBuffer);
if(TokenLength+1>=sizeof(TokenBuffer))
return ;
TokenBuffer[TokenLength]=Char;
TokenBuffer[TokenLength+1]='\0';
}
//-------------清空記號緩沖區(qū)
static void EmptyTokenString()
{
memset(TokenBuffer,0,TOKEN_LEN);
}
//-------------判斷所給的字符串是否在符號表中
static Token JudgeKeyToken(const char* IDString)
{
int loop;
for(loop=0;loop<sizeof(TokenTab)/sizeof(TokenTab[0]);loop++)
{
if(strcmp(TokenTab[loop].lexeme,IDString)==0)
return TokenTab[loop];
}
Token errortoken;
memset(&errortoken,0,sizeof(Token));
errortoken.type=ERRTOKEN;
return errortoken;
}
//-------------獲取一個記號
extern Token GetToken(void)
{
Token token;
int Char;
memset(&token,0,sizeof(Token));
EmptyTokenString();
token.lexeme=TokenBuffer;
for(;;) //過濾掉源程序中的空格,TAB,回車等,遇到文件結(jié)束符返回空記號
{
Char=GetChar();
if(Char==EOF)
{
token.type=NONTOKEN;
return token;
}
if(Char=='\n')
LineNo ++;
if(!isspace(Char))
break;
} //end of for
AddCharTokenString(Char);
//若不是空格,TAB,回車,文件結(jié)束符等,則先加入到記號的字符緩沖區(qū)中
if(isalpha(Char)) //若char是A-Za-z,則一定是函數(shù),關(guān)鍵字,P1,E等
{
for(;;)
{
Char=GetChar();
if(isalnum(Char))
AddCharTokenString(Char);
else
break;
}
BackChar(Char);
token=JudgeKeyToken(TokenBuffer);
token.lexeme=TokenBuffer;
return token;
}
else if(isdigit(Char)) //若是一個數(shù)字則一定是常量
{
for(;;)
{
Char=GetChar();
if(isdigit(Char))
{
AddCharTokenString(Char);
}
else break;
}
if(Char=='.')
{
AddCharTokenString(Char);
for(;;)
{
Char=GetChar();
if(isdigit(Char))
AddCharTokenString(Char);
else break;
}
}//end of if (Char=='.')
BackChar(Char);
token.type=CONST_ID;
token.value=atof(TokenBuffer);
return token;
}
else //若不是字符和數(shù)字,則一定是運算符或分隔符
{
switch(Char)
{
case ';':token.type=SEMICO;break;
case '(':token.type=L_BRACKET;break;
case ')':token.type=R_BRACKET;break;
case ',':token.type=COMMA;break;
case '+':token.type=PLUS;break;
case '-':
Char=GetChar();
if(Char=='-')
{
while(Char!='\n'&&Char!=EOF)
Char=GetChar();
BackChar(Char);
return GetToken();
}
else
{
BackChar(Char);
token.type=MINUS;
break;
}
case '/':
Char=GetChar();
if(Char=='/')
{
while(Char!='\n'&&Char!=EOF)
Char=GetChar();
BackChar(Char);
return GetToken();
}
else
{
BackChar(Char);
token.type=DIV;
break;
}
case '*':
Char=GetChar();
if(Char=='*')
{
token.type=POWER;
break;
}
else
{
BackChar(Char);
token.type=MUL;
break;
}
default:token.type=ERRTOKEN;break;
}// end of switch
}//end of else(不是字母和數(shù)字,則一定是符號)
return token;
}//end of GetToken
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -