在Python中解析自定义配置格式

2024-09-27 22:19:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在为Stellaris游戏编写一个配置文件管理器,我用他们的格式撞墙了,他们用这种格式保存关于mod和设置的信息。你知道吗

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)

我没有你能看到的那么远。有人能告诉我下一步怎么走吗?我并不是要一个完整的、有效的解决方案——这会让我前进很多,但其中的乐趣何在:)


Tags: nomodui格式gui数组fixdesigner
1条回答
网友
1楼 · 发布于 2024-09-27 22:19:04

好吧,这是非常诱人的,只是潜入并编写这个解析器,但你想自己的一些乐趣,这是伟大的。你知道吗

在编写任何代码之前,先编写一个BNF。这样您就可以编写一个像样且健壮的解析器,而不仅仅是“所有不是等号的东西都必须是标识符”。你知道吗

这里有很多“something=something”位,请看“=”左右两侧的类型。左手边看起来都是非常有礼貌的标识符:字母,下划线。我也可以想象数字,只要他们不是主角。假设左边是标识符:

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

右手边是各种东西的混合体:

  • 整数
  • 浮动
  • “yes”或“no”布尔值
  • 带引号的字符串
  • 戴着牙套的东西

大括号中的“something”要么是带引号的字符串列表,要么是“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* '}'

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

从BNF到pyparsing的转换应该差不多是这里的1:1。因此,在BNF中,可以使用PLY、ANTLR或其他解析库。BNF真的值得花1/2小时或1/2天的时间来整理。你知道吗

相关问题 更多 >

    热门问题