📄 compiler.cpp
字号:
case INCHAR:
if (isalnum(c))
{ int c1=scanner::getNextChar(source);
if (c1 =='\'')
{ save = TRUE;
state = DONE;
currentToken.Lex = CHARC;
}
else
{ scanner::ungetNextChar();
scanner::ungetNextChar();
state = DONE;
currentToken.Lex = ERROR;
Error = TRUE;
}
}
else
{ scanner::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))
{
scanner::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 */
cout<<"Scanner Bug: state="<<state<<endl;
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 = scanner::reservedLookup(tokenString);
if (currentToken.Lex != ID)
strcpy(tokenString,tokenString);
}
}
}
/**************** 循环处理结束 ********************/
/*将行号信息存入Token*/
currentToken.lineshow = lineno;
/*将单词的语义信息存入Token*/
switch (currentToken.Lex)
{
/* 单词tokenString为保留字,将保留字词元写入currentToken.Sem*/
case PROGRAM:
case PROCEDURE:
case TYPE:
case VAR:
case IF:
case THEN:
case ELSE:
case FI:
case INTEGER:
case CHAR:
case WHILE:
case DO:
case ENDWH:
case BEGIN:
case END:
case READ:
case WRITE:
case ARRAY:
case OF:
case RECORD:
case RETURN:
/* 单词tokenString为特殊符号:*/
case ASSIGN:
case LT:
case EQ:
case LPAREN:
case RPAREN:
case SEMI:
case PLUS:
case MINUS:
case TIMES:
case OVER:
case DOT:
case COMMA:
case LMIDPAREN:
case RMIDPAREN:
case UNDERANGE:
case INTC: //NUM (整型常量)
case CHARC: //字符型常量
case ID: //标识符
case ERROR: //错误
strcpy(currentToken.Sem, tokenString);
break;
/* 簿记单词符号 */
case ENDFILE: //ENDFILE (文件结尾)
strcpy(currentToken.Sem, "EOF");
/* 单词token为其他未知单词,未知信息写入文件listing,此种情况不应发生 */
default:
strcpy(currentToken.Sem, "unkown token");
break;
}
/*将已处理完的当前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赋值给成员变量tokenlist*/
tokenlist=chainHead;
chainHead=NULL;
return tokenlist;
}
/*=========================语法分析==================================*/
/********************************************************************/
/* 函数名 getTree */
/* 功 能 语法分析函数 */
/* 说 明 该函数把词法分析程序作为子程序调用,采用递归下降法 */
/* 根据产生式调用递归处理函数,函数为源程序创建语法分析树 */
/********************************************************************/
TreeNode * compiler::getTree(void)
{
Syntax syn;
ChainNodeType * tokenl=tokenlist;
/* 从文件Tokenlist中取得第一个单词,将词法信息送给token */
syn.setCurrentP(tokenl);
syn.ReadNextToken();
/* 开始调用基本语法分析处理函数,递归下降处理 */
Tree=syn.program();
/* 当前单词token不是ENDFILE,报代码在文件结束前提前结束错误 */
if (syn.getToken().Lex!=ENDFILE)
syn.syntaxError("Code ends before file\n");
/* 函数返回语法树根节点t */
return Tree;
}
/************************************************************/
/* 函数名 getScope() */
/* 功 能 该函数处理总的语义分析 */
/* 说 明 对语法树进行分析,得到符号表头指针 */
/************************************************************/
SymbTable ** compiler::getScope(void)
{
SymbTable * entry= NULL;
TreeNode * p = NULL;
TreeNode * pp = Tree;
TreeNode *t=Tree;
SemAnalyze sem;
/*创建符号表*/
sem.CreatTable();
/*调用类型内部表示初始化函数*/
sem.initialize();
/*语法树的声明节点*/
p=t->child[1];
while (p!=NULL)
{
switch ( p->nodekind )
{ case TypeK: sem.TypeDecPart(p->child[0]); break ;
case VarK : sem.VarDecPart(p->child[0]); break ;
case ProcDecK: sem.procDecPart(p); break ;
default:
sem.ErrorPrompt(p->lineno,"","no this node kind in syntax tree!");
break;
}
p = p->sibling ;/*循环处理*/
}
/*程序体*/
t = t->child[2];
if(t->nodekind==StmLK)
sem.Body(t);
/*撤销符号表*/
if (Level!=-1)
sem.DestroyTable();
/*输出语义错误*/
if(Error==TRUE)
cout<<"\nanalyze error:\n"<<endl;
/*如果无错误,则输出提示信息*/
else
cout<<"\n........ no error!"<<endl;
return sem.returnScope();
}
compiler::~compiler()
{
ChainNodeType *tempNode; /*临时指针,用于释放链表部分*/
/*释放链表*/
while (tokenlist!=NULL)
{
tempNode=tokenlist->nextToken;
delete(tokenlist);
tokenlist=tempNode;
}
tokenlist=NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -