📄 scanner.cpp
字号:
/* 当前字符c为"=",当前识别单词返回值currentToken设置为等号单词EQ */
case '=':
currentToken.Lex = EQ;
break;
/* 当前字符c为"<",当前识别单词返回值currentToken设置为小于单词LT */
case '<':
currentToken.Lex = LT;
break;
/* 当前字符c为"+",当前识别单词返回值currentToken设置为加号单词PLUS */
case '+':
currentToken.Lex = PLUS;
break;
/* 当前字符c为"-",当前识别单词返回值currentToken设置为减号单词MINUS */
case '-':
currentToken.Lex = MINUS;
break;
/* 当前字符c为"*",当前识别单词返回值currentToken设置为乘号单词TIMES */
case '*':
currentToken.Lex = TIMES;
break;
/* 当前字符c为"/",当前识别单词返回值currentToken设置为除号单词OVER */
case '/':
currentToken.Lex = OVER;
break;
/* 当前字符c为"(",当前识别单词返回值currentToken设置为左括号单词LPAREN */
case '(':
currentToken.Lex = LPAREN;
break;
/* 当前字符c为")",当前识别单词返回值currentToken设置为右括号单词RPAREN */
case ')':
currentToken.Lex = RPAREN;
break;
/* 当前字符c为";",当前识别单词返回值currentToken设置为分号单词SEMI */
case ';':
currentToken.Lex = SEMI;
break;
/* 当前字符c为",",当前识别单词返回值currentToken设置为逗号单词COMMA */
case ',':
currentToken.Lex = COMMA;
break;
/* 当前字符c为"[",当前识别单词返回值currentToken设置为左中括号单词LMIDPAREN */
case '[':
currentToken.Lex = LMIDPAREN;
break;
/* 当前字符c为"]",当前识别单词返回值currentToken设置为右中括号单词RMIDPAREN */
case ']':
currentToken.Lex = RMIDPAREN;
break;
/* 当前字符c为其它字符,当前识别单词返回值currentToken设置为错误单词ERROR */
default:
currentToken.Lex = ERROR;
Error = TRUE;
break;
}
}
break;
/********** 当前状态为开始状态START的处理结束 **********/
/* 当前DFA状态state为注释状态INCOMMENT,确定性有限自动机DFA处于注释位置 */
case INCOMMENT:
/* 当前字符存储状态save设置为FALSE,注释中内容不生成单词,无需存储 */
save = FALSE;
/* 当前字符c为EOF,当前DFA状态state设置为完成状态DONE,当前单词识别结束 *
* 当前识别单词返回值currentToken设置为文件结束单词ENDFILE */
if (c == EOF)
{ state = DONE;
currentToken.Lex = ENDFILE;
}
/* 当前字符c为"}",注释结束.当前DFA状态state设置为开始状态START */
else if (c == '}') state = START;
break;
/* 当前DFA状态state为赋值状态INASSIGN,确定性有限自动机DFA处于赋值单词位置 */
case INASSIGN:
/* 当前DFA状态state设置为完成状态DONE,赋值单词结束 */
state = DONE;
/* 当前字符c为"=",当前识别单词返回值currentToken设置为赋值单词ASSIGN */
if (c == '=')
currentToken.Lex = ASSIGN;
/* 当前字符c为其它字符,即":"后不是"=",在输入行缓冲区中回退一个字符 *
* 字符存储状态save设置为FALSE,当前识别单词返回值currentToken设置为ERROR */
else
{
ungetNextChar();
save = FALSE;
currentToken.Lex = ERROR;
Error = TRUE;
}
break;
case INRANGE:
/* 当前DFA状态state设置为完成状态DONE,赋值单词结束 */
state = DONE;
/* 当前字符c为".",当前识别单词返回值currentToken设置为下标界UNDERANGE */
if (c == '.')
currentToken.Lex = UNDERANGE;
/* 当前字符c为其它字符,即"."后不是".",在输入行缓冲区中回退一个字符 *
* 字符存储状态save设置为FALSE,当前识别单词返回值currentToken设置为ERROR */
else
{
ungetNextChar();
save = FALSE;
currentToken.Lex = DOT;
}
break;
/* 当前DFA状态state为数字状态INNUM,确定性有限自动机处于数字单词位置 */
case INNUM:
/* 当前字符c不是数字,则在输入行缓冲区源中回退一个字符 *
* 字符存储标志设置为FALSE,当前DFA状态state设置为DONE,数字单词识别完成 *
* 当前识别单词返回值currentToken设置为数字单词NUM */
if (!isdigit(c))
{
ungetNextChar();
save = FALSE;
state = DONE;
currentToken.Lex = INTC;
}
break;
/*当前DFA状态state为字符标志状态INCHAR,确定有限自动机处于字符标志状态*/
case INCHAR:
if (isalnum(c))
{ int c1=getNextChar();
if (c1 =='\'')
{ save = TRUE;
state = DONE;
currentToken.Lex = CHARC;
}
else
{ ungetNextChar();
ungetNextChar();
state = DONE;
currentToken.Lex = ERROR;
Error = TRUE;
}
}
else
{ ungetNextChar();
state = DONE;
currentToken.Lex = ERROR;
Error = TRUE;
}
break;
/* 当前DFA状态state为标识符状态INID,确定性有限自动机DFA处于标识符单词位置 */
case INID:
/* 当前字符c不是字母,则在输入行缓冲区源中回退一个字符 *
* 字符存储标志设置为FALSE,当前DFA状态state设置为DONE,标识符单词识别完成 *
* 当前识别单词返回值currentToken设置为标识符单词ID */
if (!isalnum(c))
{
ungetNextChar();
save = FALSE;
state = DONE;
currentToken.Lex = ID;
}
break;
/* 当前DFA状态state为完成状态DONE,确定性有限自动机DFA处于单词结束位置 */
case DONE: break;
/* 当前DFA状态state为其它状态,此种情况不应发生 */
default:
/* 将词法扫描器产生错误的状态state写入列表文件listing *
* 当前DFA状态state设置为完成状态DONE *
* 当前识别单词返回值currentToken设置为错误单词ERROR */
fprintf(listing,"Scanner Bug: state= %d\n",state);
Error = TRUE;
state = DONE;
currentToken.Lex = ERROR;
break;
}
/*************** 分类判断处理结束 *******************/
/* 当前字符存储状态save为TRUE,且当前正识别单词已经识别部分未超过单词最大长度 *
* 将当前字符c写入当前正识别单词词元存储区tokenString */
if ((save) && (tokenStringIndex <= MAXTOKENLEN))
tokenString[tokenStringIndex++] = (char) c;
if (state == DONE)
{
/* 当前DFA状态state为完成状态DONE,单词识别完成 *
* 当前识别单词词元存储区tokenString加上结束标志 */
tokenString[tokenStringIndex] = '\0';
/* 当前单词currentToken为标识符单词类型,查看其是否为保留字单词 */
if (currentToken.Lex == ID)
{
currentToken.Lex = reservedLookup(tokenString);
if (currentToken.Lex != ID)
strcpy(tokenString,tokenString);
}
}
}
/**************** 循环处理结束 ********************/
/*将行号信息存入Token*/
currentToken.lineshow = lineno;
/*将单词的语义信息存入Token*/
strcpy(currentToken.Sem , tokenString);
/*将已处理完的当前Token存入链表的Token部分*/
((*currentNode).Token).lineshow=currentToken.lineshow;
((*currentNode).Token).Lex=currentToken.Lex;
strcpy(((*currentNode).Token).Sem,currentToken.Sem);
Tokennum++; /*Token总数目加1*/
/*若不是第一个结点,则将当前结点连入链表*/
if (preNode!=currentNode)
{
preNode->nextToken=currentNode;
preNode=currentNode;
}
/*申请一个新的结点,以记录下一个Token的信息*/
currentNode=(ChainNodeType *)malloc(CHAINNODELEN);
/*初始化这个结点中,指向下一个结点的指针为空*/
currentNode->nextToken=NULL;
}
/* 直到处理完表示文件结束的Token:ENDFILE,说明处理完所有的Token*/
/* 并存入了链表中,循环结束*/
while ((currentToken.Lex)!=ENDFILE);
/*将由chainHead指向的Token链表存入文件"Tokenlist"中*/
ChainToFile(chainHead);
/*释放链表*/
while (chainHead!=NULL)
{
tempNode=chainHead->nextToken;
free(chainHead);
chainHead=tempNode;
}
}
/* 词法分析函数结束 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -