本节内容需要结合视频讲解才能更容易理解,视频播放地址如下:
用java开发编译器

本节,我们着重研究结构体定义,也就是struct 这种变量定义,C语言编译器是如何解析的,本节我们要解析的结构体定义如下:

struct tag {int x;long y;char z;struct tag* p;
}name;

1.1 结构体定义的解析语法

     * TYPE_SPECIFIER -> STRUCT_SPECIFIER* * STTUCT_SPECIFIER -> STRUCT OPT_TAG LC DEF_LIST RC*                     | STRUCT TAG* * OPT_TAG -> TAG* * TAG -> NAME* * DEF_LIST ->  DEF* * DEF_LIST ->  DEF_LIST DEF*           *             * * *            * DEF -> SPECIFIERS  DECL_LIST SEMI*        | SPECIFIERS SEMI*       *        * DECL_LIST -> DECL*             | DECL_LIST COMMA DECL*             * DECL -> VAR_DECL* * VAR_DECL -> NEW_NAME*             | VAR_DECL LP RP*             | VAR_DECL LP VAR_LIST RP*             | LP VAR_DECL RP*             | START VAR_DECL*

我们先看这一句定义:
STTUCT_SPECIFIER -> STRUCT OPT_TAG LC DEF_LIST RC

STRUCT 是关键字struct 对应的标签, OPT_TAG 对应的是结构体变量的名字tag, LC 对应左大括号, DEF_LIST 对应结构体内部变量的定义序列,RC就是右大括号。这一句语法就已经描述了整个结构体的定义,解析的终点其实在 DEF_LIST, 这个非终结符描述的是结构体内部变量的定义规则,对DEF_LIST的解析是整个解析过程的难点。

1.2语法解析流程描述

解析开始时,词法解析器会把关键字struct读入,并返回一个STRUCT标签。

读入struct 后面的变量名tag, 返回对应标签NAME.

根据表达式 TAG -> NAME, 将NAME转换成非终结符TAG.

通过表达式 OPT_TAG -> TAG , 将TAG转换成非终结符OPT_TAG.

读入左大括号{, 并返回对应标签LC.

*读入关键字int, 并返回对应的标签TYPE

*根据表达式TYPE_SPECIFIER -> TYPE, 将TYPE替换成非终结符TYPE_SPECIFIER. 这个表达式在前面的章节中讲解过,本节没有列出来。

*根据表达式 TYPE_OR_CLASS -> TYPE_SPECIFIER 将非终结符TYPE_SPECIFIER 转换成TYPE_OR_CLASS.

*通过表达式 SPECIFIER -> TYPE_OR_CLASS, 将非终结符TYPE_OR_CLASS转换成SPECIFIERS.

上面几步完成了对关键字int 的解析。

接着读入变量名x, 返回对应的标签NAME.

*根据表达式NEW_NAME -> NAME, 将非终结符NEW_NAME 压入堆栈。

*根据表达式VAR_DECL -> NEW_NAME 将非终结符换成VAR_DECL.

*通过表达式DECL -> VAR_DECL 将非终结符DECL替换掉VAR_DECL.

*通过表达式DECL_LIST -> DECL 将非终结符DECL_LIST 压入堆栈。

*读入分号,并返回对应的标签SEMI

*根据表达式DEF -> SPECIFIERS DECL_LIST SEMI 将解析堆栈上的符号全部弹出,换成非终结符DEF.

再次通过 DEF_LIST -> DEF 将非终结符压入堆栈。

在这一步我们可以看到,”int x ; “, 这一个变量定义语句可以被非终结符DEF_LIST所描述。

接下来,解析器读入语句 “long y ;”,该语句的解析也同样经历前面带*号的解析步骤,最后”long y;” 会解析成非终结符DEF,此时解析堆栈顶部有两个非终结符DEF, DEF_LIST.

通过表达式 DEF_LIST -> DEF_LIST DEF 将两个非终结符归纳成一个非终结符DEF_LIST.

解析器继续读入 “char z;”, 同样经历带*号的解析步骤后,把该语句解析成非终结符DEF, 这时解析堆栈头部又在此含有两个非终结符 DEF_LIST, DEF, 于是又可以通过表达式 DEF_LIST -> DEF_LIST DEF 将两个非终结符归纳为一个非终结符DEF_LIST.

接下来解析器再次遇到关键字struct, 读入后返回对应标签STRUCT.

入读struct 后面的变量名tag,返回对应标签NAME.

运用表达式 TAG -> NAME, 将非终结符TAG压入堆栈。

采用表达式STRUCT_SPECIFIER -> STRUCT TAG 将堆栈顶部的两个非终结符替换成STRUCT_SPECIFIER.

再通过TYPE_SPECIFIER -> STRUCT_SPECIFIER 将栈顶非终结符替换成TYPE_SPECIFIER.

接着分别通过两个表达式TYPE_OR_CLASS -> TYPE_SPECIFIER 和 SPECIFIERS -> TYPE_OR_CLASS, 将栈顶元素替换成SPECIFIERS.

然后把代表指针的* 读入,返回对应标签STAR.

读入星号后面的变量名p, 返回对应的标签NAME.

通过表达式NEW_NAME -> NAME, 将非终结符NEW_NAME压入解析堆栈。

通过VAR_DECL -> NEW_NAME 将栈顶元素替换成VAR_DECL.

此时栈顶元素包含VAR_DECL, 和 STAR, 这两个元素正好形成表达式:
VAR_DECL -> STAR VAR_DECL 的右边部分,于是经过一次reduce,将堆栈顶部的两个元素替换成VAR_DECL.

继续通过表达式DECL -> VAR_DECL, 将非终结符DECL压入堆栈。

DECL 可以通过表达式DECL_LIST -> DECL 替换成DECL_LIST.

接着读入变量p后面的分号,返回对应标签SEMI

此时,解析堆栈上含有三个元素:SEMI, DECL_LIST, SPECIFIERS, 他们正好构成表达式DEF -> SPECIFIERS DECL_LIST SEMI 的右边,于是通过该表达式进行一次reduce, 将DEF替换掉这三个符号。

此时,堆栈顶部有两个元素,DEF, DEF_LIST, 又正好构成表达式:
DEF_LIST -> DEF_LIST DEF 的右边,于是又可以用DEF_LIST 替换掉堆栈顶部的两个元素。

接着读入右括号 }, 返回对应标签RC.

这时,堆栈顶部的5个元素正好对应表达式:
STRUCT_SPECIFIER -> STRUCT OPT_TAG LC DEF_LIST RC 的右边,于是解析器可以一下子将这5个元素全部替换成STRUCT_SPECIFIER.

接着解析器可以通过TYPE_SPECIFIER -> STRUCT_SPECIFIER 将TYPE_SPECIFIER压入堆栈。

然后把}后面的变量名name,读入,解析流程跟前面讲解的流程一样。

读入最后的分号后,解析堆栈上的元素正好构成表达式:
EXT_DEF -> .OPT_SPECIFIERS EXT_DECL_LIST SEMI
的右边部分,于是整个解析堆栈顶部的元素全部弹出,换成符号EXT_DEF.

接下来的推导跟以前一样,经过一系列固定步骤后,全局非终结符PROGRAM会被压入堆栈,从而使得解析器接收输入文本。

由此可见,依赖本节给出的语法定义,解析器能够顺利的分解结构体的代码。

通过这几节的解析流程分析,我们可以看到,写的再繁杂,再杂乱无章的程序代码,只要符合语法,那么这些看似随机组合的字符或单词,本质上遵从着一种非常严谨的层次和结构,这种层次和结构可以通过语法定义的方式描述出来,大道至简,任何复杂的系统,其本质都可以归因为若干简单的原理。这就是科学之美,编译原理的算法之美,学习编译原理或任何科学知识,其实是一种享受美的过程。

要体验这种系统逻辑之美,需要巨大的耐心,和不厌其烦的探索,持之以恒的意志力,有这种恒心的人,才有可能“会当凌绝顶,一览众山小”,学习是一个不断攀爬,跌倒,再攀爬的过程,只有要紧牙,永不放弃的人,才有可能在光明顶感受到“荡胸生层云,决眦入归鸟”的人生成就感。

再次以王安石《游褒禅山记》为每一位愿意“吾将上下而求索”的同学共勉:

“古人之观于天地、山川、草木、虫鱼、鸟兽,往往有得,以其求思之深而无不在也。夫夷以近,则游者众;险以远,则至者少。而世之奇伟、瑰怪,非常之观,常在于险远,而人之所罕至焉,故非有志者不能至也。有志矣,不随以止也,然力不足者,亦不能至也。有志与力,而又不随以怠,至于幽暗昏惑而无物以相之,亦不能至也。然力足以至焉,于人为可讥,而在己为有悔;尽吾志也而不能至者,可以无悔矣,其孰能讥之乎?此余之所得也!”

相信我,你,并不孤独!

C语言结构体struct的语法解析相关推荐

  1. c语言结构体语法分析,C语言结构体struct的语法解析

    本节内容需要结合视频讲解才能更容易理解,视频播放地址如下: 用java开发编译器 本节,我们着重研究结构体定义,也就是struct 这种变量定义,C语言编译器是如何解析的,本节我们要解析的结构体定义如 ...

  2. c语言结构体定义蚂蚁,C语言结构体(struct)常见使用方法

    C语言结构体(struct)常见使用方法 C语言结构体(struct)常见使用方法 基本定义:结构体,通俗讲就像是打包封装,把一些有共同特征(比如同属于某一类事物的属性,往往是某种业务相关属性的聚合) ...

  3. C语言 结构体Struct 中冒号的用法

    C语言 结构体Struct 中冒号的用法 本文有部分内容参考菜鸟教程-C 位域 . 关于"位域"的说明 有些信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位. ...

  4. C语言 结构体 struct Cat cat1;

    引入 使用传统技术解决 需要定义多个变量或数组 结构体与结构体变量的关系示意图 类似Java类中的对象(结构体)与属性(结构体变量) 一切物体都可以看作对象(结构体) 补充:C语言数据类型 简单使用案 ...

  5. C语言结构体struct详解与实例

    目录 1.定义 2.应用 2.1初始化 2.2使用 3.结构体对齐规则与存储 1.定义 C语言中结构体(struct关键字定义)是一种自定义数据类型.通过结构体的定义可以将多种不同类型数据形成一个组合 ...

  6. 关于C语言结构体(struct)介绍

    转自:微点阅读  https://www.weidianyuedu.com 导读:       C语言结构体,怎么理解? 你可以把它想象成一个桌面上的文件夹,这个文件夹里面可以有各种各样的文件,当然也 ...

  7. C语言——结构体struct与typedef的使用

    我们常常在某些C语言代码中看到有时候typedef关键字和struct一起连用定义结构体,有时候只用struct关键字直接定义结构体,在此记录两者的一些用法,给自己做一个笔记,希望对大家也有所帮助.如 ...

  8. C语言怎么存储结构体,C语言结构体Struct怎么使用?

    在C语言中,可以使用结构体(Struct)来存放一组不同类型的数据.结构体的定义形式为:struct结构体名{结构体所包含的变量或数组};结构体是一种集合,它里面包含了多个变量或数组,它们的类型可以相 ...

  9. C语言 结构体struct总结

    文章目录 一.前言 二.结构体的引入 三.结构体声明 四.结构体变量的定义 五.结构体变量的初始化 六.结构体变量成员的访问 七.结构体存储原理 八.结构体数组 8.1结构体数组的定义 8.2结构体数 ...

最新文章

  1. ADPRL - 近似动态规划和强化学习 - Note 4 - Policy Iteration Algorithms
  2. 深度学习 “四大名著” 发布!完整 PDF 开放下载!!!
  3. c语言程序设计实验报告2,C语言程序设计实验报告2.docx
  4. 【Alpha】Daily Scrum Meeting第八次
  5. js 调用 oc 的解释
  6. SAP WebIDE一个和Destination相关的问题 - OData下拉菜单里的Destination从哪里来的
  7. 为什么要使用反射机制
  8. 自编码器(Auto-encoder) (下)它的应用
  9. linux安装mpich
  10. oracle如何判断奇数偶数_图解面试题:如何分析中位数?
  11. 2018 CodeM复赛:B. 软件包管理器(二分)
  12. Jmeter下载安装详细步骤(2021)
  13. thinkphp vue后台管理系统模板_careyshop-admin 后台管理模板
  14. python表格绘制斜线表头_Java中使用POI在Excel单元格中画斜线—XLSX格式
  15. 一学就会的虚拟化技术之hyper-v桌面虚拟化
  16. mysql将毫秒转换为小时_将毫秒转换为天小时分钟
  17. 《Qt5:Widget、Dialog和MainWindow之间的关系》
  18. 2018 ICPC 北京区域赛 I - Palindromes(规律+大数+模拟)
  19. 会员等级进度功能前端实现
  20. %2d, %02d, %d的区别

热门文章

  1. Python编程中的常见语句
  2. 使用大白菜装机维护版软件取消Win7开机密码
  3. Oracle 企业管理器DataBase Control使用说明
  4. 允许使用计算机的软件,解决win10“你的电脑设置仅允许安装来自应用商店的应用”的方法...
  5. 数据填报不用愁,帆软报表来解忧!
  6. ABAP ALV红绿黄灯5步
  7. 推荐闪电王子和非洲王子鱼
  8. 【项目】用户可自定义简易宏键盘
  9. 快手音乐公布版权生态建设阶段战报:音乐人总结算金额提升480%
  10. css有几种选择器,有什么区别?