简单说两句
前段时候看编译过程好好的,突然冒出文法这么个词,真的没有一丝防备,就这么冷不丁的出现在教材了。
由于太过抽象和枯燥,当时真有种脚板抓地的感脚,连忙把pdf往后翻了几页,奈何十几页都在讲什么正规式、正规集、规约,反正翻完满脑子都是符号。
更让人痛不欲生的是,关于这方面知识百度也搜不出什么内容,搜出来的零星信息也是孤立的,没有和编译过程有机地结合起来。
没办法,只能一点点地啃教材,至于那几页翻了多少遍真有些记不清了,反正晚上睡觉早上起大早都在想:文法究竟是个啥?有什么用?
煎熬的过程省略一万个字。。。。
文法
皇天不负有心人~~
让我看到了这么一段:
看到这里对布尔型的定义,我才隐约感觉到:可以用这种方式来检查某个语义是不是布尔型。
如果把左边的E想象成一个类型,而不是具体的值,你看,两个布尔做“与或非”结果仍是布尔型,把布尔型用单括号括起来以及单纯的true/false也是布尔型,两个数比较的结果还是布尔型。
所以说文法,就是一个规则,来描述一种类型应该满足的条件。
比如说词法分析中,我们要把代码中的字符给剥离出来放到符号表中。
那就必须告诉编译器哪些字符应该算作保留字,哪些应该算标识符,比如把±*/这样的字符串看成运算符,把什么if else while 看作保留字(以具体语言为准)。
根据这个定义,我们可以认为begin、end等为保留字,abc、abc123、abc1231def为标识符。
那这破玩意儿与文法又有什么关系呢?
比如:
<保留字> -> begin | end | while
说明遇到begin、end、while就可以认为是保留字,那我们也可以分开写:
保留字 -> begin, 保留字 -> end, 保留字 -> while
如果把保留字记为A,begin、end、while等记为a,那这一类表达式的语法就可以定义为:
A -> a
再比如:
标识符 -> 字母 | 字母<字母数字>
字母数字 -> 字母 | 数字 | 字母<字母数字> | 数字<字母数字>
我们这样写:
标识符 -> 字母,标识符 -> <标识符>字母
同样把标识符记为A,字母记为a,则标识符又可以定义为:
A -> a, A -> Aa
那么,上面这种A ->a, A ->Aa(或A ->aA)的写法,恰恰是3型文法的定义:
总结
由此,我们可以通俗地理解一波,文法就是产生式的语法,如词法分析使用第3类文法,则所有关于词法分析的产生式都应该满足3型文法的规范。
当然了,在语法分析中我们同样使用了文法,只不过用的是2类文法,所以语法产生式满足的语法便是另一种形式了。
所以说,只要我们针对某一语言定义了一整套关于词法和语法的文法,便能产生任何满足条件的语句,换句话说,如果代码中的字符和语法不满足定义的文法和产生式,则编译不通过。
也是这个时候,才真正理解了这句话的含义了。
即,文法定义产生式,产生式决定产生集,而任一代码上的字符或语法不过是产生集的一个子集罢了。