Python(pyparsing):解析遗留大括号文件格式

问题描述 投票:0回答:1

我必须使用 Python (pyparse) 解析未明确定义的遗留文件格式。

它属于大括号家族(事实上,必须解析任意大括号格式是一个反复出现的问题,因为人们总是喜欢“XML 太冗长了,让我们发明自己的格式”)。

所以我有类似的东西

Variable = [1, 2]
Variable2 = {
   Variable,
   "Literal",
}

Variable[1] = Variable2

Namespace::Function(argument, {"string literal",
100})

换行符在表达式之外很重要(像 C 中的

;
那样的分隔语句),但在任何类型的大括号中都不重要(
{}
()
[]
)。

为了理解它,需要对其进行解析:

  1. 每一行都是 AST 根的子行(其中“行”指的是由换行符分隔且不在任何类型的大括号内的行)。
  2. 每种括号构成一个节点(标注括号类型)。
  3. 括号列表的子项以逗号分隔(从这个意义上说,换行符也构成一种大括号)。
  4. 任何其他内容都被视为要在另一遍中处理的单个令牌。

因此,对于上面的示例,AST 应该如下所示:

Root
 * Brace: \n
   * Token: 'Variable ='
   * Brace: []
     * Token: '1'
     * Token: '2'
 * Brace: \n
   * Token: 'Variable2 ='
   * Brace: {}
     * Token: 'Variable'
     * Token: '"Literal"'
 * Brace: \n
   * Token: 'Variable'
   * Brace: []
     * Token: '1'
   * Token: '= Variable2'
 * Brace: \n
   * Token: 'Namespace:Function'
     * Brace: ()
       * Token: 'argument'
       * Brace: {}
         * Token: '"string literal"'
         * Token: '100'

在 Python 中表示为:

[
  Brace('\n', [
    'Variable =',
    Brace('[]', ['1', '2'])
  ]),
  ...

问题是

  1. 指定解析器的语法,
  2. 将解析器的结果转换为我以后可以使用的数据结构。

(我使用了一个专用的解析器包来执行(1),但结果是(2)完全无法用于任何进一步的步骤,所以我再次尝试,这次使用

pyparsing
。)

python-3.x parsing text-parsing curly-braces
1个回答
0
投票

使用“pyparsing”解析卷曲基本格式:

  1. 定义语法:使用
    pyparsing
    创建处理变量、文字、不同类型括号
    ('[]','{}','()')
    的规则。使用
    nestedExpr
    表示嵌套结构。
from pyparsing import Word, alphas, nums, nestedExpr, quotedString, Group, ZeroOrMore, LineEnd

identifier = Word(alphas + "_", alphas + nums + "_")
literal = quotedString

square_braces = nestedExpr('[', ']', content=identifier | literal)
curly_braces = nestedExpr('{', '}', content=identifier | literal | square_braces)
parentheses = nestedExpr('(', ')', content=identifier | curly_braces)

statement = Group(identifier + '=' + (square_braces | curly_braces | parentheses))
grammar = ZeroOrMore(statement + LineEnd().suppress())
  1. 转换为 AST:使用解析操作构建抽象语法树 (AST)。定义一个
    Brace
    类来表示不同的大括号类型。
class Brace:
    def __init__(self, brace_type, children):
        self.brace_type = brace_type
        self.children = children

def create_ast_node(tokens):
    return Brace(tokens[0], tokens[1:])

statement.setParseAction(create_ast_node)
  1. 用法示例:

解析您的输入并生成 AST

input_text = """
Variable = [1, 2]
Variable2 = {
   Variable,
   "Literal",
}
"""
result = grammar.parseString(input_text)
print(result)

这种方法可以有效地解析自定义大括号格式,并将输出组织成结构化、可用的形式。我希望我的定义有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.