我正在尝试为C库设计一个更好的C接口,它通过通信通道发送树状表达式(àlaiostreams vs stdio).我不确定是否有可能在C中设计一个DSL来记录这些树,同时避免运行时开销,如果是的话,如何.
C库的简化说明
有一个C库可以通过通信通道发送“表达式”.这里的“表达式”表示可以以类似于函数调用的方式方便地表示的树结构.
例如,
f(1,2,g(3),"foo")
表示这棵树:
你们当中有些人可能会认识到Mathematica,但我决定将其排除在外,因为这与问题无关.
我们将f称为head,将1,g(3)称为参数.
要发送此表达式,我们将编写以下内容:
puthead("f" /* name */,3 /* argument count */); putInteger(1); putInteger(2); puthead("g" /* name */,1 /* argument count */); putInteger(3); putString("foo");
题
是否可以使用以下功能为此设计更方便的C API?
>写得更简洁(想想iostreams vs stdio)
>不需要明确指定每个头的参数计数;而是使用一个方便的符号(类似于上面的f(1,g(3))),从中自动推断出参数计数
>实现(2)没有运行时开销(即在编译时推断参数计数)
>必须在幕后使用上述C接口
我可以(1)使用类似于流的接口(即,不需要显式指定每个参数的Integer,String等的类型).我可以通过涉及额外运行时计算的方式来做(2).但鉴于C的特点,我不知道(2)/(3)是否可能在一起.最后,我想在C本身中为这些表达式提供方便的表示法.
那么是否可以在C中为此设计DSL,同时避免所有运行时开销?如果有,怎么样?我不一定在寻找一个完整的解决方案,只需要代码作为答案,只需要一些指导即可开始,或者总结可能有效的方法.
解决方法 我可以想到几种用C表示树的方法.其中一些(#1,#2)的实现将涉及构建中间结构,然后在最后调用C函数.其他(#5,#6)可以随时调用C函数,因为任何节点的子节点数在编译时都是已知的.1)使用流畅的界面和重载:
Tree() .head("f") .put(1) .put(2) .head("g") .put(3) .end() .put("foo") .end();
2)或者,无需调用end():
head("f") .put(1) .put(2) .put(head("g") .put(3)) .put("foo");
3)使用运算符<<:
Tree("f") << 1 << 2 << (Tree("g") << 3) << "foo";
4)使用operator():
Tree("f") (1) (2) (Tree("g")(3)) ("foo")
5)使用std :: initializer_List,其中Node是可以从int和std :: string隐式转换的类型:
Tree { "f",{ 1,{ "g",{ 3 } } "foo",} }
6)使用可变参数模板:
head("f").put( 1,head("g").put(3) "foo");总结
以上是内存溢出为你收集整理的设计用于记录和传输树木的C DSL全部内容,希望文章能够帮你解决设计用于记录和传输树木的C DSL所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)