zoukankan      html  css  js  c++  java
  • 文法设计,有一些大的修改

    上次忘了写函数的实现,只写了函数的声明。此外修改了基本语句的文法,把判断语句删除了。嗯,就是这样。

      1 //这个文件主要是用来描述当前源语言的词法结构和语法结构
      2 //当前语言是c语言的一个子集,因此里面所有的描述大家都很熟悉
      3 //注意,当前语言并不支持预处理,因为c预处理比较复杂,而且楼主能力低下,因此做不来
      4 //如果有想做预处理的同志,可以自行修改代码。
      5 //本代码完全木有任何版权,因此各位读者在使用过程中由于程序bug而造成的挂科、失恋、车祸、离婚等不良后果
      6 //楼主不负任何法律责任,钦此。
      7 //
      8 //
      9 //第一版本修改,添加函数。函数这东西老牛逼了。
     10 //下面来描述词法中的字符集
     11 //
     12 //
     13 //变量名称符:大小写字母和下划线,注意这里并不支持数字,变量名字中有数字是很不科学的,个人认为,而下划线在
     14 //使得变量名称可读这方面有很重要的作用,因此这里会支持
     15 //算术及逻辑运算符: < > <= >= == + - * & | ! ^ && || /  ~ %
     16 //赋值运算符: =
     17 //取地址运算符:$
     18 //指针运算符: @
     19 //结构体分量运算符: .
     20 //结构体指针分量运算符: ->
     21 //数组运算符: [ ]
     22 //函数运算符: ( )
     23 //内存大小运算符: sizeof
     24 //行尾界定符: ;
     25 //字符串界定符: " "
     26 //字符界定符: ' '
     27 //换行符: 
    
     28 //制表符: 	
     29 //单元界定符: ( )
     30 //空格符: 
     31 //转义字符:  说明,转义字符与其之后的那一个字符会被当作一个单元来处理,即直接输出其之后的字符
     32 //注意,转义字符只会在字符及字符串中进行使用,其他情况下会被解释为除法运算符
     33 //代码块界定符: { }
     34 //
     35 //下面来介绍一下关键字
     36 //sizeof ,大家对这个很熟悉了吧,不解释
     37 //for ,不解释
     38 //while 不解释
     39 //if 不解释
     40 //else 不解释
     41 //break 不解释
     42 //注意我这个语言取消了goto和switch,case,因为goto容易引起混乱,而switch的语法结构对我来说有点复杂,
     43 //而且这个分支结构总是能够转变为for语句加上break的模式,因此我当前就不添加了,有兴趣的人可以自己去修改
     44 //下面说的是类型关键字
     45 //int 不解释
     46 //float 不解释
     47 //long 不解释
     48 //double 不解释
     49 //char 不解释
     50 //struct 不解释
     51 //union 不解释
     52 //void 不解释
     53 //注意这里我们取消了枚举类型,因为如果对这个类型进行处理的话,会让我很烦躁
     54 //typedef也被我取消了,这东西除了少写几个字外,没啥大用途把
     55 //现在我们开始对这个做词法单元分类
     56 //注意这里我们只支持十进制和十六进制,8进制直接被忽略,
     57 //而且对于整数常量,我们默认为64位,因此对于十进制,我们支持18位数字
     58 //而对于浮点数,由于默认常量为双精度,所以我们允许,小数点后有10位,,小数点之前最多36位
     59 //这里我只是照搬c语言里面的规定,事实上,需要这么多位并要求精确计算的还是用大数来算吧。
     60 //不要指望系统自带的算术精度
     61 //constant_char:'(a-b)|(A-B)|(0-9)|
    |	|| ',事实上还有其他有关转义字符的组合,但是那些组合并没有特殊意义
     62 //所以在这里我们就不提那些组合了
     63 //这里我们将不支持科学计数法的表示
     64 
     65 //
     66 //
     67 //现在我们讨论声明和定义部分
     68 
     69 
     70 //unsigned : 0x((0-9)|(a-f)|(A-F))+|(0-9)+
     71 //sign_constant_int: -(0-9)+
     72 //
     73 //double_constant:(-)?((0-9)+.(0-9)+)
     74 //new_name: ((a-z)|(A-Z)|(-))+  ,即一个或多个合法的名称字符
     75 //
     76 //
     77 //
     78 //list_name: new_name|list_name[unsign_constant_int] 对应数组的情形
     79 //data_type_basic_body: int |char|float|double|long|unsigned  基础类型体
     80 //data_type_basic_pointer: data_type_basic *|data_type_basic_pointer * 基础类型的指针
     81 //data_type_basic:data_type_basic_body|data_type_basic_pointer 基础类型(包括指针)
     82 //data_type_struct_body: struct struct_direct_name  //结构体类型
     83 //data_type_union_body: union union_direct_name        联合类型
     84 
     85 //data_type_struct_pointer: data_type_struct_body *|data_type_struct_pointer * 结构体指针
     86 //data_type_struct:data_type_struct_body|data_type_struct_pointer                结构体类型声明头部
     87 //data_type_union_pointer:data_type_union_body * |data_type_union_pointer *        联合类型指针
     88 //data_type_union:data_type_union_body|data_type_union_pointer                    联合类型声明头部
     89 //
     90 //data_type_definition:data_type_basic|data_type_struct|data_type_union            所有的类型头部
     91 //data_type_def_phrase: data_type_definition list_name;                            内部 声明,不需要具名联合和结构
     92 //data_type_struct_anomynous: struct { in_block_def_list } new_name ;            内部结构体声明
     93 //data_type_union_anomynous:  union { in_block_def_list } new_name;                内部联合声明
     94 //in_block_def: data_type_def_phrase|data_type_struct_anomynous|data_type_union_anomynous  内部声明类型
     95 //in_block_def_list: in_block_def| in_block_def_list in_block_def                内部声明列表
     96 //data_type_struct_decl: struct new_name { in_block_def_list } ;                外部结构体声明
     97 //data_type_union_decl: union new_name { in_block_def_list };                    外部联合声明
     98 //data_type_decl_simple: data_type_definition_phrase|data_type_struct_decl|data_type_union_decl 
     99 //外部声明,包括具名联合和结构
    100 //data_type_com_list:data_type_simple|data_type_com_list data_type_simple 声明列表
    101 //data_type_decl_phrases:data_type_com_list    | function_decl                        声明头
    102 //现在开始函数声明
    103 //因为我们默认函数的返回值是有长度限制的,所以我们把返回类型限制为所有的基础类型和所有的指针类型
    104 //return_type_basic: data_type_basic_body | struct struct_direct_name | union union_direct_name  
    105 //return_type_pointer: return_type_basic * | return_type_pointer *
    106 //return_type_concrete: return_type_basic_body| return_type_pointer
    107 //return_type: void | return_type_concrete
    108 //现在开始参数列表的声明,我们把参数的类型限定为基础类型和指针类型,即与返回值一样的类型
    109 //返回值类型只包括所有基础类型及其指针及符合类型的指针
    110 //decl_arg_list_concrete: return_type_concrete new_name | decl_arg_list_concrete ; return_type_concrete new_name
    111 //decl_arg_list: void | decl_arg_list_concrete
    112 //注意我们这里采用分号作为分隔符
    113 //function_decl: return_type new_name ( decl_arg_list ) { data_instance_decl statements }//这里有两个向后引用
    114 //注意这里我们允许函数内部再声明函数的,这样就增加了构造符号表的难度。。。
    115 //当前语言的特点是所有的类型声明都需要在变量声明之前出现,但是结构体内部及联合内部声明不受此限制
    116 //现在开始变量声明部分
    117 //data_instance_decl_list : data_type_def_phrase| data_instance_decl_list data_type_def_phrase
    118 //data_instance_decl: data_instance_decl_list
    119 //至此变量声明结束
    120 //现在开始变量定义的处理
    121 //现在开始描述运算符的优先级
    122 //0级: [ ] ( ) -> . 结合性 从左到右
    123 //1级:! ~  & * - (cast)  sizeof 这些都是单目运算符,注意cast的意思是强制类型转换
    124 //2级: * / % 这些运算符都是从左到右 
    125 //3级: + - 这些也是从左到右 
    126 //4级: >> << 按道理木有结合性
    127 //5级:> < >= <= 从左到右
    128 //6级: == != 从左到右
    129 //7级: & 从左到右
    130 //8级:^ 从左到右
    131 //9级:| 从左到右
    132 //10级: && 从左到右
    133 //11级: ||从左到右
    134 //总共12级优先级,这里相对于c语言少了三个优先级,分别是条件运算符,逗号运算符和赋值运算符,
    135 //逗号和条件都是坑爹的存在,我是不想去实现他了,而对于赋值运算符,我把这个单独归类,放在文法分析里面去
    136 //对于自增以及自减运算符,这东西除了作为考试题恶心人用没啥大用途吧,
    137 //i=i+1在优化的时候总是会变成等价的自增指令,咱们何必呢
    138 
    139 
    140 //首先考虑算术优先级
    141 //我们用优先级编号来命名临时的产生式 
    142 //而且我们用左递归来完成从左到右的优先级
    143 //function_arg_type: constant| id_0
    144 //function_use_arg: function_arg_type| function_use_arg ; function_arg_type
    145 //fun_arg: void | function_use_arg
    146 //expression_0:constant|name|(expression_11)|expression_0[expression_11]|expression_0.name|expression_0->name |fun_name(fun_arg)
    147 //expression_1:expression_0|!expression_1|~expression_1|-expression_1
    148 //                |&expression_1|*expression_1|(data_type_com)expression_1|sizeof expression_1
    149 //expression_2:expression_1|expression_2 * expression_1|expression_2 / expression_1| expression_2 % expression_1
    150 //expression_3:expression_2|expression_3 + expression_2 | expression_3 - expression_2|
    151 //expression_4:expression_3|expression_4 >> expression_3| expression_4 << expression_3
    152 //expression_5:expression_4|expression_5 > expression_4| expression_5 < expression_4| expression_5 >= expression_4
    153 //                |expression_5 <= expression_4
    154 //expression_6:expression_5|expression_6 == expression_5|expression_6 != expression_5
    155 //expression_7:expression_6|expression_7 & expression_6
    156 //expression_8: expression_7|expression_8 ^ expression_7
    157 //expression_9: expression_8| expression_9 | expression_8
    158 //expression_10:expression_9|expression_10 && expression_9
    159 //expression_11:expression_10|expression_11 || expression_10
    160 //expression: expression_11
    161 //id_0: name |(id)| id_0[expression_11] | id_0.name | id_0->name 
    162 //id_1: id_0 | *id_0 |& id_0
    163 //id : id_1
    164 //statement_0: id = expression ;|fun_name(fun_arg);
    165 // simple_statements: statement_0| simple_statements statement_0
    166 //for_statement: for ( statement_0 ; expression ; statement_0 ) { statements }
    167 //while_statement: while(expression) { statements }
    168 //branch_statement: if ( expression) { statements } else { statements }
    169 //                    | if(expression) { statements }
    170 //break_statement: break ;
    171 //statement: simple_statements | break_statement | branch_statement | while_statement |for_statement
    172 //statements: statement | statements statement
    173 //
    174 //
    175 //
    176 //总的来说,一个程序分为三个部分,第一部分数据类型声明,数据类型声明的末尾是函数声明,
    177 //所有的声明按照拓扑顺序来声明
    178 //数据类型声明之后是变量声明,注意这里的变量声明还不能赋值,所以当前只是分配空间
    179 //在变量声明之后才是程序的正文,即所有的赋值语句。
    180 //注意,这里我把算术赋值与函数赋值分开来了。即不允许在算术表达式中出现函数求值。
    181 //还有一个非常需要注意的一点就是,在调用函数的时候,我们不允许算术表达式的存在
    182 //注意在赋值的时候,左边的分量只利用了前两级的运算符,因此任何带取地址和读内存运算符的都需要使用括号括起来
    183 //因为这几个与其他运算符合用的时候总是很容易引起误会,所以我这里就强制规定了
    184 //而对于右边,我就没做这个规定,但是推荐是所有的都采取这样。
    185 //在调用函数的时候,由于参数里面不允许有算术运算符及其他类似的运算符,因此所有的参数都需要提前计算好它的值
    186 //然后再传,这样就没有求值顺序的问题了,我真是太机智了。
    187 //
    188 //
    189 //接下来需要处理的是符号表的管理及各个数据类型、函数、变量的作用域的问题,这个才是大麻烦
    190 //
    191 //
    192 //
  • 相关阅读:
    使用nodejs消费SAP Cloud for Customer上的Web service
    如何在SAP Cloud for Customer自定义BO中创建访问控制
    SAP云平台运行环境Cloud Foundry和Neo的区别
    SAP成都研究院马洪波:提升学习力,增强竞争力,收获一生乐趣
    SAP Netweaver的负载均衡消息服务器 vs CloudFoundry的App Router
    写在Github被微软收购之际
    在SAP云平台的CloudFoundry环境下消费ABAP On-Premise OData服务
    Java实现 LeetCode 517 超级洗衣机
    Java实现 LeetCode 517 超级洗衣机
    Java实现 LeetCode 517 超级洗衣机
  • 原文地址:https://www.cnblogs.com/huangfeidian/p/3198912.html
Copyright © 2011-2022 走看看