C# 我们有一个图形设计师,现在他们想要一个基于文本的设计师。建议?

C# 我们有一个图形设计师,现在他们想要一个基于文本的设计师。建议?,c#,python,scripting,parsing,embedding,C#,Python,Scripting,Parsing,Embedding,对不起,我想不出更好的标题了 问题如下: 对于我们的客户,我们创建了一个 他们可以用来构建“场景”的图形设计器 这些场景由“复合”组成,而“复合”又由 “命令”的定义。这些命令对象都派生自CommandBase和 实现一个名为ICompilable的接口 scenario类还实现了ICompilable。调用Compile()时 在命令上,返回一个字节数组,然后将其发送到设备 它们的用途(抱歉,无法透露有关该硬件的更多信息) 给你一个想法: var scenario = new Scenario

对不起,我想不出更好的标题了

问题如下:

对于我们的客户,我们创建了一个 他们可以用来构建“场景”的图形设计器

这些场景由“复合”组成,而“复合”又由 “命令”的定义。这些命令对象都派生自CommandBase和 实现一个名为ICompilable的接口

scenario类还实现了ICompilable。调用Compile()时 在命令上,返回一个字节数组,然后将其发送到设备 它们的用途(抱歉,无法透露有关该硬件的更多信息)

给你一个想法:

var scenario = new Scenario();

scenario.Add(new DelayCommand(1));
scenario.Add(new CountWithValueCommand(1,ActionEnum.Add,1));
scenario.Add(new DirectPowerCommand(23,false,150));
scenario.Add(new WaitCommand(3));
scenario.Add(new DirectPowerCommand(23,false,150));
scenario.Add(new SkipIfCommand(1,OperatorEnum.SmallerThan,10));
scenario.Add(new JumpCommand(2));

byte[] compiledData = scenario.Compile();
图形设计器从用户那里抽象出所有这些内容,并允许 他(或她)只需将en-drop复合材料拖动到设计器表面即可。 (Composites可以对命令进行分组,以便为返回的任务提供构建块)

最近我们的客户来找我们说,“设计师真的很酷, 但是我们有些人更喜欢某种编程语言, 就简单一点。”

(当然对他们来说很简单)

我非常愿意为他们提供一种简单的语言, 它可以调用各种命令,也可以用 更好的结构等

我不知道从哪里开始,也不知道我的选择是什么(不破坏我们现有的)

我听说有人嵌入Python之类的语言, 人们编写自己的语言和语法分析器等等

有什么建议吗

注:用户只使用复合材料,从不使用命令。 组合在运行时动态加载(连同其图形设计器)
并且可能由第三方在单独的组件中提供。

据我所知,您有两种选择

您可以使用XML样式的“标记”让它们定义实体及其分组,但这可能不是最好的

你的选择是肯定的,你可以嵌入一种语言,但你真的需要吗?这不是太过分了吗?你如何控制它

如果您只需要非常简单的语法,那么可以编写自己的语言。事实上,创建一个简单的解释器并不难,只要你有一个严格的、明确的语言。在你正在使用的c#中查找一些编译器示例


我在uni用java编写了一个非常简单的interperter,它并没有你想象的那么难。

对于一个简单的DSL来说,这看起来是一个完美的场景。有关详细信息,请参阅


您还可以使用lua.Net之类的脚本语言

如果您真的想要一种非常简单的语言,那么您需要一个“递归下降解析器”

例如,像这样的语言:

SCENARIO MyScenario
DELAY 1
COUNT 1 ADD 1
DIRECT_POWER 23, False, 150
WAIT 3
...
END_SCENARIO
您可能有如下语法:

scenario :: 'SCENARIO' label newline _cmds END_SCENARIO
cmds::  _delay or _count or _direct_power or...
delay:: 'DELAY' number
这会产生如下代码:

def scenario():
    match_word('SCENARIO')
    scenario_name = match_label()
    emit('var scenario = new Scenario();')
    cmds()
    match_word('END_SCENARIO')
    emit('byte[] ' + scenario_name + ' = scenario.Compile();')

def delay():
    match_word('DELAY')
    length = match_number()
    emit('scenario.Add(new DelayCommand('+ length +'))')

def cmds():
    word = peek_next_word()
    if word == 'DELAY':
       delay()
    elif ...

这里有一个Pythonic解决方案,用于构建DSL,您可以使用它编译和创建字节码数组

  • 编写一个简单的模块,使您的C#结构可用于Python。目标是将允许用户使用的每个C#类(组合或命令或其他)定义为Python类

    通常,这涉及到实现一组最小的方法,这些方法具有从C#类型到本机Python类型的不同转换,反之亦然

  • 编写一些演示,展示如何使用这些Python类定义创建脚本。您应该能够在Python中创建这样的东西

    import * from someInterfaceModule
    scenario= Scenario(
        Delay(1),
        Repeat( Range(10),
            DirectPower( 23, False, 150),
            Wait(3),
            DirectPower( 23, False, 150)
        )
    )
    scenario.compile()
    
  • 这些是相对简单的类来定义。这里的每个类都很容易实现为直接调用基本C#模块的Python模块


    语法是纯Python的,不需要额外的解析或词法扫描。

    要添加到S.Lott的评论中,下面是您如何创建这种小型语言并编写代码的过程。

    虽然创建这种小型语言可能会非常有趣,但您需要问的真正问题是:

  • 添加此功能/设施的业务案例是什么
  • 谁来为这个功能付费
  • 如果您构建了此功能,谁将“注销”它
  • “真正整洁”的特性有一种构建的方式,而现实可能表明对这样一个请求的真正答案是“不”

    在继续之前,看看您是否有利益相关者愿意对此进行赞助。然后在提交到项目之前,与最终用户核实一下,看看他们真正想要什么

    干杯


    -R

    这难道不要求我们购买某种许可证并使用特殊版本的VS.NET吗(这里可能完全错了……我有一本关于DSL的书,但不清楚如何使用许可证)我认为不需要任何特殊版本的VS.NET,因为DSL工具是SDK的一部分,不是VS.NET。但我必须向客户部署VS.NET?我可能也有一些代码,等我回到我的PC时我会检查他们是否愿意付款。。。这意味着我们愿意实施:p他们明确要求(在最初的计划制定后:p)