是否有针对clojure的语言规范?在EBNF或类似的东西中精确定义词法语法和语法的东西?
我能找到的最接近的是clojure website,但这并不完全符合语言规范的要求(尽管它是一个非常好的资源)。如果没有规格,我们的BDFL是否提到了任何一个计划?
这是您可能找到的官方Clojure EBNF最接近的事情。
在Eclipse插件linked by fogus中的语法Counterclockwise已不再被该项目使用并已被删除。
Clojure.g4
,ANTLR语法有关Clojure的更新的ANTLR语法,请参阅Clojure.g4
的permalink(grammars-v4),这是“为ANTLR v4编写的语法”的集合。 Clojure.g4
体积小,易于阅读,它在过去成功解析了Compojure和clojure.core
,但这并不能保证它能正确解析所有Clojure代码。
LispReader.java
Clojure语法的最具说服力的规范是Clojure’s source code本身。 Clojure不使用抽象语法,只使用自定义解析器,但在仔细研究解析器的实现后,您可以理解语法。这是Clojure的解析器:LispReader.java
(permalink)。
LispReader.java
使用the same directory中其他文件中的一些类,例如LineNumberingPushbackReader
,但大多数代码都在该文件中。在LispReader
,主要功能是read
。 read
使用isWhitespace
来忽略空格和逗号。它还可以检测数字,并解析为readNumber
。对于大多数其他符号,例如(
和#
,read
将解释交给macros
and dispatchMacros
arrays中的物体。您可以从那里按照代码。
还有一个叫做LispReader.java
的clojure.tools.reader的Clojure重新实现。 Its source code可能比LispReader
更容易阅读,因为它是在Clojure中,而不是Java。 clojure.tools.reader有一些differences from LispReader.java
,它们大多能够读取为Clojure提出的一些较小的额外语法并更好地处理错误。
没有语言规范。如果将来有任何计划,我还没有听说过。
我们来看一两个语法错误:
user=> (defn)
Syntax error macroexpanding clojure.core/defn at (REPL:1:1).
() - failed: Insufficient input at: [:fn-name] spec: :clojure.core.specs.alpha/defn-args
和
user=> (fn [3]) Syntax error macroexpanding clojure.core/fn at (REPL:1:1).
(3) - failed: Extra input at: [:fn-tail :arity-1 :params] spec: :clojure.core.specs.alpha/param-list
3 - failed: vector? at: [:fn-tail :arity-n :params] spec: :clojure.core.specs.alpha/param-list
很明显,现在使用clojure.spec
检查核心宏的语法(版本1.10)。如果Clojure项目中的Clojure进展,我们可以期待spec
将其范围扩展到编译器中。
关键是spec
具有完整的EBNF功能,因此源代码将包含该语言的完整EBNF。符号在Clojure - clojure.spec: Rationale and Overview中解释:
序列
序列/向量的规范使用一组标准正则表达式运算符,具有正则表达式的标准语义:
cat - a concatenation of predicates/patterns alt - a choice of one among a set of predicates/patterns * - zero or more occurrences of a predicate/pattern + - one or more ? - one or none & - takes a regex op and further constrains it with one or more predicates
这会发生什么时候?我(完全没有知情)的印象是,核心团队淹没在短吻鳄中,几乎忘记了他们打算消耗这片沼泽的初衷。
之前关于Clojure 1.9的一般术语spec
的答案已被删除。我认为它用于定义和检查宏语法是1.10的新功能。