代码之家  ›  专栏  ›  技术社区  ›  Dmytrii Nagirniak

关于c DSL语法的想法

  •  3
  • Dmytrii Nagirniak  · 技术社区  · 14 年前

    我正在考虑实施 模板化引擎 仅使用 纯C/.NET 4语法 有利于静态类型。

    然后在模板语言的基础上,我们可以 创建特定于域的语言 (比如HTML4、XHTML、HTML5、RSS、Atom、多部分电子邮件等)。

    .NET 4中最好的DSL之一(如果不是只有一个)是 SharpDOM . 它实现了特定于HTML的DSL。

    看看Sharpdom,我真的对您可以使用.NET(4)做什么印象深刻。

    所以我相信在.NET4中实现自定义DSL有一些不太知名的方法。可能没有红宝石那么好,但仍然如此。

    所以我的问题是: 可用于实现自定义DSL的C(4)特定语法功能是什么?

    我现在能想到的例子:

    // HTML - doesn't look tooo readable :)
    div(clas: "head",
      ul(clas: "menu", id: "main-menu", () => {
        foreach(var item in allItems) {
          li(item.Name)
        }
      }) // See how much noise it has with all the closing brackets?
    )
    
    // Plain text (Email or something) - probably too simple
    Line("Dear {0}", user.Name);
    Line("You have been kicked off from this site");
    

    对我来说,很难用 噪音最小 .

    请注意,我不是在谈论另一种语言(boo、ironruby等),也不是在谈论不同的模板引擎(nhaml、spark、stringtemplate等)。

    2 回复  |  直到 9 年前
        1
  •  1
  •   Gabriel Ščerbák    14 年前

    我猜你对马丁·福勒的DSL书很熟悉,但如果不一定要看的话。它不包含任何特定于C 4.0的内容,但具有一些内部DSL的通用模式,您可以使用这些模式。另外,看看C中的泛型类型和类型推断是如何工作的,Linq可能是使用高级语言特性实现DSL的一个很好的例子。在Linq中,还应该有一些AST操作,这可能会让您感兴趣。

        2
  •  2
  •   John Saunders    13 年前

    你知道吗 T4 Templates ?虽然它不允许你 创造 一个DSL,一旦您有了一个模型可以使用,它对于生成代码或其他基于文本的工件当然是很好的。例如,textmaplate1.tt:

    <#@ template debug="false" hostspecific="false" language="C#" #>
    <#@ output extension=".thml" #>
    <#@ import namespace="System.Collections.Generic" #>
    
    <div class="head">
        <ul class="menu" id="main-menu">
    <#
    foreach (var item in allItems)
    {
    #>
            <li><#= item.Name #></li>
    <#
    }
    #>
        </ul>
    </div>
    <#+
    public class DummyItem
    {
        public string Name {get;set;}
    }
    
    public List<DummyItem> allItems = new List<DummyItem>
                                      {
                                          new DummyItem {Name="Name1"},
                                          new DummyItem {Name="Name2"},
                                      };
    #>
    

    这很快产生了:

    <div class="head">
        <ul class="menu" id="main-menu">
            <li>Name1</li>
            <li>Name2</li>
        </ul>
    </div>
    

    显然,除了创建一个虚拟类之外,您还必须以其他方式将模型引入系统!