当前位置: 首页 > news >正文

编译原理实验 之 Tiny C语言编译程序实验 语法分析

文章目录

    • 具体的实现
    • 结果图

在这里插入图片描述

首先回顾项目架构

-MAIN.C  主程序
-GLOBALS.H  全局类型及变量(如Token类属及语法树结点的组成)
-UTIL.H、UTIL.C  各步骤的实用函数。如输出Token,生成语法树结点等
-SCAN.C、SCAN.H  词法分析程序及其头文件
-PARSE.C、PARSE.H  语法分析程序及其头文件
-ANALYZE.C、ANALYZE.H  语义检查程序及其头文件
-SYMTAB.C、SYMTAB.H  符号表生成程序及其头文件
-CGEN.H、CGEN.C、CODE.C、CODE.H  目标代码生成程序及其头文件
-TM  编译sample.tny源程序后得到目标代码,在该虚拟机上运行得到结果

明确任务

  • 本次实现完成的是语法分析

在这里插入图片描述

  • parse.c文件
typedef enum {StmtK,ExpK} NodeKind;
typedef enum {IfK,RepeatK,AssignK,ReadK,WriteK} StmtKind;
typedef enum {OpK,ConstK,IdK} ExpKind;typedef enum {Void,Integer,Boolean} ExpType;#define MAXCHILDREN 3typedef struct treeNode{ struct treeNode * child[MAXCHILDREN];struct treeNode * sibling;int lineno;NodeKind nodekind;union { StmtKind stmt; ExpKind exp;} kind;union { TokenType op;int val;char * name; } attr;ExpType type; } TreeNode;/****************************************************/
/* 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);
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;
}static void match(TokenType expected)
{ if (token == expected) token = getToken();else {syntaxError("unexpected token -> ");printToken(token,tokenString);fprintf(listing,"      ");}
}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;
}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 : syntaxError("unexpected token -> ");printToken(token,tokenString);token = getToken();break;} /* end case */return t;
}TreeNode * if_stmt(void)
{          ……          //此处请自己填写
}TreeNode * repeat_stmt(void)
{……          //此处请自己填写
}TreeNode * assign_stmt(void)
{ ……          //此处请自己填写
}TreeNode * read_stmt(void)
{……          //此处请自己填写
}TreeNode * write_stmt(void)
{……          //此处请自己填写
}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;
}TreeNode * simple_exp(void)
{……          //此处请自己填写
}TreeNode * term(void)
{……          //此处请自己填写
}TreeNode * factor(void)
{……          //此处请自己填写
}/****************************************/
/* 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;
}

具体的实现

  • 完善这个parse.c文件:直接把parse.c和要求丢给ai即可
要求:填写各语法符号的递归下降子程序,完成语法分析器parse.c。
约定:
-用递归下降分析法,为每个语法符号编写子程序。进入每个子程序前已读入一个新Token。
-一个语法结构的内部表示形式为语法树,数据结构是globals.h中的treeNode。在做语法分析的同时建立语法结构的内部表示——语法树。
  • 生成完成之后,修改main.c中的参数设置
/* set NO_PARSE to TRUE to get a scanner-only compiler */
#define NO_PARSE FALSE
/* set NO_ANALYZE to TRUE to get a parser-only compiler */
#define NO_ANALYZE TRUE/* set NO_CODE to TRUE to get a compiler that does not* generate code*/
#define NO_CODE TRUE
  • 还有下面的参数
/* allocate and set tracing flags */
int EchoSource = FALSE;
int TraceScan = FALSE;
int TraceParse = TRUE;
int TraceAnalyze = FALSE;
int TraceCode = FALSE;
int Error = FALSE;
  • 接着就可以测试语法分析,xxxxx替换为编译之后的文件名,自己取
gcc main.c util.c scan.c parse.c -o xxxxx
  • 测试,xxxxx是上面编译之后的程序,SAMPLE.TNY是文件夹里面本身就有的测试文件
./xxxxx SAMPLE.TNY 

结果图

在这里插入图片描述

http://www.xdnf.cn/news/175051.html

相关文章:

  • 量子力学:量子通信
  • 人工智能时代的网络安全威胁
  • 全自动部署到远程服务器
  • 8.0 西门子PLC的S7通讯解析
  • 欧空局的P 波段雷达卫星即将升空
  • python pyplot 输出支持中文
  • Linux常用命令23——usermod
  • 关于堆栈指针的那些事 | bootloader 如何跳转app
  • react的 Fiber 节点的链表存储
  • 学生公寓限电模块控制柜是如何实现智能限电功能?
  • 【八股消消乐】发送请求有遇到服务不可用吗?如何解决?
  • 项目代码生成工具
  • 【技术追踪】基于扩散模型的脑图像反事实生成与异常检测(TMI-2024)
  • 【计算机视觉】CV实战项目- Four-Flower:基于TensorFlow的花朵分类实战指南
  • HarmonyOS NEXT:多设备的自由流转
  • 前端Vue项目处理跨域请求问题解决方案(后端未加cors),前端调后端
  • 深入探索Python Pandas:解锁数据分析的无限可能
  • go语言八股文(四)
  • WGS84(GPS)、火星坐标系(GCJ02)、百度地图(BD09)坐标系转换Java代码
  • 电池管理系统
  • Linux文件管理(3)
  • SpringMVC 静态资源处理 mvc:default-servlet-handler
  • 新增29个专业,科技成为未来主赛道!
  • 【机器学习驱动的智能化电池管理技术与应用】
  • 数字人接大模型第二步:实时语音同步
  • 在旧版本中打开Anylogic模型
  • Linux命令-iostat
  • 力扣4-最长公共前缀
  • 02_值相同、类型不同,用 equals() 比较为什么是 false?
  • 微信小程序自定义组件阻止click事件冒泡