30 什么是开始编写编程语言的好资源,不是上下文无关的?

我正在寻找一种有趣的编程语言,但是我看到的大部分资源都是用于编写一种上下文无关的语言,但是我希望编写一种像 python 一样使用缩进的语言,据我所知意味着它不能是上下文无关的。

请先 登录 后评论

5 个回答

Daniel Spiewak

仅仅因为一种语言使用重要的缩进并不意味着它本质上是上下文相关的。例如,Haskell 使用了重要的缩进,并且(据我所知)它的语法是上下文无关的。

需要上下文相关语法的源代码示例可能是来自 Ruby 的以下代码段:

my_essay = << END_STR
This is within the string
END_STR

<< self
  def other_method
    ...
  end
end

另一个例子是 Scala 的 XML 模式:

def doSomething() = {
  val xml = <code>def val <tag/> class</code>
  xml
}

作为一般规则,上下文相关语言在任何精确意义上都稍微难以想象,因此不太常见。甚至 Ruby 和 Scala 也不真正算在内,因为它们的上下文敏感特性只包含该语言的一小部分。如果我是你,我会根据灵感来制定我的语法,然后再担心以后的解析方法。我想你会发现你想出的任何东西都会自然地与上下文无关,或者非常接近它。

最后一点,如果您真的需要上下文相关的解析工具,您可以尝试一些不太严格的正式技术。解析器组合器用于 Scala 的解析。它们有一些烦人的限制(没有词法分析),但它们不是一个坏工具。像 ANTLR 这样的 LL(*) 工具似乎也更擅长表达这种“临时”解析转义。不要尝试将 Yacc 或 Bison 与上下文相关的语法一起使用,它们对于轻松表达这些概念来说太严格了。

请先 登录 后评论
Scott Wisniewski

我建议您手动编写解析器,在这种情况下,包含大量空白不应出现任何实际问题。

使用解析器生成器的主要问题是很难在解析器中获得良好的错误恢复。如果您计划为您的语言实现 IDE,那么良好的错误恢复对于让 Intellisence 之类的东西正常工作很重要。 Intellisence 始终适用于不完整的句法结构,解析器越能确定用户尝试键入的结构,您可以提供的智能体验就越好。

如果您编写一个手写的自顶向下解析器,您几乎可以在任何地方实现您想要的任何规则。这使得提供错误恢复变得容易。它还将使您实现重要的空白变得微不足道。您可以简单地将当前缩进级别存储在解析器类中的变量中,并且当您在新行上遇到列位置小于当前缩进级别的标记时,可以停止解析块。此外,您可能会在语法中遇到歧义。大多数广泛使用的“生产”语言都有语法歧义。一个很好的例子是 C 中的泛型

请先 登录 后评论
Allan Wind

您读过 Aho、Sethi、Ullman:“编译器:原理、技术和工具”吗?这是一本经典的语言参考书。

/艾伦

请先 登录 后评论
Kent Quirk

如果您以前从未编写过解析器,请从简单的开始。解析器非常微妙,如果您从未研究过编程语言的结构,您可能会在编写它们时遇到各种麻烦。

阅读 Aho、Sethi 和 Ullman(被称为“龙之书”)是一个不错的计划。与其他贡献者相反,我说您应该首先使用更简单的解析器生成器,例如 Yacc 和 Bison,并且只有当您因为无法使用该工具做某事而被烧毁时,您才应该继续尝试使用 LL(* ) 像 Antlr 这样的解析器。

请先 登录 后评论
Walter Bright

简单地说,上下文无关文法不需要符号表即可正确解析代码。上下文相关的语法可以。

D 编程语言是上下文无关文法的一个例子。 C是上下文敏感的。 (比如 T*x 是声明 x 是指向 T 的指针,还是将 T 乘以 x ?我们只能通过在符号表中查找 T 来判断它是类型还是变量。)

空白与它无关。

D 使用上下文无关文法来大大简化解析它,以便简单的工具可以解析它(例如语法高亮编辑器)。

请先 登录 后评论