Tiny C语言编译程序之语法分析Parser

来源:互联网 发布:圣诞唱诗班歌曲知乎 编辑:程序博客网 时间:2024/05/22 07:02

Tiny C语言编译程序之语法分析Parser

约定:

  • 用递归下降分析法,为每个语法符号编写子程序。进入每个子程序前已读入一个新Token。
  • 一个语法结构的内部表示形式为语法树,数据结构是globals.h中的treeNode。在做语法分析的同时建立语法结构的内部表示——语法树。

语法分析器parse.c

/****************************************************//* File: parse.c                                    *//* The parser implementation for the TINY compiler  *//****************************************************/#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);        /* 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){ if (token == expected) token = getToken();/*它找到匹配时就调用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 /* now p cannot be NULL either *//* 如果t不是NULL,那么p也一定不是NULL */      { p->sibling = q;/* 把state链接起来 */        p = q;      }    }  }  return t;}/* 用来匹配statement非终结符 */TreeNode * statement(void){ TreeNode * t = NULL;  switch (token) {/* 检测当前的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;  } /* end case */  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){    char msgerror[100];    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:            strcpy(msgerror,"unexpected token -> ");            strcat(msgerror,tokenString);            syntaxError(msgerror);            //syntaxError("unexpected token -> ");            //printToken(token,tokenString);            token = getToken();            break;    }    return t;}/****************************************//* the primary function of the parser   *//****************************************//* Function parse returns the newly  * constructed syntax tree */TreeNode * parse(void){ TreeNode * t;  token = getToken();  t = stmt_sequence();  if (token!=ENDFILE)    syntaxError("Code ends before file\n");  return t;}

分析后输出的语法树结构如下:

Syntax tree:  Read: x  If    Op: <      Const: 0      Id: x    Assign to: fact      Const: 1    Repeat      Assign to: fact        Op: *          Id: fact          Id: x      Assign to: x        Op: -          Id: x          Const: 1      Op: =        Id: x        Const: 0    Write      Id: fact
原创粉丝点击