.NET自然语言编程/别名/(域特定语言)框架

时间:2011-02-03 21:55:51

标签: .net nlp dsl

我们目前使用ILOG BRMS for .NET来允许业务用户在我们的系统中创建逻辑,而不知道如何编程。此规则由业务用户创建(即:它是系统的一部分,而不是规范的一部分):

definitions
  set 'the letter event' to the scheduled DelinquentLetterEvent on the invoice;
  set 'final notice possibility1' to the bill date of the invoice + 36 days;
  set 'final notice possibility2' to the time of 'the letter event' + 7 days;
  set 'final notice result' to the most future date from these values {
    'final notice possibility1', 'final notice possibility2' };
then
  in the event that 'final notice result' is not a mailing date,
    change it to the next available mailing date;
  add a new FinalNoticeEvent scheduled for 'final notice result' to the invoice;

系统在.Net中执行等效操作(此处显示伪造的C#):

//variable declarations
ScheduledEvent theLetterEvent = theInvoice.GetScheduledEvent(
  KnownEventType.DelinquentLetterEvent);
DateTime noticePossibility1 = theInvoice.BillDate.AddDays(36);
DateTime noticePossibility2 = theLetterEvent.Time.AddDays(7);
DateTime[] possibilities = new DateTime[]() 
    { noticePossibility1, noticePossibility2 };
DateTime noticeResult = CustomClass.Max(possibilities);
  //actions
CustomClass2.MakeNextMailingDate(ref noticeResult);
theInvoice.AddScheduledEvent(KnownEventType.FinalNoticeEvent, noticeResult);

程序员在设计时指定每个类/方法/属性使用的文本。例如,最后一个方法的文本是:

add a new {0} scheduled for {1} to {this}

我慢慢恍然大悟,根本不需要BRMS。将规则与断言实例匹配的概念与业务用户和程序员一样陌生。我们的业务用户对SQL脚本有点熟悉(有些人对VBA有点了解),所以他们对顺序执行感到满意。

我真正想要的是一种在设计时指定文本(DSL)的方法,该方法映射到自然语言编程的类/方法/属性,最好是在BRMS之外。

这样的事情存在吗?这个概念的正确名称是什么?


对策:

我们已经考虑过编写脚本语言来广泛地满足这种需求。具体而言,它们不提供我寻求的.NET代码的文本替换/映射。   我想编写一个c#方法,然后声明一些可以调用它的合理短语。

ANTLR - 感谢小费。这是一个通用的解析器。如果我想自己实现,我将毫无疑问需要解析器。

  

根据定义,您使用专注于问题区域的高跷词汇创建的任何人工语言都是“特定领域语言”。

我觉得这句话和答案一样好,因为我可以回答我的问题。感谢。

  

如果您需要完全通用计算,那么最终将使用典型的计算机语言。如果你可以缩小范围,你可能会以有用的东西结束。

我可以将范围缩小到调用我已实现的方法,但问题是,当我添加更多方法时,我想为这些新方法附加更多词汇。

无论我们是继续使用ILOG还是其他东西作为该语言的支持基础设施,DSL都将不断发展。

2 个答案:

答案 0 :(得分:3)

实际上,你不能编写一个接受真实自然语言并将其映射到工作代码的工具。没人知道怎么做。 (因此C#而不是英语)。

你可以期待的最好的是一套不高兴的短语(很像你展示的BRML),它总是具有更好定义的优势,而且“商业用户”要学习更难,因为他们不(想)知道该说些什么开始,更不用说表达能力的极限了。根据定义,您使用专注于问题区域的笨拙词汇创建的任何人工语言都是“特定领域语言”。

真正的论点是,您的语言需要包含哪些活动范围?您的“业务”用户的教育程度如何(如果他们可以编码,我想知道他们将其描述为“业务用户”)?他们是否同意他们愿意说的事情(不打赌)。如果你需要完全通用的计算,你最终会得到一种典型的计算机语言(实际上更糟糕的是,因为你最终会对编程功能进行编播,产生一个真正丑陋的宝贝)。如果你可以缩小范围,你可能会以有用的东西结束。

问题是,你能设计出这样一种语言,它比你想要取代的BRML更好吗?用户期望能做什么? [我对ILOG的BRML有多好没有意见,但你必须假设他们已经尝试解决这个问题一段时间了,因为它们仍然存在,所以它们一定不能有一个愚蠢的解决方案]。

如果您有信心,那么您可以使用基于解析器的代码生成器工具来实现DSL。它非常实验;如果你从现在开始,你将不知道你的方法是否成功一年,它可能会失败。

良好的语言设计,无论是程序设计还是DSL,都是 hard

可行的DSL经常发生的事情是他们设法解决原始问题的一个有趣部分,其余部分以“某种方式”解决。解决这个问题的一种方法是发展DSL:新语法,新语义等;成功的DSL确实会发生这种情况。期待你的进化。另一种典型的方法是提供一些标准的转义机制(例如,某种过程调用,任意表达式......),然后有人根据需要添加额外的子程序。

即使您正确使用DSL,它也可能无法被社会所接受。 [Ada是一个非常好的语言,它被C和C ++取代,因为程序员根本不想学习它。)

答案 1 :(得分:2)

您有很多选择如何实现这一目标。我们举几个例子:

  • 集成脚本语言。你可以,例如使用VBScript或Lua。您可以为自己的对象创建包装器,并使它们可用于脚本语言。这样做的好处是已经为您实现了解析器和可执行引擎;

  • 使用XAML。 XAML是一种在XML中定义对象结构的方法。您可以使用公式的标记扩展名,以便您可以使用例如日期分配日期。 BillDate="{DateFormula +1 days}";

  • 使用ANTLR为您自己的DSL定义解析器。使用ANTLR,编写解析器相对容易。您可以从匹配的构造中创建语法中的对象。