parse.c

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

C
290
字号
/* parse.c
 * The parser 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"
#include "scan.h"
#include "parse.h"

static TokenType token;			/* holds current token */

/* function prototypes for recursive calls */
static TreeNode *stmt_sequence(void);
static TreeNode *statement(void);
static TreeNode *if_stmt(void);
static TreeNode *repeat_stmt(void);
static TreeNode *assign_stmt(void);
static TreeNode *read_stmt(void);
static TreeNode *write_stmt(void);
static TreeNode *exp(void);
static TreeNode *simple_exp(void);
static TreeNode *term(void);
static TreeNode *factor(void);

static void syntaxError(char *msg)
{
	fprintf(listing, "\n>>> ");
#ifdef CHINESE
	fprintf(listing, "语法错误, %d 行: %s", lineno, msg);
#else
	fprintf(listing, "Syntax error at line %d: %s", lineno, msg);
#endif
	Error = TRUE;
}

static void match(TokenType exp)
{
	if (token == exp)
		token = getToken();
	else {
#ifdef CHINESE
		syntaxError("错误符号 -> ");
#else
		syntaxError("unexpected token -> ");
#endif
		printToken(token, tokenString);
		fprintf(listing, "      ");
	}
}

static TreeNode *stmt_sequence(void)
{
	TreeNode *t = statement();
	TreeNode *p = t;

	while ((token != ENDFILE) && (token != END)
		   && (token != ELSE) && (token != UNTIL)) {
		TreeNode *q;

		match(SEMI);
		q = statement();
		if (q != NULL) {
			if (t == NULL)
				t = p = q;
			else {				/* now p cannot be NULL either */
				p->sibling = q;
				p = q;
			}
		}
	}
	return t;
}

static TreeNode *statement(void)
{
	TreeNode *t = NULL;

	switch (token) {
	case IF:
		t = if_stmt();
		break;
	case REPEAT:
		t = repeat_stmt();
		break;
	case ID:
		t = assign_stmt();
		break;
	case READ:
		t = read_stmt();
		break;
	case WRITE:
		t = write_stmt();
		break;
	default:
#ifdef CHINESE
		syntaxError("错误符号 -> ");
#else
		syntaxError("unexpected token -> ");
#endif
		printToken(token, tokenString);
		token = getToken();
		break;
	}
	return t;
}

static TreeNode *if_stmt(void)
{
	TreeNode *t = newStmtNode(IfK);

	match(IF);
	if (t != NULL)
		t->child[0] = exp();
	match(THEN);
	if (t != NULL)
		t->child[1] = stmt_sequence();
	if (token == ELSE) {
		match(ELSE);
		if (t != NULL)
			t->child[2] = stmt_sequence();
	}
	match(END);
	return t;
}

static TreeNode *repeat_stmt(void)
{
	TreeNode *t = newStmtNode(RepeatK);

	match(REPEAT);
	if (t != NULL)
		t->child[0] = stmt_sequence();
	match(UNTIL);
	if (t != NULL)
		t->child[1] = exp();
	return t;
}

static TreeNode *assign_stmt(void)
{
	TreeNode *t = newStmtNode(AssignK);

	if ((t != NULL) && (token == ID))
		t->attr.name = copyString(tokenString);
	match(ID);
	match(ASSIGN);
	if (t != NULL)
		t->child[0] = exp();
	return t;
}

static TreeNode *read_stmt(void)
{
	TreeNode *t = newStmtNode(ReadK);

	match(READ);
	if ((t != NULL) && (token == ID))
		t->attr.name = copyString(tokenString);
	match(ID);
	return t;
}

static TreeNode *write_stmt(void)
{
	TreeNode *t = newStmtNode(WriteK);

	match(WRITE);
	if (t != NULL)
		t->child[0] = exp();
	return t;
}

static TreeNode *exp(void)
{
	TreeNode *t = simple_exp();

	if ((token == LT) || (token == EQ) || (token == GT)
		|| (token == LE) || (token == NE) || (token == GE)) {
		TreeNode *p = newExpNode(OpK);

		if (p != NULL) {
			p->child[0] = t;
			p->attr.op = token;
			t = p;
		}
		match(token);
		if (t != NULL)
			t->child[1] = simple_exp();
	}
	return t;
}

static TreeNode *simple_exp(void)
{
	TreeNode *t = term();

	while ((token == PLUS) || (token == MINUS)) {
		TreeNode *p = newExpNode(OpK);

		if (p != NULL) {
			p->child[0] = t;
			p->attr.op = token;
			t = p;
		}
		match(token);
		if (t != NULL)
			t->child[1] = term();
	}
	return t;
}

static TreeNode *term(void)
{
	TreeNode *t = factor();
	while ((token == TIMES) || (token == OVER)) {
		TreeNode *p = newExpNode(OpK);

		if (p != NULL) {
			p->child[0] = t;
			p->attr.op = token;
			t = p;
		}
		match(token);
		if (t != NULL)
			t->child[1] = factor();
	}
	return t;
}

static TreeNode *factor(void)
{
	TreeNode *t = NULL;

	switch (token) {
	case NUM:
		t = newExpNode(ConstK);
		if ((t != NULL) && (token == NUM))
			t->attr.val = atoi(tokenString);
		match(NUM);
		break;
	case ID:
		t = newExpNode(IdK);
		if ((t != NULL) && (token == ID))
			t->attr.name = copyString(tokenString);
		match(ID);
		break;
	case LPAREN:
		match(LPAREN);
		t = exp();
		match(RPAREN);
		break;
	default:
#ifdef CHINESE
		syntaxError("错误符号 -> ");
#else
		syntaxError("unexpected token -> ");
#endif
		printToken(token, tokenString);
		token = getToken();
		break;
	}
	return t;
}

/* Function parse returns the newly
 * constructed syntax tree
 */
TreeNode *parse(void)
{
	TreeNode *t;

	token = getToken();
	t = stmt_sequence();
	if (token != ENDFILE)
#ifdef CHINESE
		syntaxError("代码结束于文件之前\n");
#else
		syntaxError("Code ends before file\n");
#endif
	return t;
}

⌨️ 快捷键说明

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