我有一种可以翻译成 SQL 的领域特定语言。我必须编写自己的词法分析器、解析器和代码生成器,还是有可以帮助我的工具?
6 回答
您可能想阅读这本书: Terence Parr 的语言实现模式,来自 The Pragmatic Programmers 系列。它是对解析、翻译和编译的全面介绍。它在很大程度上依赖于Terence Parr的 ANTLR 示例,但其通用性足以让您使用其他语言和系统。
如果您的 DSL 是为 DSL 编码器的可读性而设计的,那么是的,您需要一个词法分析器、一个解析器和一个代码生成器。
(其他答案表明,如果您“以'元语言'的语法”编写 DSL,则不需要这些机制;虽然这可能是真的,但它优化了 DSL 在元语言中的可嵌入性,而不是它的最终用户的可读性,我认为这是一个糟糕的权衡)。
不,您不必从头开始编写它们。
有很多解析器生成器(YACC、Bison、ANTLR、JavaCC)可以帮助您专注于为您的 DSL 编写语法规则;它们提供了许多低级解析机制来处理/执行您的语法规则作为解析引擎。尽管如此,您仍然必须努力将您的概念语法弯曲到特定解析器生成器的限制(LALR(1),LL(k),...)ANTLR/Bison/Yacc 将帮助您构建树;你必须做明确的工作才能做到这一点。之后,您就可以自己使用传统的解析器了。大多数人到达那里后最终都会感到惊讶(如果他们走到这一步;真实语言的解析器往往比他们预期的要多。
那是因为解析后有很多生命:符号表、代码分析、代码生成。我们的DMS Software Reengineering Toolkit旨在帮助您构建语法引擎约束最小的解析规则;自动构建树(看,妈,没有手!)并以多种方式为代码转换提供大量支持。此外,DMS 提供了一个视角和工具来支持 DSL(“你的语言”)片段和目标之间的转换,使用源/目标模式对来指定映射。对于 OP 的特定目的,可以使用 SQL2011 语法获得 DMS,为编写目标模式提供了一个很好的基线。
要阅读有关使用工具进行自动转换的更多信息,请参阅我关于语言之间翻译的 SO 讨论。
这在很大程度上取决于您将使用的语言,但 Groovy、Ruby、Scala、F# 和 Haskell 是执行此操作的好语言。
您使用哪种语言将影响您还应该使用哪些工具。
例如,您可以在 C 中执行此操作,但工作量会更大,并且对用户来说可能看起来不太好。
有些语言你需要使用工具来帮助解析器,有些语言没有工具会更好。
您可能想通读这本书,以了解更多关于 DSLs、DSLs in Action的主题。
我有一个和你类似的项目。我认为你应该看看 Xtext 和 Xtend,因为它们可以直接在 Eclipse 中使用,你可以轻松获得智能感知、语法、词法分析器。我尝试生成 SQL 代码,到目前为止它一直是一个成功的项目。
如果您使用适当的元语言(例如,Lisp),则不需要词法分析器、解析器和代码生成器。一切都已包含在内——您可以在 S 表达式之上构建您的 DSL,您可以在 Lisp 本身中生成代码的宿主部分。
即使您想要为您的 DSL 提供一种特殊的语法,也很容易将解析器嵌入到元语言中。
听起来您正在寻找像 Eli 这样的东西,它旨在接受规范并从中生成翻译器:
http://eli-project.sourceforge.net/
另一方面,您可能会很高兴使用像 ANTLR 这样的生成工具来编写解析器,并自己编写 AST 和代码生成器。
假设您的 DSL 的翻译很简单,那么编写 SQL 等高级语言的代码生成可能并不难实现。
如果是我,我会使用 ocamllex 和 ocamlyacc 在 OCaml 中编写内容,但为此您首先需要了解 OCaml。