符合规格/ AST的规格

时间:2017-01-16 23:31:31

标签: clojure clojure.spec

我有一个DSL规范,它是一个像往常一样的序列(cat)。我想利用spec的解析(即conform ing)来获得符合我的DSL的表达式的AST。 E.g。

user> (s/def ::person (s/cat :person-sym '#{person} :name string? :age number?))
=> :user/person
user> (s/conform ::person '(person "Henry The Sloth" 55))
=> {:person-sym person, :name "Henry The Sloth", :age 55}

既然它已被解析并且我有我的AST,我会想用它做有趣的事情,所以我想测试它和诸如此类的东西。所以现在我需要为那个AST写一个规范,这基本上就是复制了一切。实际上它更糟比因为现在我必须s/def规范我之前不需要的谓词,因为keys的文档说:“没有通过设计支持内联值规范。“ /“规范的(强制执行的)意见是,与命名空间关键字相关联的值的规范,例如:my.ns / k,应该在该关键字本身下注册。”所以重复(省略person-sym部分):

user> (s/def ::name string?)
=> :user/name
user> (s/def ::age number?)
=> :user/age
user> (s/def ::person-ast (s/keys :req-un [::name ::age]))
:user/person-ast

现在它似乎兼容:

user> (s/conform ::person-ast (s/conform ::person '(person "Henry The Sloth" 55)))
=> {:person-sym person, :name "Henry The Sloth", :age 55}

在实践中,我当然有更复杂的数据,我想知道该怎么办? AFAIK规范没有给我它创建的AST的规范(实际上我个人认为这是它应该做的事情)。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

我现在说你有两种选择 - 一种是做你正在做的事情,并为之前/之后创建两套规格。

另一种选择是在数据中创建域模型并生成两个规范(我见过很多人都在做这样的事情)。

我没有听过Rich谈论生成符合结果的输出规范,所以我认为这不太可能出现在当前的路线图中。