?? analyze.c
字號:
/****************************************************/
/* File: analyze.c */
/* Semantic analyzer implementation */
/* for the C_Minus compiler */
/****************************************************/
#include "globals.h"
#include "symtab.h"
#include "analyze.h"
static int location=0;
/* procedure traverse is a generic recursive
* syntax tree traversal routine:
* it applies preProc in preorder and postProc
* in postorder to tree pointed to by t
*/
static void traverse(TreeNode * t, void (* preProc) (TreeNode *),
void (* postProc) (TreeNode *))
{
if (t != NULL)
{
preProc(t);
{int i;
for (i=0; i < MAXCHILDREN; i++)
traverse(t->child[i], preProc, postProc);
}
postProc(t);
traverse(t->sibling, preProc, postProc);
}
}
/* nullProc is a do-nothing procedure to
* generate preorder-only or postorder-only
* traversals from traverse
*/
static void nullProc(TreeNode *t)
{if(t==NULL) return ;
else return;
}
/* procedure insertNode inserts
* identifiers stored in t into
* the symbol table
*/
static void insertNode(TreeNode * t)
{
switch (t->nodekind)
{
case StmtK:
switch (t->kind.stmt)
{
case AssignK:
case ReadK:
if (st_lookup(t->attr.name) ==-1)
st_insert(t->attr.name,t->lineno,location++);
else
st_insert(t->attr.name,t->lineno,0);
break;
default:
break;
}
break;
case ExpK:
switch(t->kind.exp)
{ case IdK:
if(st_lookup(t->attr.name)==-1)
st_insert(t->attr.name,t->lineno,location++);
else
st_insert(t->attr.name,t->lineno,0);
break;
default:
break;
}
break;
default:
break;
}
}
/* function buildSymtab constructs the symbol
* table by preorder traversal of the syntax tree
*/
void buildSymtab(TreeNode * syntaxTree)
{ traverse(syntaxTree,insertNode,nullProc);
fprintf(listing,"\nSymbol table:\n\n");
printSymTab(listing);
}
static void typeError(TreeNode * t, char * message)
{
fprintf(listing,"Type error at line %d: %s\n", t->lineno, message);
Error = TRUE;
}
/* procedure checkNode performs
* type checking at a single tree node
*/
static void checkNode(TreeNode * t)
{
switch (t->nodekind)
{
case ExpK:
switch (t->kind.exp)
{case OpK:
if((t->child[0]->type!=Integer)||(t->child[1]->type!=Integer))
typeError(t,"Op applide to non-integer");
if((t->attr.op==EQ)||(t->attr.op==LT))
t->type=Boolean;
else
t->type=Integer;
break;
case ConstK:
case IdK:
t->type=Integer;
break;
default:
break;
}
break;
case StmtK:
switch(t->kind.stmt)
{ case IfK:
if(t->child[0]->type==Integer)
typeError(t->child[0],"if test is not Boolean");
break;
case AssignK:
if(t->child[0]->type!=Integer)
typeError(t->child[0],"assignment of non-integer value");
break;
case WriteK:
if(t->child[0]->type!=Integer)
typeError(t->child[0],"write of non -integer value");
break;
case RepeatK:
if(t->child[0]->type==Integer)
typeError(t->child[1],"repeat test is no Boolean");
break;
default:
break;
}
break;
default:
break;
}
}
void typeCheck(TreeNode *syntaxTree)
{
traverse(syntaxTree,nullProc,checkNode);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -