文法设计,对于void的修改
//这个文件主要是用来描述当前源语言的词法结构和语法结构
//当前语言是c语言的一个子集,因此里面所有的描述大家都很熟悉
//注意,当前语言并不支持预处理,因为c预处理比较复杂,而且楼主能力低下,因此做不来
//如果有想做预处理的同志,可以自行修改代码。
//本代码完全木有任何版权,因此各位读者在使用过程中由于程序bug而造成的挂科、失恋、车祸、离婚等不良后果
//楼主不负任何法律责任,钦此。
//
//
//第一版本修改,添加函数。函数这东西老牛逼了。
//下面来描述词法中的字符集
//
//
//变量名称符:大小写字母和下划线,注意这里并不支持数字,变量名字中有数字是很不科学的,个人认为,而下划线在
//使得变量名称可读这方面有很重要的作用,因此这里会支持
//算术及逻辑运算符: < > <= >= == + - * & | ! ^ && || / ~ %
//赋值运算符: =
//取地址运算符:$
//指针运算符: @
//结构体分量运算符: .
//结构体指针分量运算符: ->
//数组运算符: [ ]
//函数运算符: ( )
//内存大小运算符: sizeof
//行尾界定符: ;
//字符串界定符: " "
//字符界定符: ' '
//换行符: \n
//制表符: \t
//单元界定符: ( )
//空格符:
//转义字符:\ 说明,转义字符与其之后的那一个字符会被当作一个单元来处理,即直接输出其之后的字符
//注意,转义字符只会在字符及字符串中进行使用,其他情况下会被解释为除法运算符
//代码块界定符: { }
//
//下面来介绍一下关键字
//sizeof ,大家对这个很熟悉了吧,不解释
//for ,不解释
//while 不解释
//if 不解释
//else 不解释
//break 不解释
//return 不解释
//注意我这个语言取消了goto和switch,case,因为goto容易引起混乱,而switch的语法结构对我来说有点复杂,
//而且这个分支结构总是能够转变为for语句加上break的模式,因此我当前就不添加了,有兴趣的人可以自己去修改
//下面说的是类型关键字
//int 不解释
//float 不解释
//long 不解释
//double 不解释
//char 不解释
//struct 不解释
//union 不解释
//unsign 代表无符号的长整数
//void 这里的void跟c里面的不同,void代表一个四字节的内容,没有格式,变量声明可以声明为void 以及他的指针形式
//跟int的用法没有差别,唯一的差别就是函数的返回值类型为void时,代表没有返回值,这是void唯一需要注意的地方
//注意这里我们取消了枚举类型,因为如果对这个类型进行处理的话,会让我很烦躁
//typedef也被我取消了,这东西除了少写几个字外,没啥大用途把
//现在我们开始对这个做词法单元分类
//注意这里我们只支持十进制和十六进制,8进制直接被忽略,
//而且对于整数常量,我们默认为64位,因此对于十进制,我们支持18位数字
//而对于浮点数,由于默认常量为双精度,所以我们允许,小数点后有10位,,小数点之前最多36位
//这里我只是照搬c语言里面的规定,事实上,需要这么多位并要求精确计算的还是用大数来算吧。
//不要指望系统自带的算术精度
//constant_char:'(a-b)|(A-B)|(0-9)|\n|\t|\0| ',事实上还有其他有关转义字符的组合,但是那些组合并没有特殊意义
//所以在这里我们就不提那些组合了
//这里我们将不支持科学计数法的表示 //
//
//现在我们讨论声明和定义部分 //unsigned : 0x((0-9)|(a-f)|(A-F))+|(0-9)+
//sign_constant_int: -(0-9)+
//
//double_constant:(-)?((0-9)+.(0-9)+)
//new_name: ((a-z)|(A-Z)|(-))+ ,即一个或多个合法的名称字符
//
//
//
//list_name: new_name|list_name[unsign_constant_int] 对应数组的情形
//data_type_basic_body: int |char|float|double|long|unsigned|void 基础类型体
//data_type_basic_pointer: data_type_basic *|data_type_basic_pointer * 基础类型的指针
//data_type_basic:data_type_basic_body|data_type_basic_pointer 基础类型(包括指针)
//data_type_struct_body: struct struct_direct_name //结构体类型
//data_type_union_body: union union_direct_name 联合类型
//data_type_struct_pointer: data_type_struct_body *|data_type_struct_pointer * 结构体指针
//data_type_struct:data_type_struct_body|data_type_struct_pointer 结构体类型声明头部
//data_type_union_pointer:data_type_union_body * |data_type_union_pointer * 联合类型指针
//data_type_union:data_type_union_body|data_type_union_pointer 联合类型声明头部
//data_type_head:data_type_basic|data_type_struct|data_type_union 所有的类型头部
//data_var_decl: data_type_head list_name; 所有的显示变量声明
//data_type_struct_anomynous: struct { in_block_def_list } new_name ; 内部结构体声明
//data_type_union_anomynous: union { in_block_def_list } new_name; 内部联合声明
//in_block_def: data_var_decl|data_type_struct_anomynous|data_type_union_anomynous 内部声明类型
//in_block_def_list: in_block_def| in_block_def_list in_block_def 内部声明列表
//data_type_struct_decl: struct new_name { in_block_def_list } ; 外部结构体声明
//data_type_union_decl: union new_name { in_block_def_list }; 外部联合声明
//data_type_decl_simple: data_type_struct_decl|data_type_union_decl
//外部声明,包括具名联合和结构
//data_type_com_list:data_type_simple|data_type_com_list data_type_simple 所有的类型声明列表 //现在开始函数声明
//因为我们默认函数的返回值是有长度限制的,所以我们把返回类型限制为所有的基础类型和所有的指针类型
//return_type_basic: data_type_basic_body | struct struct_direct_name | union union_direct_name
//return_type_pointer: return_type_basic * | return_type_pointer *
//return_type_concrete: return_type_basic_body| return_type_pointer
//return_type: void | return_type_concrete
//现在开始参数列表的声明,我们把参数的类型限定为基础类型和指针类型,即与返回值一样的类型
//返回值类型只包括所有基础类型及其指针及符合类型的指针
//decl_arg_list_concrete: return_type_concrete new_name | decl_arg_list_concrete ; return_type_concrete new_name
//decl_arg_list: void | decl_arg_list_concrete
//注意我们这里采用分号作为分隔符
//function_decl: return_type new_name ( decl_arg_list ) { code_block }//这里有两个向后引用
//注意这里我们允许函数内部再声明函数的,这样就增加了构造符号表的难度。。。
//function_decl_list: function_decl | function_decl_list function_decl 所有的函数声明
//当前语言的特点是所有的类型声明都需要在变量声明之前出现,但是结构体内部及联合内部声明不受此限制 //现在开始变量声明部分
//data_var_decl_list: data_instance_decl| data_var_decl_list data_var_decl
//至此变量声明结束
//现在开始变量定义的处理
//现在开始描述运算符的优先级
//0级: [ ] ( ) -> . 结合性 从左到右
//1级:! ~ & * - (cast) sizeof 这些都是单目运算符,注意cast的意思是强制类型转换
//2级: * / % 这些运算符都是从左到右
//3级: + - 这些也是从左到右
//4级: >> << 按道理木有结合性
//5级:> < >= <= 从左到右
//6级: == != 从左到右
//7级: & 从左到右
//8级:^ 从左到右
//9级:| 从左到右
//10级: && 从左到右
//11级: ||从左到右
//总共12级优先级,这里相对于c语言少了三个优先级,分别是条件运算符,逗号运算符和赋值运算符,
//逗号和条件都是坑爹的存在,我是不想去实现他了,而对于赋值运算符,我把这个单独归类,放在文法分析里面去
//对于自增以及自减运算符,这东西除了作为考试题恶心人用没啥大用途吧,
//i=i+1在优化的时候总是会变成等价的自增指令,咱们何必呢 //首先考虑算术优先级
//我们用优先级编号来命名临时的产生式
//而且我们用左递归来完成从左到右的优先级
//
//expression_0:char_type|constant|name|(expression_11)|expression_0[expression_11]|expression_0.name|expression_0->name |fun_name(fun_arg)
//expression_1:expression_0|!expression_0|~expression_0|-expression_0
// |&expression_0|*expression_0|(data_type_com)expression_0|sizeof (expression_0 )
//expression_2:expression_1|expression_2 * expression_1|expression_2 / expression_1| expression_2 % expression_1
//expression_3:expression_2|expression_3 + expression_2 | expression_3 - expression_2|
//expression_4:expression_3|expression_4 >> expression_3| expression_4 << expression_3
//expression_5:expression_4|expression_5 > expression_4| expression_5 < expression_4| expression_5 >= expression_4
// |expression_5 <= expression_4
//expression_6:expression_5|expression_6 == expression_5|expression_6 != expression_5
//expression_7:expression_6|expression_7 & expression_6
//expression_8: expression_7|expression_8 ^ expression_7
//expression_9: expression_8| expression_9 \| expression_8
//expression_10:expression_9|expression_10 && expression_9
//expression_11:expression_10|expression_11 \|\| expression_10
//expression: expression_11
//id_0: name |(id)| id_0[constant] | id_0.name | id_0->name |id_0[name]
//id_1: id_0 | *id_0
//id : id_1
//function_arg_type: constant| id
//function_use_arg: function_arg_type ;| function_use_arg function_arg_type ;
//fun_arg: (void)//这里代表空参数 | function_use_arg //statement_0: id = expression ;|fun_name(fun_arg);
// simple_statements: statement_0| simple_statements statement_0
//for_statement: for ( statement_0 ; expression ; statement_0 ) { statements }
//while_statement: while(expression) { statements }
//branch_statement: if (expression) { statements } else { statements }
// | if(expression) { statements }
//break_statement: break ;
//statement: simple_statements | break_statement | branch_statement | while_statement |for_statement
//statements: statement | statements statement
//code_block:data_type_com_list function_decl_list data_var_decl_list statements
//
//
//总的来说,一个程序分为三个部分,第一部分数据类型声明,数据类型声明的末尾是函数声明,
//所有的声明按照拓扑顺序来声明
//数据类型声明之后是变量声明,注意这里的变量声明还不能赋值,所以当前只是分配空间
//在变量声明之后才是程序的正文,即所有的赋值语句。
//注意,这里我把算术赋值与函数赋值分开来了。即不允许在算术表达式中出现函数求值。
//还有一个非常需要注意的一点就是,在调用函数的时候,我们不允许算术表达式的存在
//注意在赋值的时候,左边的分量只利用了前两级的运算符,因此任何带取地址和读内存运算符的都需要使用括号括起来
//因为这几个与其他运算符合用的时候总是很容易引起误会,所以我这里就强制规定了
//而对于右边,我就没做这个规定,但是推荐是所有的都采取这样。
//在调用函数的时候,由于参数里面不允许有算术运算符及其他类似的运算符,因此所有的参数都需要提前计算好它的值
//然后再传,这样就没有求值顺序的问题了,我真是太机智了。
//
//
//接下来需要处理的是符号表的管理及各个数据类型、函数、变量的作用域的问题,这个才是大麻烦
//
//
//
文法设计,对于void的修改的更多相关文章
- 我的mini_c语言文法设计
//这个文件主要是用来描述当前源语言的词法结构和语法结构 //当前语言是c语言的一个子集,因此里面所有的描述大家都很熟悉 //注意,当前语言并不支持预处理,因为c预处理比较复杂,而且楼主能力低下,因此 ...
- 测试点常用用例设计(登录、修改密码、输入框、上传视频、XSS、URL篡改)
1.无效-视频文件测试点: 视频大小过大 视频大小过小 视频名称过长 视频名称包含特殊字符 视频名称包含中文.中英混合 视频文件格式错误 视频文件重复性上传 2.有效-视频文件测试点: 选择符合要求的 ...
- SOA 实现:服务设计原则
http://www.ibm.com/developerworks/cn/webservices/ws-soa-design/ 引言 面向服务的体系结构(Service-Oriented Archit ...
- C# 报表设计器 (winform 设计端)开发与实现生成网页的HTML报表
记得2010年之前,公司的项目基本上都要用到报表,以前我们常用的方法就是针对客户的需求来定制化开发(基本上是死写代码)来实现,经常导致项目经常性的延期,因为客户的需求经常会变化,随着用户的使用认知度的 ...
- [自制操作系统] BMP格式文件读取&图形界面系统框架/应用接口设计
本文将介绍在本人JOS中实现的简单图形界面应用程序接口,应用程序启动器,以及一些利用了图形界面的示例应用程序. 本文主要涉及以下部分: 内核/用户RW/RW调色板framebuffer共享区域 8bi ...
- App 组件化/模块化之路——使用SDK的思路进行模块化设计接口
在不久之前分享一篇<App 组件化/模块化之路——如何封装网络请求框架>文章介绍了我在项目中封装网络请求框架的思路.开发一个 App 会涉及到很多网络请求 API ,例如登录注册接口.用户 ...
- C++课程设计报告总结
C++课程设计报告 学院:计算机学院 班级:计科141班 姓名:刘建伟 学号:201400814125 指导老师:王璐 C++课程设计实验报告 学号:2014008 ...
- 学校的c++程序课程设计(简单的写法 并无太多c++的特色)
好久没更新博客了,最近一直在忙,花了一天时间做出这个简陋版的课程设计, 为了储存,也为了更新,所以于今天更新我的博客. 我选的课程设计题目如下: 某某公司的设备管理系统 功能及要求描述: (1)公司主 ...
- C#设计模式(0)——设计原则
设计原则 使用设计模式的根本原因是适应变化,提高代码复用率,使软件更具有可维护性和可扩展性.在进行设计的时候,我们需要遵循以下几个原则:单一职责原则.开闭原则.里氏替代原则.依赖倒置原则.接口隔离原则 ...
随机推荐
- Foxmail 登录 qq 账号时无法登录 提示我们设置了独立密码或使用授权码登录的解决方法
Foxmail 登录 qq 账号时无法登录 提示我们设置了独立密码或使用授权码登录的解决方法 1.首先我们设置我们邮箱的类型如下图所示 2.打开网页版的qq邮箱 在设置--->账户---&g ...
- COCOS2D - JS 之JSON 解析
list 类型的json数据 var source = ["10004","1234","4","3","1 ...
- CF 某套题 O :Grid (简单BFS)
题意: 从左上角跳到右下角最少需要多少步,跳的规则为:可以向四个方向的任意一个方向跳当前格子中的步数,若跳不到右下角输出IMPOSSIBLE. 题解: BFS搜索,注意判断边界,标记. 代码: #in ...
- CSS3主要的几个样式笔记
1.边框:border-color: 设置对象边框的颜色. 使用CSS3的border-radius属性,如果你设置了border的宽度是X px,那么你就可以在这个border上使用X ...
- 17-7-20-electron中主进程和渲染进程区别与通信
老规矩,先吐槽,再记录. 今天被上司教育了将近一个小时.因为之前自动更新的模块,我认为已经完成了,但是还有一些细节没有完善好,就一直一直的被教育~ 事情全部做完,提交以后关闭issue! electr ...
- 【java NIO】服务器端读写图片的一次排错经历
上传文件方面: 一.前端 使用的是jQuery框架来上传图片,参考的是harttle大神博客:http://harttle.com/2016/07/04/jquery-file-upload.html ...
- 【UOJ #179】线性规划 单纯形模板
http://uoj.ac/problem/179 终于写出来了单纯性算法的板子,抄的网上大爷的qwq 辅助线性规划找非基变量时要加个随机化才能A,我也不知道为什么,卡精度吗? 2017-3-6UPD ...
- 【Kruskal】舒适的路线
[codevs1001]舒适的路线 题目描述 Description Z小镇是一个景色宜人的地方,吸引来自各地的观光客来此旅游观光.Z小镇附近共有N(1<N≤500)个景点(编号为1,2,3,… ...
- 【枚举】【并查集】Gym - 101243F - Vitamins
题意:有n片药,有三种颜色,白色比红色重,红色比蓝色重,给你一些它们之间的重量关系,比如1>3,2=4之类,问你它们的颜色,如果没法判断的输出?. 先并查集把等于号全缩起来,然后按照大于号建图, ...
- 【树状数组】Codeforces Round #423 (Div. 1, rated, based on VK Cup Finals) C. DNA Evolution
题意跟某道我出的等差子序列求最值非常像…… 反正询问的长度只有10种,你就建立10批树状数组,每组的公差是确定的,首项不同. 然后询问的时候只需要枚举询问串的每一位,找找这一位对应哪棵树状数组即可. ...