📄 scan.cpp
字号:
#include "globals.h" //分析器的词法扫描部分
#include "scan.h"
void Do_Tag(char * strSource); //识别标识符的中间状态
void Do_Digit(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_EndOfMultiply(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_EndOfRightBracket2(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); //用'\0'作为源程序结束
void PrintError(int nColumn, int nRow, char chInput); //词法分析错误输出
void Scaner(void); //词法扫描函数
void scaner(void);
extern char * strSource; //待分析的源程序
extern FILE * fw; //结果输出文件
int gnColumn,
gnRow, //行列号
gnLocate, //下一个字符脚标
gnLocateStart; //下一个单词开始位置
WORD uWord; //Word uWord; 扫描出的单词
char * KEY_WORDS[20] = {"main","int","char","if","else","for",
"while","void","bool","string","this",
"double","public","private","new","true",
"false","print","null","class"}; //_ _KEY
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; //gnLocateStart = gnLocate
switch(strSource[gnLocate]){ //根据第一个字符判断
case '+':Do_EndOfPlus(strSource); break;
case '-':Do_EndOfSubtraction(strSource); break;
case '*':Do_EndOfMultiply(strSource); break;
case '/':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_EndOfRightBracket2(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] != ' '
&& strSource[gnLocate] != '\t'
&& strSource[gnLocate] != '\n'
&& strSource[gnLocate] != '\r')
{
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_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], "class")) //_KEY_WORD_END)){ //查关键字表,是否关键字
{
if(! strcmp(KEY_WORDS[nLoop], uWord.value.T1)) //比较和某关键字相符
{
uWord.syn = nLoop + 1; //设置正确的syn
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_EndOfMultiply(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) //Word uWord 打印二元组
{
if(uWord.syn <= _SYN_ID //关键字、标识符有错误
|| uWord.syn == _SYN_ME //>=
|| uWord.syn == _SYN_LE //<=
|| uWord.syn == _SYN_EQ) //==
{
fprintf(fw,"\n%s\t %d", uWord.value.T1, uWord.syn);
}
else if(uWord.syn == _SYN_NUM) //数字
{
fprintf(fw,"\n%d\t %d", uWord.value.T2, uWord.syn);
}
else //其他符号
{
fprintf(fw,"\n%c\t %d", uWord.value.T3, uWord.syn);
}
return;
}
void ApartWord(char * strSource) //根据输入的源程序识别所有的单词
{
gnColumn = gnRow = 1;
gnLocate = gnLocateStart = 0;
fprintf(fw,"\n词法分析结果:");
fprintf(fw,"\n单词符号 种别码");
while(strSource[gnLocate])
{
Scaner();
}
return;
}
void Scaner(void) //词法扫描函数
{
Do_Start(strSource); //识别出一个单词
PrintWord(uWord); //打印二元组
return;
}
void scaner(void)
{
Do_Start(strSource); //识别出一个单词
// return;
}
void PrintError(int nColumn, int nRow, char chInput)
//打印词法扫描发现的错误
{
fprintf(fw,"\nCol:%d Row:%d :%c", nColumn, nRow, chInput);
fprintf(fw,"(无法识别的单词)");
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -