?? analyze.c
字號:
/****************************************************/
/* 文件: analyze.c */
/* 語義分析代碼實現 */
/****************************************************/
#include "globals.h"
#include "symtab.h"
#include "analyze.h"
/* 變量內存位置計數器counter for variable memory locations */
static int location = 0;
/* 函數traverse是一個通用的遞歸訪問語法樹函數
* 他通過調用preProc函數來實現前序遍歷;
* 調用函數postProc實現后序遍歷
*/
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是一個什么都不做的函數,
* 目的是產生單前敘或者單后序遍歷的遍歷過程
*/
static void nullProc(TreeNode * t)
{ if (t==NULL) return;
else return;
}
/* 函數insertNode把在t(語法樹)中存儲的節點插入符號表
*/
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;
}
}
/* 函數buildSymtab通過前敘遍歷語法樹構建符號表
*/
void buildSymtab(TreeNode * syntaxTree)
{ traverse(syntaxTree,insertNode,nullProc);
if (TraceAnalyze)
{ 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;
}
/* 函數checkNode在語法樹的一個節點執行類型檢查
*/
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 applied 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)
{
/* IF語句,類型是布爾型 */
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[1]->type == Integer)
typeError(t->child[1],"repeat test is not Boolean");
break;
default:
break;
}
break;
default:
break;
}
}
/* 函數typeCheck通過后序遍歷語法樹來執行類型檢查
*/
void typeCheck(TreeNode * syntaxTree)
{ traverse(syntaxTree,nullProc,checkNode);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -