【问题标题】:Is there a (simple) way to modify the syntax of some particular programming language?有没有一种(简单的)方法来修改某些特定编程语言的语法?
【发布时间】:2020-05-12 16:48:19
【问题描述】:

这个问题可能很幼稚,所以请随时向我提出澄清。我是从数学背景进入计算机科学的,所以人们一直告诉我,像 Haskell 这样的函数式编程语言对我来说感觉很自然,但我发现很多语言(不仅仅是函数式语言)的语法非常丑陋和不直观。

在 Haskell 中,举个小例子,类型声明用:: 编写,例如,

str :: String 
str = "Hello, World!"

我有什么办法可以修改我自己系统中的语法,以便:: 的功能可以由其他东西来执行,比如:::,或者可能是;;,或者更好的是:is_a:,这样我就可以执行与上述相同的功能:

str ::: String 
str = "Hello, World!"

需要明确的是,如果我修改系统中的语法,我并不担心任何关于共享代码困难的实际问题;我只是想知道理论上是否可以修改编程语言的基本语法,如果可以,如何修改。

请随时修改标签,或要求澄清。

【问题讨论】:

  • sed s/:::/::/ 可能会让你走完 99% 的路。最后 1% 的难度要大得多,但肯定是可行的,否则任何编程语言首先如何实现......?但是,我强烈建议您不要这样做。习惯表面语法比您最初想象的要容易得多。见鬼,你在数学中一直这样做,总有第一部分是“为了本文的目的,我将使用以下符号:......”,然后你只需要忍受任何选择作者为论文的其余部分制作。
  • @DanielWagner 超级有用的评论,谢谢!

标签: syntax programming-languages


【解决方案1】:

一个非常广泛的主题,您可能会在 Stack Exchange 的软件工程和计算机科学论坛中获得更详细的答案。但我会尽量给出一些建议。

很明显,我不知道你从数学到编程方面已经走了多远,所以如果这个答案的某些部分对你来说是显而易见的,请多多包涵。

如果你抛开程序员之间交换源代码的需要(实际上是一个非常大的if),你可以定义任何你想要的编程语言语法,...只要你的语法定义是 一致。问题是,确保语言的一致性一点也不简单。

这意味着:您必须能够以某种方式生成一个可执行的解析器程序,该程序可以读取使用您的新语法编写的源代码,并生成一个语法树。机器代码生成和/或直接解释执行从语法树开始。

现在是 21 世纪,您拥有诸如 Yacc/BisonLex/Flex 之类的软件工具,它们将从 您提供的语法的一些高级描述开始为您编写实际的解析器代码 strong>,通常接近于巴库斯-瑙尔形式 (BNF)。

解析器本质上是一个基于堆栈的自动机。现在,如果您的新语法有任何可能在某处不明确,您的解析器生成器工具将不会生成基于堆栈的自动机的可编译描述。相反,它会输出一些部分不清楚的错误消息,例如 shift-reduce conflict at line 413 。根据我对工作语言设计师的有限经验,他们花费了大量时间来解决语法中的 shift-reduce 冲突。

例如,您说您可能想为“;;”分配一些语义值。但是 Haskell 和许多其他编程语言一样,为单个分号分配一个既定值。它是一个指令终止符。如何确保我们在该级别避免任何和所有的歧义?通过解析器生成工具获取 BNF。这是唯一的方法。

更多详情here。深入理解问题的最佳方法是为某种迷你语言创建解析器。您可以使用经典的 Bison/Flex 工具包,它是在传统命令式语言领域产生的。或者,您可以使用 Haskell 特定工具之一,例如 Megaparsec

话虽如此,您似乎感觉到的部分丑陋可能是由于历史上只使用 ASCII 字符的必要性造成的,因为在过去,这是源代码交换的要求。为了写一个不等于,Fortran 使用了.NE。因为没有 Unicode,因此没有 '≠' 字符。 C 语言的设计者在公元 1975 年左右面临同样的问题,他们更喜欢使用“!=”。

Haskell 在公元 2020 年处于先锋地位,默认情况下仍使用单个普通 ASCII 点“。”用于函数组合,而不是数学课本中使用的适当的“∘”字符。修复它可能需要很长时间。

【讨论】:

    【解决方案2】:

    重新定义编程语言的语法绝对是可能的。在这种情况下,您所做的是发明一种新的编程语言,它具有与原始语言相同的功能,但语言结构的语法不同。

    这不是一件很简单的事情,但这里有两种可能的方法:

    预处理器/翻译器

    您可以编写一个程序,以新语法读取文件,对其进行解析,然后将其翻译成具有原始语言的文件。此时可以使用原始编译器/解释器。

    这种方法的主要优点是您只需要提供翻译。其他一切都可以重复使用。

    主要缺点是您仍然会有大部分错误消息(例如类型错误)指向翻译,并提及原始语言的语法。您也许可以将它们翻译回来,但这取决于语法的不同程度。

    fork 语言实现

    没有什么能阻止您下载 GHC 源代码(或 GCC,或...)并修改其解析器和漂亮的打印机以使用新语法。您必须在大量文件中找到合适的位置进行修改,但这是可以做到的。

    这里的主要缺点是,每当发布新版本的 GHC 时,您都必须重新合并更改,或者坚持使用旧版本。

    结论

    有一个好的语法很好,但不是那么重要。现在的 PL 理论研究人员从不讨论句法问题,而只讨论语义问题:新特性、新类型、新优化等。

    如果您愿意,可以随意修改任何语言的语法。这可能是一个有趣的项目——一种挑战自己理解大型代码库的方式,足以在各处进行一些更改。但是请记住,其他人很可能不想阅读用您自己的语法编写的代码:周围已经有很多语言,为已知语言学习新语法可能被视为浪费精力,这可以用来学习一些真正新的东西。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-15
      • 2018-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多