我正在用python编写游戏,并决定为地图数据文件创建一个DSL。我知道我可以用regex编写自己的解析器,但我想知道是否有现成的python工具可以更容易地做到这一点,比如在PHP引擎中使用的re2c。
一些额外信息:
DSL只包含数据(声明性?),它不会被“执行”。大多数行看起来像:
SOMETHING: !abc @123 #xyz/123
我只需要阅读数据树。
答案 0 :(得分:12)
pyparsing给我留下了深刻的印象。作者Paul McGuire积极参与python list / comp.lang.python,对任何有关它的疑问一直非常有帮助。
答案 1 :(得分:7)
有很多Python解析工具:http://nedbatchelder.com/text/python-parsers.html
答案 2 :(得分:6)
这是一种非常有效的方法。
abc= ONETHING( ... )
xyz= ANOTHERTHING( ... )
pqr= SOMETHING( this=abc, that=123, more=(xyz,123) )
声明。易于解析。
和...
它实际上是Python。一些类声明和工作已经完成。 DSL实际上是类声明。
重要的是DSL只是创建对象。定义DSL时,首先必须从对象模型开始。稍后,您在该对象模型周围添加了一些语法。您不是从语法开始,而是从模型开始。
答案 3 :(得分:4)
是的,有很多 - 太多 - 解析工具,但标准库中没有。
从我看到的PLY和SPARK很受欢迎。 PLY就像是yacc,但是你在Python中做了所有事情,因为你在docstrings中写了你的语法。
就个人而言,我喜欢解析器组合器的概念(取自函数式编程),我非常喜欢pyparsing:你可以直接在python中编写你的语法和动作,并且很容易入手。我最终使用操作生成自己的树节点类型,而不是使用默认的ParserElement
类型。
否则,您也可以使用现有的声明性语言,如YAML。
答案 4 :(得分:2)
我已经在工作中写了类似的内容来读取SNMP通知定义并自动生成Java类和SNMP MIB文件。使用这个小DSL,我可以编写20行规范,它将生成大约80行Java代码和100行MIB文件。
为了实现这一点,我实际上只是使用直接的Python字符串处理(split(),切片等)来解析文件。我发现Pythons字符串功能足以满足我(解决)大部分(简单)解析需求。
除了其他人提到的库,如果我写的东西更复杂并需要适当的解析功能,我可能会使用ANTLR,它支持Python(和其他语言)。
答案 5 :(得分:2)
彼得,
DSL是好东西,所以你不需要为自己辩护:-)
但是,您考虑过内部DSL吗?这些有很多专业人士与外部(解析)DSL相比,他们至少值得考虑。将DSL与本机语言的强大功能混合在一起可以为您解决许多问题,并且Python在内部DSL上并不是很糟糕,with
语句很方便。
答案 6 :(得分:2)
对于您所描述的“小语言”,我使用简单的分割,shlex(注意#定义注释)或正则表达式。
>>> line = 'SOMETHING: !abc @123 #xyz/123'
>>> line.split()
['SOMETHING:', '!abc', '@123', '#xyz/123']
>>> import shlex
>>> list(shlex.shlex(line))
['SOMETHING', ':', '!', 'abc', '@', '123']
以下是一个例子,因为我不确切地知道你在寻找什么。
>>> import re
>>> result = re.match(r'([A-Z]*): !([a-z]*) @([0-9]*) #([a-z0-9/]*)', line)
>>> result.groups()
('SOMETHING', 'abc', '123', 'xyz/123')
答案 7 :(得分:1)
在声明性python的行中,我编写了一个名为'bpyml'的辅助模块,它允许您以更加XML结构的方式在python中声明数据,而不需要详细标记,它也可以转换为XML或从XML转换,但是有效蟒。
https://svn.blender.org/svnroot/bf-blender/trunk/blender/release/scripts/modules/bpyml.py
使用示例 http://wiki.blender.org/index.php/User:Ideasman42#Declarative_UI_In_Blender