util.c

来自「SIP软件开发记录 由于通信网的封闭性」· C语言 代码 · 共 307 行

C
307
字号
/* util.c
 * Utilaty function implementation
 * for the TINY compiler
 *
 * Compiler Construction: Principles and Practice
 * Kenneth C. Louden
 * 编译原理及实践
 * (美) Kenneth C. Louden 著
 * 冯博琴 冯岚 等译
 * 机械工业出版社 IBSN 7-111-07703-2
 * 源代码:zwf编辑并修订
 * Code Modify: 
 */
#include "globals.h"
#include "util.h"

/* Procedure printToken prints a token
 * and its lexeme to the listing file
 */
void printToken(TokenType token, const char *tokenString)
{
	switch (token) {
	case IF:
	case THEN:
	case ELSE:
	case END:
	case REPEAT:
	case UNTIL:
	case READ:
	case WRITE:
#ifdef CHINESE
		fprintf(listing, "关键字: %s\n", tokenString);
#else
		fprintf(listing, "reserved word: %s\n", tokenString);
#endif
		break;
	case ASSIGN:
		fprintf(listing, ":=\n");
		break;
	case LT:
		fprintf(listing, "<\n");
		break;
	case GT:
		fprintf(listing, ">\n");
		break;
	case EQ:
		fprintf(listing, "=\n");
		break;
	case LE:
		fprintf(listing, "<=\n");
		break;
	case GE:
		fprintf(listing, ">=\n");
		break;
	case NE:
		fprintf(listing, "<>\n");
		break;
	case LPAREN:
		fprintf(listing, "(\n");
		break;
	case RPAREN:
		fprintf(listing, ")\n");
		break;
	case SEMI:
		fprintf(listing, ";\n");
		break;
	case PLUS:
		fprintf(listing, "+\n");
		break;
	case MINUS:
		fprintf(listing, "-\n");
		break;
	case TIMES:
		fprintf(listing, "*\n");
		break;
	case OVER:
		fprintf(listing, "/\n");
		break;
	case ENDFILE:
#ifdef CHINESE
		fprintf(listing, "文件结束\n");
#else
		fprintf(listing, "EOF\n");
#endif
		break;
	case NUM:
#ifdef CHINESE
		fprintf(listing, "数值, 值= %s\n", tokenString);
#else
		fprintf(listing, "NUM, val= %s\n", tokenString);
#endif
		break;
	case ID:
#ifdef CHINESE
		fprintf(listing, "变量, 名称= %s\n", tokenString);
#else
		fprintf(listing, "ID, name= %s\n", tokenString);
#endif
		break;
	case ERROR:
#ifdef CHINESE
		fprintf(listing, "错误: %s\n", tokenString);
#else
		fprintf(listing, "ERROR: %s\n", tokenString);
#endif
		break;
	default:
#ifdef CHINESE
		fprintf(listing, "未知符号: %d\n", token);
#else
		fprintf(listing, "Unknown token: %d\n", token);
#endif
		break;
	}
}

/* Function newStmtNode create a new statement
 * node for syntax tree construction
 */
TreeNode *newStmtNode(StmtKind kind)
{
	TreeNode *t = (TreeNode *) malloc(sizeof(TreeNode));
	int i;

	if (t == NULL)
#ifdef CHINESE
		fprintf(listing, "内存溢出, 行号: %d\n", lineno);
#else
		fprintf(listing, "Out of memory error at line %d\n", lineno);
#endif
	else {
		for (i = 0; i < MAXCHILDREN; i++)
			t->child[i] = NULL;
		t->sibling = NULL;
		t->nodekind = StmtK;
		t->kind.stmt = kind;
		t->lineno = lineno;
	}
	return t;
}

/* Function newExpNode create a new expression
 * node for syntax tree construction
 */
TreeNode *newExpNode(ExpKind kind)
{
	TreeNode *t = (TreeNode *) malloc(sizeof(TreeNode));
	int i;

	if (t == NULL)
#ifdef CHINESE
		fprintf(listing, "内存溢出, 行号: %d\n", lineno);
#else
		fprintf(listing, "Out of memory error at line %d\n", lineno);
#endif
	else {
		for (i = 0; i < MAXCHILDREN; i++)
			t->child[i] = NULL;
		t->sibling = NULL;
		t->nodekind = ExpK;
		t->kind.stmt = kind;
		t->lineno = lineno;
	}
	return t;
}

/* Function copyString allocates and makes a new
 * copy of an existing string
 */
char *copyString(char *s)
{								/* strdup */
	int n;
	char *t;

	if (s == NULL)
		return NULL;
	n = strlen(s) + 1;
	t = malloc(n);
	if (t == NULL)
#ifdef CHINESE
		fprintf(listing, "内存溢出, 行号: %d\n", lineno);
#else
		fprintf(listing, "Out of memory error at line %d\n", lineno);
#endif
	else
		strcpy(t, s);
	return t;
}

/* Variable indentno is used by printTree to
 * store current number of spaces to indent
 */
static 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 yo indicate subtree
 */
void printTree(TreeNode * tree)
{
	int i;

	INDENT;
	while (tree != NULL) {
		printSpaces();
		if (tree->nodekind == StmtK) {
			switch (tree->kind.stmt) {
			case IfK:
#ifdef CHINESE
				fprintf(listing, "如果\n");
#else
				fprintf(listing, "If\n");
#endif
				break;
			case RepeatK:
#ifdef CHINESE
				fprintf(listing, "循环\n");
#else
				fprintf(listing, "Repeat\n");
#endif
				break;
			case AssignK:
#ifdef CHINESE
				fprintf(listing, "赋值到: %s\n", tree->attr.name);
#else
				fprintf(listing, "Assign to: %s\n", tree->attr.name);
#endif
				break;
			case ReadK:
#ifdef CHINESE
				fprintf(listing, "读取: %s\n", tree->attr.name);
#else
				fprintf(listing, "Read: %s\n", tree->attr.name);
#endif
				break;
			case WriteK:
#ifdef CHINESE
				fprintf(listing, "输出\n");
#else
				fprintf(listing, "Write\n");
#endif
				break;
			default:
#ifdef CHINESE
				fprintf(listing, "未知关键字\n");
#else
				fprintf(listing, "Unknown ExpNode kind\n");
#endif
				break;
			}
		} else if (tree->nodekind == ExpK) {
			switch (tree->kind.exp) {
			case OpK:
#ifdef CHINESE
				fprintf(listing, "操作符: ");
#else
				fprintf(listing, "Op: ");
#endif
				printToken(tree->attr.op, "\0");
				break;
			case ConstK:
#ifdef CHINESE
				fprintf(listing, "变量: %d\n", tree->attr.val);
#else
				fprintf(listing, "Const: %d\n", tree->attr.val);
#endif
				break;
			case IdK:
#ifdef CHINESE
				fprintf(listing, "名称: %s\n", tree->attr.name);
#else
				fprintf(listing, "Id: %s\n", tree->attr.name);
#endif
				break;
			default:
#ifdef CHINESE
				fprintf(listing, "未知关键字\n");
#else
				fprintf(listing, "Unknown ExpNode kind\n");
#endif
				break;
			}
		} else
#ifdef CHINESE
			fprintf(listing, "未知节点\n");
#else
			fprintf(listing, "Unknown node kind\n");
#endif
		for (i = 0; i < MAXCHILDREN; i++)
			printTree(tree->child[i]);
		tree = tree->sibling;
	}
	UNINDENT;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?