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 + -
显示快捷键?