关于C#DSL语法的想法

时间:2010-05-17 12:17:10

标签: c# .net c#-4.0 dsl templating

我正在考虑使用普通C#/ .NET 4语法来实现模板引擎,并带来静态类型的好处。

然后,在该模板语言之上,我们可以创建特定于域的语言(比如HTML4,XHTML,HTML5,RSS,Atom,Multipart电子邮件等)。

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

看看SharpDOM,我对使用.NET(4)可以做些什么感到非常满意。

所以我相信在.NET 4中实现自定义DSL有一些不太知名的方法。可能不如Ruby,但仍然。

所以我的问题是:可以用于实现自定义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 个答案:

答案 0 :(得分:2)

您知道T4 Templates吗?虽然它不允许你创建一个DSL,但是一旦你有一个模型可以用来生成代码或其他基于文本的工件,它当然很好。例如,TextTemplate1.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>

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

答案 1 :(得分:1)

我猜你会熟悉Martin Fowlers的DSL书籍,但如果不是肯定的话。它不包含C#4.0特有的任何内容,但是您可以使用内部DSL的一些通用模式。另外,看看泛型类型和类型推断如何在C#中工作,LINQ可能是使用高级语言功能来实现DSL的一个很好的例子。在LINQ中,东西也应该是一些AST操作,你可能也会感兴趣。