首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >clojure.spec对象的自定义生成器

clojure.spec对象的自定义生成器
EN

Stack Overflow用户
提问于 2016-12-16 03:10:56
回答 2查看 1.1K关注 0票数 7

我刚刚在clojure.spec上看到了一个clojure.spec,我真的很想在我的项目上尝试一下。我正在编写一系列使用eclipse库解析C代码的工具,我想说明我的函数接受并发出AST对象。

我认为可以为一个函数编写一个非常基本的规范,该函数取AST的根,并像这样发射树的所有叶子:

代码语言:javascript
复制
(import '(org.eclipse.cdt.core.dom.ast IASTNode))
(require '[clojure.spec :as s])

(defn ast-node? [node] (instance? IASTNode node))
(s/def ::ast-node ast-node?)
(s/fdef leaves :args ::ast-node :ret (s/coll-of ::ast-node))

然而,当我尝试执行代码(s/exercise leaves)时,我会得到一个错误:

代码语言:javascript
复制
Unable to construct gen at: [] for:  
xxx.x$leaves@xxx  
#:clojure.spec{:path [], :form #function[xxx.xxx/leaves], :failure :no-gen}

我如何为Java对象编写一个自定义生成器来完全规范和执行我的代码?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-12-16 07:00:16

您可以使用s/with-gen将自定义生成器附加到规范。您需要编写一个生成器,生成所需的所有节点变体。您可能会发现,编写每个节点类型的一个生成器,然后将它们组合起来会更容易,可以使用s/or,也可以使用类似于s/multi-spec的东西(这将使扩展开放)。

编写生成Java对象的生成器的示例如下所示:

代码语言:javascript
复制
(s/def ::date 
  (s/with-gen #(instance? java.util.Date %)
    (fn [] (gen/fmap #(java.util.Date. %) (s/gen pos-int?)))))

fmap接受一个函数,并将它应用到生成器的每个结果中。如果有一个具有多个值的构造函数的Java对象,则可以使用像(s/gen (s/tuple int? string? int?))这样的源生成器。

票数 14
EN

Stack Overflow用户

发布于 2016-12-22 02:37:46

为了完整起见,下面是我将Alex的答案应用于规范"LiteralExpression“AST节点之后的代码:

代码语言:javascript
复制
(ns atom-finder.ast-spec
  (:import [org.eclipse.cdt.internal.core.dom.parser.cpp CPPASTLiteralExpression])
  (:require [clojure.spec :as s]
            [clojure.spec.gen :as gen]))

(def gen-literal-expression-args
 (gen/one-of
  [
   (gen/tuple (s/gen #{CPPASTLiteralExpression/lk_char_constant})
              (gen/char-ascii))
   (gen/tuple (s/gen #{CPPASTLiteralExpression/lk_float_constant})
              (gen/double))
   (gen/tuple (s/gen #{CPPASTLiteralExpression/lk_integer_constant})
              (s/gen (s/int-in -2147483648 2147483647)))
   (gen/tuple (s/gen #{CPPASTLiteralExpression/lk_string_literal})
              (gen/string))]))

(def gen-literal-expression
  (gen/fmap
   (fn [[type val]]
     (CPPASTLiteralExpression. type (.toCharArray (str val))))
   gen-literal-expression-args))

(s/def ::literal-expression
  (s/with-gen
    (partial instance? CPPASTLiteralExpression)
    (fn [] gen-literal-expression)))

(s/exercise :atom-finder.ast-spec/literal-expression 10
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41176696

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档