从自然语言认识文法 | 从零实现一门语言

  本节开始文法的内容,文法在编译器里也是比较复杂的一部分。一般编译原理的文法部分会比较晦涩,但是想要构建一个编译器,却不得不理解并使用它。

自然语言的结构

    高级编程语言的表达方式更贴近人类理解的范畴,更符合书面表达的形式。书面语言是遵从一定的语法结构的,高级编程语言的表达形式最初也是借鉴自然语言,方便理解。

    先从自然语言分析开始,以此推导高级编程语言的文法,这里选取书面语的句子作为参考,编程语言最早也是参考英语的用法。

    以句子中的主谓结构来举例:

饥饿的小明在吃苹果。他吃了最大的苹果。

    上述包含两个句子。每个句子由主语和谓语组成,即由名词短语和动词短语组成。

<句子> -> <名词短语> <动词短语>

    上述表示,句子的形式可以由名词短语和动词短语的形式代替,或者可由后者推导出,”->“ 称之为推导。

    【饥饿的小明】和【他】为名词短语,【吃苹果】和【吃了最大的苹果】为动词短语。

    以此类推,我们得到如下形式。

<名词短语> -> <形容词> <名词> <名词短语> -> <名词>

    这里我们可以看出名词短语可以由形容词加名词推导,也可以是单独的名词,所以也可以写成以下结构。

<名词短语> -> <形容词> <名词> | <名词>

    <形容词> <名词>和<名词>称为<名词短语>的产生式,用 “|” 连接起来。

<动词短语> -> <动词> <名词短语>

    【吃苹果】由动词【吃】和名词【苹果】组成,【吃了最大的苹果】由动词【吃了】、形容词【最大的】和名词【苹果】组成,由此可见,句子是一种递归结构。

<名词短语> -> <形容词> <名词短语><形容词> -> 饥饿的 <名词> -> 小明

    【饥饿的】和【小明】我们认为无法继续推导了,是组成整个句子的最小单元,称之为终结符,与此相对的为非终结符。

    上述句子的划分其实是按句号,在编程语言中判断一个句子是否结束往往采用  ”;“,是一种特殊的终结符。

于是我们可以得到一般的文法结构:​​​​​​​

 S -> Ax S -> By A -> a A -> zA B -> b b -> mB

    其中S、A、B、为非终结符,其中S为特殊的非终结符,称为开始符,a、b、m、x、y、z为终结符。可以得到下面关于文法的四元组定义:

G=(Vn,Vt,P,S)

    其中Vn为非终结符集合,Vt为终结符集合,P为产生式集合,S为开始符。

LL文法

    上述分析过程中,我们采用的是从左到右逐个字符推导的方式,直至识别一个完整的句子结束,这种分析方法称为LL文法分析。

    那么文法结构:A->zA,按照从左到右的方式,是否可以写作:A->Az ?

    如果写作后者,当读取到A非终结符时,仍然会进入A的判定规则中去,那么A的推导将一直会处于循环之中,所以在LL文法中不能出现这种推导,即不能出现左递归。如下:

S ->Sz -> Szz -> Szzz ->Szzzz ...

这里我们用到A的判定规则来阐述左递归的问题,不同的判定规则即代表不同的非终结符,在LL文法中也称为First集合,详细内容可参考相关书籍,这里不深入讨论。

    提取左公因子,例如,在下述S的推导式中:

S -> za|zb|zc|zd|zf...

    可以提取重复的左公因子,变成如下结构:

S ->zS' S' -> a|b|c|d|f...

    为方便理解,本节用自然语言来类比分析文法的构成,同时介绍了文法基本的定义和关键知识点。下节我们将进行自定义编程语言的文法分析,构建我们的语言解析规则。

欢迎关注公众号:零点码起。


     1.一个hello world的诞生

     2.词法解析器

     3.从自然语言认识文法

     4.构造文法

     5.语义分析

     6.生成中间代码

     7.函数的帧栈调用过程

     8.汇编

     9.编译和链接

     10.终于跑起来了

     11.多文件编译

     12.丰富数据类型

     13.流程控制语句

     14.编译优化算法

     15.文件读取

     16.一个线程的实现

     17.什么是锁

     18.网络编程

     19.面向对象

     20.其他规划

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值