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

时间:2008-11-04 21:39:37

标签: c# python scripting parsing embedding

对不起,我想不出一个更好的头衔。

问题如下:

对于我们的客户,我们创建了(作为更大的应用程序的一部分)a 他们可以使用图形设计器来构建“场景”。

这些场景由“复合材料”组成,而“复合材料”又包含在内 “命令”这些命令对象都来自CommandBase和 实现一个名为ICompilable的接口。

方案类还实现了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();

图形设计师从用户那里抽象出所有这些并允许 他(或她)只需将复合材料拖到设计师表面上即可。 (Composites可以对命令进行分组,以便我们可以为返回任务提供构建块)

最近我们的客户来找我们说:“设计师真的很酷, 但我们有些人宁愿拥有某种编程语言, 只是简单的事情。“

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

我非常想为他们提供一种简单的语言, 可以调用各种命令,也可以替换SkipIfCommand 一个更好的结构等...

我不知道从哪里开始或我的选择是什么(不破坏我们拥有的东西)

我听说有人嵌入Python等语言, 人们用自己的语言编写解析器等等......

有什么建议吗?

PS:用户只能使用复合材料,而不能使用命令。     复合材料在运行时动态加载(以及它们的图形设计器)     并且可能由第三方单独提供。

6 个答案:

答案 0 :(得分:4)

据我所知,我知道你有两个选择

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

你的选择是肯定的,你可以嵌入一种语言,但是你真的需要,不会有点矫枉过正,你怎么能控制它呢?

如果您只需要非常简单的语法,那么也许可以编写自己的语言。只要你有一个严格的,明确的语言,它实际上并不难创建一个简单的解释器。查看一些编译器的例子,无论你使用什么,c#?

我在大学的java中写了一个非常简单的插图工具,它并不像你想象的那么难。

答案 1 :(得分:2)

对于简单的DSL来说,这看起来很完美。有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/bb126235(VS.80).aspx

您还可以使用脚本语言,例如lua.Net。

答案 2 :(得分:2)

如果你真的只想要一个简单易懂的语言,你需要一个'递归下降解析器'。

例如,这样的语言:

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 ...

答案 3 :(得分:1)

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

  1. 编写一个简单的模块,使您的C#结构可供Python使用。目标是定义允许用户使用的每个C#类(Composites或Commands或其他)作为Python类。

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

  2. 编写一些很好的演示文稿,演示如何使用这些Python类定义来创建脚本。你应该能够在Python中创建这样的东西。

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

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

答案 4 :(得分:1)

要添加到S.Lott的评论,请按以下方式eval a Python script from C#

答案 5 :(得分:0)

虽然创建这种迷你语言并编写代码可能会非常有趣,但您需要提出的真正问题是:

  1. 添加此功能/设施的业务案例是什么?
  2. 谁将为此功能付费?
  3. 如果您构建此功能,谁将“签字”?
  4. “真正整洁”的功能有一种建立的方式,当现实可能表明这种请求的真实答案是“不”。

    在继续之前,看看您是否有利益相关方愿意赞助此事。然后在最终用户检查之前查看他们真正想要的内容。

    干杯,

    -R