📄 analyze.c
字号:
/****************************************************//* File: analyze.c *//* Semantic analyzer implementation *//* for the TINY compiler *//* Compiler Construction: Principles and Practice *//* Kenneth C. Louden *//****************************************************/#include "globals.h"#include "symtab.h"#include "analyze.h"/* counter for variable memory locations */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) /* not yet in table, so treat as new definition */ st_insert(t->attr.name,t->lineno,location++); else /* already in table, so ignore location, add line number of use only */ 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) /* not yet in table, so treat as new definition */ st_insert(t->attr.name,t->lineno,location++); else /* already in table, so ignore location, add line number of use only */ 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); 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;}/* 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 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) { 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; }}/* Procedure typeCheck performs type checking * by a postorder syntax tree traversal */void typeCheck(TreeNode * syntaxTree){ traverse(syntaxTree,nullProc,checkNode);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -