C# DSL 语法的想法

发布于 2024-09-01 15:36:02 字数 1030 浏览 1 评论 0原文

我正在考虑仅使用具有静态类型优势的纯 C#/.NET 4 语法来实现模板引擎

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

.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 等)。

I am thinking about implementing a templating engine using only the plain C#/.NET 4 syntax with the benefit of static typing.

Then on top of that templating language we could create Domain Specific Languages (let's say HTML4, XHTML, HTML5, RSS, Atom, Multipart Emails and so on).

One of the best DSLs in .NET 4 (if not only one) is SharpDOM. It implements HTML-specific DSL.

Looking at SharpDOM, I am really impressed of what you can do using .NET (4).

So I believe there are some not-so-well-known ways for implementing custom DSLs in .NET 4. Possibly not as well as in Ruby, but still.

So my question would be: what are the C# (4) specific syntax features that can be used for implementing custom DSLs?

Examples I can think of right now:

// 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");

For me it is really hard to come up with the syntax with least amount of noise.

Please NOTE that I am not talking about another language (Boo, IronRuby etc), neither I am not talking about different templating engines (NHaml, Spark, StringTemplate etc).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

魂ガ小子 2024-09-08 15:36:02

您是否了解T4 模板?虽然它不允许您创建 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>

显然,您必须通过创建虚拟类以外的其他方式将模型放入系统!

Are you aware of T4 Templates? While it doesn't allow you to create a DSL, it's certainly nice for generating code or other text-based artifacts, once you've got a model to work from. For example, 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"},
                                  };
#>

This quickly produced:

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

Obviously, you would have to get your model into the system some other way than creating a dummy class!

只怪假的太真实 2024-09-08 15:36:02

我猜你很熟悉 Martin Fowlers DSL 这本书,但如果不熟悉,一定要看看它。它不包含任何特定于 C# 4.0 的内容,但具有一些可供您使用的内部 DSL 的通用模式。另请参阅 C# 中的泛型类型和类型推断如何工作,LINQ 可能是使用高级语言功能来实现 DSL 的一个很好的示例。 LINQ 中还应该有一些 AST 操作,您可能也会对此感兴趣。

I would guess you are familiar with Martin Fowlers DSL book, but if not definitely look at it. It does not contain anything specific to C# 4.0, but has some general patterns for internal DSLs which you could use. Also look at how generic types and type inference works in C#, LINQ might be a good example of using advanced language features to implement a DSL. In the LINQ stuff should also be some AST manipulation, which might interest you as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文