设计用于记录和传输树木的C DSL

设计用于记录和传输树木的C DSL,第1张

概述简而言之 我正在尝试为C库设计一个更好的C接口,它通过通信通道发送树状表达式(àlaiostreams vs stdio).我不确定是否有可能在C中设计一个DSL来记录这些树,同时避免运行时开销,如果是的话,如何. C库的简化说明 有一个C库可以通过通信通道发送“表达式”.这里的“表达式”表示可以以类似于函数调用的方式方便地表示的树结构. 例如, f(1, 2, g(3), "foo") 表示这棵 简而言之

我正在尝试为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所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1224788.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存