⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parse.c

📁 c语言高级编程实例程序代码、按章放置; 光盘中所有程序在TC2.0或者在VC6.0下调试通过
💻 C
字号:
/****************************************************/
/* 文件: parse.c                                   */
/* TINY编译器的语法分析执行程序						*/
/****************************************************/

#include "globals.h"
#include "util.h"
#include "scan.h"
#include "parse.h"

static TokenType token; /* 保留当前的记号 */

/* 递归调用时候的函数原型 */
static TreeNode * stmt_sequence(void);		/* 语句序列 */
static TreeNode * statement(void);			/* 语句 */
static TreeNode * if_stmt(void);			/* if语句 */
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 * message)
{ fprintf(listing,"\n>>> ");
  fprintf(listing,"Syntax error at line %d: %s",lineno,message);
  Error = TRUE;
}

/* 保存向前看记号的静态变量token和检测输入的记号是否和预期相同 */
static void match(TokenType expected)
{ 
/*它找到匹配时就调用getToken,否则就声明出错*/
  if (token == expected) token = getToken();
  else {
    syntaxError("unexpected token -> ");
    printToken(token,tokenString);
    fprintf(listing,"      ");
  }
}
/* 用来匹配非终结符stmt_sequence */
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 /* 如果t不是NULL,那么p也一定不是NULL */
      {
		  /* 把state链接起来 */
		p->sibling = q;
        p = q;
      }
    }
  }
  return t;
}
/* 用来匹配statement非终结符 */
TreeNode * statement(void)
{ TreeNode * t = NULL;
/* 检测当前的token,根据输入决定如何识别 */
  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 : syntaxError("unexpected token -> ");
              printToken(token,tokenString);
              token = getToken();
              break;
  } 
  return t;
}
/* 用来匹配if_stmt非终结符 */
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;
}
/* 用来匹配repeat_stmt非终结符 */
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;
}
/* 用来匹配assign_stmt非终结符 */
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;
}
/* 用来匹配read_stmt非终结符 */
TreeNode * read_stmt(void)
{ TreeNode * t = newStmtNode(ReadK);
  match(READ);
  if ((t!=NULL) && (token==ID))
    t->attr.name = copyString(tokenString);
  match(ID);
  return t;
}
/* 用来匹配write_stmt非终结符 */
TreeNode * write_stmt(void)
{ TreeNode * t = newStmtNode(WriteK);
  match(WRITE);
  if (t!=NULL) t->child[0] = exp();
  return t;
}
/* 用来匹配exp非终结符 */
TreeNode * exp(void)
{ TreeNode * t = simple_exp();
  if ((token==LT)||(token==EQ)) {
    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;
}
/* 用来匹配simple_stmt非终结符 */
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);
      t->child[1] = term();
    }
  }
  return t;
}
/* 用来匹配term非终结符 */
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);
      p->child[1] = factor();
    }
  }
  return t;
}
/* 用来匹配factor非终结符 */
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:
      syntaxError("unexpected token -> ");
      printToken(token,tokenString);
      token = getToken();
      break;
    }
  return t;
}

/****************************************/
/* 语法分析程序的主函数					*/
/****************************************/
/*
 * 函数parse返回最近被构建的语法树
 */
TreeNode * parse(void)
{ TreeNode * t;
  token = getToken();
  t = stmt_sequence();
  if (token!=ENDFILE)
    syntaxError("Code ends before file\n");
  return t;
}

⌨️ 快捷键说明

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