📄 util.c
字号:
/****************************************************/
/* File: util.c */
/* Utility function implementation */
/* for the TINY compiler */
/* Compiler Construction: Principles and Practice */
/* Kenneth C. Louden */
/****************************************************/
#include "Globals.h"
#include "Util.h"
void printType(VExpType type)
{
switch(type.type){
case Void:
fprintf(listing,"Void");
break;
case Integer:
fprintf(listing,"Integer");
break;
case Double:
fprintf(listing,"Double");
break;
case Char:
fprintf(listing,"Char");
break;
case String:
fprintf(listing,"String");
break;
case Boolean:
fprintf(listing,"Boolean");
break;
case Struct:
fprintf(listing,"Struct %s", type.name);
break;
default:
fprintf(listing,"Unknown Type");
break;
}
}
/* Procedure printToken prints a token
* and its lexeme to the listing file
*/
void printToken( TokenType token, const char* tokenString )
{
switch (token)
{
case INT:
case CHAR:
case DOUBLE:
case VOID:
case IF:
case ELSE:
case RETURN:
case WHILE:
case BREAK:
case STRUCT:
case TYPEDEF:
case CONTINUE:
fprintf(listing, "reserved word: %s\n",tokenString);
break;
case ASSIGN:
fprintf(listing,":=\n");
break;
case DOT:
fprintf(listing,".");
break;
case LT:
fprintf(listing,"<\n");
break;
case EQ:
fprintf(listing,"==\n");
break;
case LP:
fprintf(listing,"(\n");
break;
case RP:
fprintf(listing,")\n");
break;
case SEMI:
fprintf(listing,";\n");
break;
case COMMA:
fprintf(listing,",\n");
break;
case PLUS:
fprintf(listing,"+\n");
break;
case SUB:
fprintf(listing,"-\n");
break;
case MUT:
fprintf(listing,"*\n");
break;
case DIV:
fprintf(listing,"/\n");
break;
case ENDFILE:
fprintf(listing,"EOF\n");
break;
case LE: fprintf(listing,"<=\n"); break;
case GT: fprintf(listing,">\n"); break;
case GE: fprintf(listing,">=\n"); break;
case AND: fprintf(listing,"&&\n"); break;
case OR: fprintf(listing,"||\n"); break;
case NOT: fprintf(listing,"!\n"); break;
case LSP: fprintf(listing,"[\n"); break;
case RSP: fprintf(listing,"]\n"); break;
case LFP: fprintf(listing,"{\n"); break;
case RFP: fprintf(listing,"}\n"); break;
case NUM:
fprintf(listing,"NUM, val= %s\n",tokenString);
break;
case ID:
fprintf(listing,"ID, name= %s\n",tokenString);
break;
case DNUM:
fprintf(listing,"DNUM, val= %s\n",tokenString);
break;
case SCHAR:
fprintf(listing,"SCHAR, val= %s\n",tokenString);
break;
case STRING:
fprintf(listing,"STRING, val= %s\n",tokenString);
break;
case ERROR:
fprintf(listing,"ERROR: %s\n",tokenString);
break;
default: /* should never happen */
fprintf(listing,"Unknown token: %d\n",token);
break;
}
}
/* Function newStmtNode creates a new statement
* node for syntax tree construction
*/
TreeNode * newDecNode(DecKind kind)
{
TreeNode * t = (TreeNode *) malloc(sizeof(TreeNode));
int i;
if (t==NULL)
fprintf(listing,"Out of memory error at line %d\n",lineno);
else {
for (i=0;i<MAXCHILDREN;i++) t->child[i] = NULL;
t->sibling = NULL;
t->nodekind = DecK;
t->lineno = lineno;
t->call_stmt = 0;
t->kind.dec = kind;
}
return t;
}
TreeNode * newStmtNode(StmtKind kind)
{
TreeNode *t = (TreeNode *) malloc(sizeof(TreeNode));
int i;
if (t==NULL)
fprintf(listing,"Out of memory error at line %d\n",lineno);
else {
for (i=0;i<MAXCHILDREN;i++)
t->child[i] = NULL;
t->sibling = NULL;
t->nodekind = StmtK;
t->kind.stmt = kind;
t->lineno = lineno;
t->call_stmt = 0;
}
return t;
}
/* Function newExpNode creates a new expression
* node for syntax tree construction
*/
TreeNode * newExpNode(ExpKind kind)
{
TreeNode *t = (TreeNode *) malloc(sizeof(TreeNode));
int i;
if (t==NULL)
fprintf(listing,"Out of memory error at line %d\n",lineno);
else {
for (i=0;i<MAXCHILDREN;i++)
t->child[i] = NULL;
t->sibling = NULL;
t->nodekind = ExpK;
t->kind.exp = kind;
t->lineno = lineno;
t->call_stmt = 0;
t->type.type = Void;
}
return t;
}
/* Function copyString allocates and makes a new
* copy of an existing string
*/
char * copyString(char * s)
{
int n;
char * t;
if (s==NULL)
return NULL;
n = strlen(s)+1;
t = (char*)malloc(n);
if (t==NULL)
fprintf(listing,"Out of memory error at line %d\n",lineno);
else
strcpy(t,s);
return t;
}
/* Variable indentno is used by printTree to
* store current number of spaces to indent
*/
static int indentno = 0;
/* macros to increase/decrease indentation */
#define INDENT indentno+=2
#define UNINDENT indentno-=2
/* printSpaces indents by printing spaces */
static void printSpaces(void)
{
int i;
for (i=0;i<indentno;i++)
fprintf(listing," ");
}
/* procedure printTree prints a syntax tree to the
* listing file using indentation to indicate subtrees
*/
void printTree( TreeNode * tree )
{
int i;
INDENT;
while (tree != NULL)
{
printSpaces();
if(tree->nodekind==DecK){
switch(tree ->kind.dec){
case VarK:
fprintf(listing,"ID_Dec Var_Type: ");
printType(tree ->type);
fprintf(listing,"\n");
break;
case FunDecK:
fprintf(listing,"Fun_Dec name: %s Return_Type: ",tree->attr.name);
printType(tree ->type);
fprintf(listing,"\n");
break;
case FunDefK:
fprintf(listing,"Fun_Def name: %s Return_Type: ",tree->attr.name);
printType(tree ->type);
fprintf(listing,"\n");
break;
case StructDecK:
fprintf(listing,"Str_Dec name: %s Return_Type: ",tree->attr.name);
printType(tree ->type);
fprintf(listing,"\n");
break;
case StructEndK:
fprintf(listing,"Str_End ");
fprintf(listing,"\n");
break;
case ParamK:
fprintf(listing,"Param_Dec Param_Type: ");
printType(tree ->type);
fprintf(listing,"\n");
break;
case CompK:
fprintf(listing,"Comp_Dec \n");
break;
}
}
else if (tree->nodekind==StmtK)
{
switch (tree->kind.stmt)
{
case IfK:
fprintf(listing,"If\n");
break;
case WhileK:
fprintf(listing,"While\n");
break;
case AssignK:
fprintf(listing,"Assign to: %s\n",tree->attr.name);
break;
case ReturnK:
fprintf(listing,"Return\n");
break;
case CallK:
fprintf(listing,"Call to: %s\n",tree ->attr.name);
break;
case ContinueK:
fprintf(listing,"Continue\n");
break;
case BreakK:
fprintf(listing,"break\n");
break;
default:
fprintf(listing,"Unknown ExpNode kind\n");
break;
}
}
else if (tree->nodekind==ExpK)
{
switch (tree->kind.exp) {
case OpK:
fprintf(listing,"Op: ");
printToken(tree->attr.op,"\0");
break;
case IdK:
fprintf(listing,"Id: %s\n",tree->attr.name);
break;
case FieldIdK:
fprintf(listing,"FieldId: %s\n",tree->attr.name);
break;
case StructIdK:
fprintf(listing,"StructId: %s\n",tree->attr.name);
break;
case NumK:
fprintf(listing,"Num_Const: %d\n",tree->attr.val.i);
break;
case DNumK:
fprintf(listing,"DNum_Const: %f\n",tree->attr.val.f);
break;
case CharK:
fprintf(listing,"Char_Const: %c\n",tree->attr.val.i);
break;
case StringK:
fprintf(listing,"String_Const: %s\n",tree->attr.val.str);
break;
default:
fprintf(listing,"Unknown ExpNode kind\n");
break;
}
}
else
fprintf(listing,"Unknown node kind\n");
for (i=0;i<MAXCHILDREN;i++)
printTree(tree->child[i]);
tree = tree->sibling;
}
UNINDENT;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -