将类C结构文本解析为di

2024-10-01 13:31:51 发布

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

我有类似简化C语法的配置文件,例如:

Main { /* some comments */
    VariableName1 = VariableValue1;
    VariableName2 = VariableValue2;

    SubSection {
        VariableName1 = VariableValue1; // inline comment
        VariableName2 = VariableValue2;
    }

    VariableName3 = "StriingValue4";
}

节可以递归嵌套。在

如何以一种干净且“pythonish”的方式将该文件解析为dict?在

[编辑]

好的,我已经找到了pyparsing模块:),但是也许有人可以告诉你没有它怎么做。在

[EDIT2]

因为好奇,我想知道今后如何写我认为简单的手工作业。在


Tags: main配置文件语法commentinlinesomecommentssubsection
3条回答

它是一个空括号,也就是一个空格,它是一个字符串。可以使用Regexpr完成

2)编写一个简单的解析器。跳过第一个标识符和左大括号。在

解析器需要一个标识符后跟EqualSign或OpeningBrace或ClosingBrace之一。在

2.1)如果是等号,后面必须跟标识符和分号。 2.2)如果是OpeningBrace,则递归地调用解析器。 2.3)如果ClosingBrace,则从递归调用返回。在

在2.1的处理过程中,以您喜欢的方式将所需的数据输入dict。您可以在标识符前面加上封闭块的名称,例如

{"Main.SubSection.VariableName1": VariableValue1}

下面是解析器的原型代码,将在标记器之后调用。它扫描一个字符串,其中字母表示标识符,分隔符是={};,最后一个标记必须是$。在

^{pr2}$

执行时,输出:

^{3}$

证明它确实发现了巢穴。用您喜欢的任何处理替换print语句。在

您需要递归地解析它,使用这个Backus Naur表单,从parse开始:

PARSE: '{' VARASSIGN VARASSIGN [PARSE [VARASSIGN]] '}'

VARASSIGN : VARIABLENAME '=' '"' STRING '"'

VARIABLENAME: STRING

STRING: [[:alpha:]][[:alnum:]]*

因为您的结构很简单,所以可以使用谓词解析器LL(1)。在

使用像SimpleParse这样的解析器,只需向它提供EBNF定义。在

你是否有某种BNF格式的文档,不是吗?如果没有,您可以告诉下一个发明另一种配置格式而不是使用json、xml、yaml或xml的天才,除非他可以使用EBNF指定语法,否则他无权重新发明轮子。在

如果你不熟悉EBNF,写语法可能需要一些时间,但这是值得的。它将使您的代码有良好的文档记录,坚如磐石,更易于维护。在

有关其他选项,请参见pythonwiki关于Language Parsing。在

如果你想用结构分裂或者正则表达式,其他每一个做维护的开发人员都会诅咒你。在

更新:

我突然想到,如果将SectionName替换为SectionName :;替换为{},并用一对大括号将主部分括起来,这种格式will likely to be valid json。在

"Name"     = JSON Grammar
"Author"   = Arsène von Wyss
"Version"  = 1.0
"About"    = 'Grammar for JSON data, following http://www.json.org/'
! and compliant with http://www.ietf.org/rfc/rfc4627

"Start Symbol" = <Json>
"Case Sensitive" = True
"Character Mapping" = 'Unicode'

! ------------------------------------------------- Sets

{Unescaped} = {All Valid} - {&1 .. &19} - ["\]
{Hex} = {Digit} + [ABCDEFabcdef]
{Digit9} = {Digit} - [0]

! ------------------------------------------------- Terminals

Number = '-'?('0'|{Digit9}{Digit}*)('.'{Digit}+)?([Ee][+-]?{Digit}+)?
String = '"'({Unescaped}|'\'(["\/bfnrt]|'u'{Hex}{Hex}{Hex}{Hex}))*'"'

! ------------------------------------------------- Rules

<Json> ::= <Object>
         | <Array>

<Object> ::= '{' '}'
           | '{' <Members> '}'

<Members> ::= <Pair>
            | <Pair> ',' <Members>

<Pair> ::= String ':' <Value>

<Array> ::= '[' ']'
          | '[' <Elements> ']'

<Elements> ::= <Value>
             | <Value> ',' <Elements>

<Value> ::= String
          | Number
          | <Object>
          | <Array>
          | true
          | false
          | null

相关问题 更多 >