加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 06:51:23 所属栏目:百科 来源:网络整理
导读:简而言之 我正在尝试为C库设计一个更好的C接口,它通过通信通道发送树状表达式(àlaiostreams vs stdio).我不确定是否有可能在C中设计一个DSL来记录这些树,同时避免运行时开销,如果是的话,如何. C库的简化说明 有一个C库可以通过通信通道发送“表达式”.这里
简而言之

我正在尝试为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");

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读