在Python

时间:2017-05-16 10:25:04

标签: python pyparsing stellaris

我正在为Stellaris游戏编写一个概要文件管理器,我用他们的格式打了一个墙,他们保留了有关模组和设置的信息。

Mod文件:

name="! (Ship Designer UI Fix) !"
path="mod/ship_designer_ui_fix"
tags={
    "Fixes"
}
remote_file_id="879973318"
supported_version="1.6"

设定:

language="l_english"
graphics={
    size={
        x=1920
        y=1200
    }
    min_gui={
        x=1920
        y=1200
    }
    gui_scale=1.000000
    gui_safe_ratio=1.000000
    refreshRate=59
    fullScreen=no
    borderless=no
    display_index=0
    shadowSize=2048
    multi_sampling=8
    maxanisotropy=16
    gamma=50.000000
    vsync=yes
}
last_mods={
    "mod/ship_designer_ui_fix.mod"
    "mod/ugc_720237457.mod"
    "mod/ugc_775944333.mod"
}

我认为pyparsing会在那里提供帮助(而且可能会有所帮助)但是我已经做了很长时间了,因为我实际上做了这样的事情,而且我一无所知。

我必须提取简单的key=value,但我很难实际从那里移动以提取数组,更不用说多级数组了。

lbrack = Literal("{").suppress()
rbrack = Literal("}").suppress()
equals = Literal("=").suppress()

nonequals = "".join([c for c in printables if c != "="]) + " \t"

keydef = ~lbrack + Word(nonequals) + equals + restOfLine

conf = Dict( ZeroOrMore( Group(keydef) ) )
tokens = conf.parseString(data)

我没有走得太远,你可以看到。有人能指出我下一步吗?我并不是要求一个完整且有效的解决方案 - 它会让我前进很多,但那里的乐趣在哪里:)

1 个答案:

答案 0 :(得分:1)

嗯, 非常诱人,只是潜入并编写这个解析器,但你想要为自己带来一些乐趣,这很棒。

在编写任何代码之前,请写一个BNF。这样你就可以编写一个体面而强大的解析器,而不仅仅是"所有不是等号的东西都必须是一个标识符"。

有很多" something = something"在这里,看看' ='的右侧和左侧的事物种类。左侧所有看起来都非常有礼貌的标识符:alphas,underscores。我也可以设想数字,只要它们不是主角。所以,让我们说左侧是标识符:

identifier_leading = 'A'..'Z' 'a'..'z' '_'
identifier_body = identifier_leading '0'..'9'
identifier ::= identifier_leading + identifier_body*

右手边是各种各样的东西:

  • 整数
  • '是'或者没有'布尔值
  • 引用字符串
  • 大括号中的东西

"大括号中的东西"可以是带引号的字符串列表,也可以是' identifer = value'对。我将跳过定义浮点数和整数以及引用字符串的可怕细节,让我们假设我们已经定义了这些:

boolean_value ::= 'yes' | 'no'
value ::= float | integer | boolean_value | quoted_string | string_list_in_braces | key_value_list_in_braces
string_list_in_braces ::= '{' quoted_string * '}'
key_value ::= identifier '=' value
key_value_list_in_braces ::= '{' key_value* '}'

在完全定义之前,您必须使用排序Forward来声明value,因为它在key_value中使用,但key_value用于key_value_list_in_braces 1}},用于定义value - 递归语法。您已经熟悉Dict(OneOrMore(Group(named_item)))模式,这应该很好地为您提供可通过名称访问的字段结构。对于identifierWord可以使用,或者您可以使用去年作为pyparsing_common.identifier命名空间类的一部分引入的预定义pyparsing_common

从BNF到pyparsing的翻译应该从这里开始一比一步。就此而言,从BNF中,您也可以使用PLY,ANTLR或其他解析库。 BNF真的值得花半小时或半天才能整理出来。