对不起,我想不出一个更好的头衔。
问题如下:
对于我们的客户,我们创建了(作为更大的应用程序的一部分)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:用户只能使用复合材料,而不能使用命令。 复合材料在运行时动态加载(以及它们的图形设计器) 并且可能由第三方单独提供。
答案 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解决方案,您可以使用它来编译和创建字节码数组。
编写一个简单的模块,使您的C#结构可供Python使用。目标是定义允许用户使用的每个C#类(Composites或Commands或其他)作为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,无需额外的解析或词法扫描。
答案 4 :(得分:1)
要添加到S.Lott的评论,请按以下方式eval a Python script from C#
答案 5 :(得分:0)
虽然创建这种迷你语言并编写代码可能会非常有趣,但您需要提出的真正问题是:
“真正整洁”的功能有一种建立的方式,当现实可能表明这种请求的真实答案是“不”。
在继续之前,看看您是否有利益相关方愿意赞助此事。然后在最终用户检查之前查看他们真正想要的内容。
干杯,
-R