幻の上帝吧 关注:325贴子:3,165
  • 13回复贴,共1

关于Syntax与Grammar的区分,搞不懂啊

只看楼主收藏回复

比如说,
Lisp中规定函数调用是
(func args...)
这种形式

而C语言中是
func(args,,,)
这种形式

这个算作Syntax还是Grammar呢?
还有,如果定义了一种类似Lisp的语法:
(if bexp1 doexp1 doexp2 doexp3 ... elsif bexp2 doexp4... else doexp5...)
if else等关键词出现的顺序会影响解析的结果
出现
(if else elsif)
这种不正确输入,应该算作Syntax Error吧?
那么Syntax与Grammar具体怎么区分呢?
求给出详细的例子
@幻の上帝


IP属地:广东1楼2016-11-24 23:08回复
    我所理解的Grammar,是结合做的parser,根据你的文章臆测的。
    设定一个简单的parse格式:
    (....) 可嵌套的列表,内部的不同元由空格区别(字符串除外)
    [...] 等价于 (list ...)
    根据这个定义,可以轻松地写出psrser来生成AST
    然后根据AST进行语义分析。
    那么这个parser所依据的,是不是就是Grammar呢?


    IP属地:广东来自Android客户端4楼2016-11-24 23:58
    回复
      如果我的理解没错的话,那么又有个问题:
      如上都是我基于类Lisp语法所产生的理解,而这一理解对类C语言十分无力。
      在类C语言中,我所听到最多的词就是Grammar,很少听到Syntax。根据你的文章,Grammar表示文法,这很容易让人联想到编译前端的parser,(似乎就是来自于这里),那么语法之于类C语言,是不是就是Grammar了呢?


      IP属地:广东来自Android客户端5楼2016-11-25 00:19
      回复
        Grammar是一套规则,一般用一套formal language表示,可以描述syntax(syntactic grammar)或者semantics,但后两者严格来讲也不一定要用formal grammar描述,只要能parse得清楚的规则就是syntax,其它规则都是semantic rules。只是没有grammar描述的syntax缺乏单独存在的意义,用自然语言代替也描述不怎么清楚,又没法自动化,所以syntax经常就指示formal syntactic grammer。而semantics用grammar描述是比较困难的也不方便一般人理解(没几个语言的spec里提供了),所以多数情况下formal grammar就只有formal syntactic grammar。但这仍然不表示两者是一回事。
        Syntax不一定有明确的确定外延,取决于语言设计者的理解和对规则的严格性的要求。
        C的大部分grammar都符合严格的syntax,只有少部分需要判断semantics提供例外描述,虽然光这点就很难实现而回避了。C++就麻烦得多,没有明确的syntax能直接以formal grammar的形式确定出来,所以不要指望会有这种东西。
        Lisp方言则比较自由,因为没有规定phase of translation,可以附加约定,你要简单就简单,要复杂就复杂。


        IP属地:北京6楼2016-11-25 12:22
        收起回复
          因为一档线飞了所以中午有些话没说完。
          实际上分离边界有更现实的原因:实现的结构。
          纯粹就形式语言理论上讲,你可以构造一个自动机的来对语言进行识别,这样实现语言就成了提供解一个判定性问题的程序。
          然而现实设计不允许这样。先不论写spec的难度,即便你成功地把现实语言的形式语义分解为有限深度的判定树或者其它能够不引入副作用直接表示这个解的“简单”数据结构——有个更严重的问题:谁来实现?
          当你真的把实现语言转换成解这类问题着手解决,意味着你得连物理实现都包了——不仅包括硬件设计,还包括实现基本硬件单元的映射到语义的物理理论——显然没谁做得到。
          你不得不为语言的实现提供不属于形式语言描述的附加结构(比如说,确定“编译”还是“解释”,虽然就这点来讲未必必要)。一般从涉众角色划分来讲,语言的实现者(如编译器的作者)和其它用户是需要区别对待的,否则下场会是所有能用这个语言的用户都得会自行实现……这又不符合一般现实需要。
          对应这个现实,语言的实现分为由实现者完全负责的部分,以及可以随着用户需求迭代改进的另一部分。前者可以通过完全参数化定制的程序来简化,这种程序的输出也是完全提前确定可以做到基本上不需要更改的。这种程序就叫做parser。决定parser的规则也可以设置得很严格,这就是一般所谓的syntax了。
          其实syntax来源于自然语言的研究。笼统地来讲,由于没有设计而只有演化,确定自然语言的grammar是非常困难以至于基本是无解的。强行做出解来固化了的规则(实际上是提取一部分能说的清楚的语言子集),就叫syntax。
          人工语言可以有明确的设计,先进行syntax设计就容易得多。当然整个确定grammar也是可行的,但很少有通用语言这样做。除了我上面说过的难度大这个主要原因以外,直接确定grammar对应对需求变化不友好。于是现实中,需求容易变化的东西就配置成semantics手工调整,而syntactic rules扔给完全参数化定制(如使用parser combinator)或通过约定足够简单的规则(如S-expr)干脆直接写死不需要改动即可。


          IP属地:北京7楼2016-11-25 17:24
          收起回复
            还有一些次要原因。
            例如,实现的自由性。这里不限于严格的机器实现,也适合允许部分错误的非严格实现,典型地,就是人。这种实现的性能虽然很不咋地,却可以“容错”,而且可以随时内联历史经验优化提高的。但当syntax和表示semantics的规则过于僵死或者干脆完全没法区分时,就非常不利于这种自由了。
            举例:汉顺字序不影响阅读。
            反驳WG21 P0145很大程度上也是基于这个原因:阅读(parse)顺序和理解(evaluate)的顺序完全是两码事。有人鼓吹严格从左到右更能减少错误,但这在熟练用户看来是无稽之谈:虽然(不管是否有意识的)检查syntax(其实层次更低,一般是preprocessing token这样的lexeme)通常和自然语言一样的按字面顺序进行,但理解含义本身应该是允许并行的,这比机器实现代价小得多也要有效得多。强行要求读者从左到右理解在parsing上即是反智的行为。


            IP属地:北京8楼2016-11-25 17:35
            收起回复
              cf. pl-docs: zh-CN/about-syntax.md.
              可能仍需更新。


              IP属地:北京9楼2020-04-01 14:45
              回复