如何解析和 return 关键字的层次结构?
How to parse and return a hierarchy of keywords?
我要解析的命令的关键字具有层次结构,例如:
关键字 'aaa'
和 'bbb'
属于 'product1'
,'ccc'
和 'ddd'
属于 'product2'
。整体'product1'
和'product2'
属于'product'
.
当用户输入诸如 'ccc run X'
的字符串时,我希望解析器将输出作为转储的一部分:
Product: product2
我试图根据 思考如何构建这种层次结构,但似乎想不出解决方案...有人可以指出适用于此的 pyparse 元素的相关示例吗?
谢谢
我认为解析操作是将此类项目添加到令牌的最佳位置。在获取传入的标记的解析操作主体中,您只需使用标记上的字典接口即可添加新的命名结果。
我模拟了这个简单的解析器来解析你的命令:
import pyparsing as pp
cmd_prefix = pp.oneOf("aaa bbb ccc ddd")
action_expr = pp.oneOf("run hold cancel submit pause resume")
cmd_expr = (cmd_prefix("prefix")
+ action_expr("action")
+ pp.empty() + pp.restOfLine("qualifiers"))
运行 您的示例命令作为测试:
cmd_expr.runTests("""\
aaa run X
""")
给出:
aaa run X
['aaa', 'run', 'X']
- action: 'run'
- prefix: 'aaa'
- qualifiers: 'X'
我们可以向您的 cmd_expr 添加解析操作,以使用额外的条目来美化结果。为了保持代码和数据的分离,这里是一个字典,它根据前缀定义了一些添加的项目:
prefix_items = {
'aaa': {'Product': 'product1', 'Material': 'paper', },
'bbb': {'Product': 'product1', 'Material': 'wool', },
'ccc': {'Product': 'product2', 'Material': 'wood', },
'ddd': {'Product': 'product2', 'Material': 'plastic', },
}
并且此解析操作会将它们添加到解析结果中:
def add_prefix_items(tokens):
# find dict of items to add
adders = prefix_items.get(tokens.prefix, {})
# for each key-value in dict, add to the parsed tokens
for name, value in adders.items():
tokens[name] = value
cmd_expr.addParseAction(add_prefix_items)
这里还有一些测试和输出:
cmd_expr.runTests("""\
aaa run X
ddd hold Z
eee resume A
""")
给出:
aaa run X
['aaa', 'run', 'X']
- Material: 'paper'
- Product: 'product1'
- action: 'run'
- prefix: 'aaa'
- qualifiers: 'X'
ddd hold Z
['ddd', 'hold', 'Z']
- Material: 'plastic'
- Product: 'product2'
- action: 'hold'
- prefix: 'ddd'
- qualifiers: 'Z'
eee resume A
^
FAIL: Expected aaa | bbb | ccc | ddd (at char 0), (line:1, col:1)
如果此列表变长,您可能最终不得不从某种数据库中读取它。这是一个内存数据库的小例子(使用我的另一个开源库 littletable):
import littletable as lt
# create simple in-memory database table, indexed by item
prefix_items = lt.Table().create_index('prefix').csv_import("""\
prefix,name,value
aaa,Product,product1
aaa,Material,paper
bbb,Product,product1
bbb,Material,wool
ccc,Product,product2
ccc,Material,wood
ddd,Product,product2
ddd,Material,plastic
""")
def add_prefix_items_from_table(t):
# get all entries in the table with matching key
# (in a SQL database, this would be some kind of SELECT query)
adders = prefix_items.by.prefix[t.prefix]
# for each matching record, add the item-value to the parsed tokens
for rec in adders:
t[rec.name] = rec.value
# clear previous parse action and add new one
cmd_expr.setParseAction()
cmd_expr.addParseAction(add_prefix_items_from_table)
给出与之前所示相同的结果。
我要解析的命令的关键字具有层次结构,例如:
关键字 'aaa'
和 'bbb'
属于 'product1'
,'ccc'
和 'ddd'
属于 'product2'
。整体'product1'
和'product2'
属于'product'
.
当用户输入诸如 'ccc run X'
的字符串时,我希望解析器将输出作为转储的一部分:
Product: product2
我试图根据
谢谢
我认为解析操作是将此类项目添加到令牌的最佳位置。在获取传入的标记的解析操作主体中,您只需使用标记上的字典接口即可添加新的命名结果。
我模拟了这个简单的解析器来解析你的命令:
import pyparsing as pp
cmd_prefix = pp.oneOf("aaa bbb ccc ddd")
action_expr = pp.oneOf("run hold cancel submit pause resume")
cmd_expr = (cmd_prefix("prefix")
+ action_expr("action")
+ pp.empty() + pp.restOfLine("qualifiers"))
运行 您的示例命令作为测试:
cmd_expr.runTests("""\
aaa run X
""")
给出:
aaa run X
['aaa', 'run', 'X']
- action: 'run'
- prefix: 'aaa'
- qualifiers: 'X'
我们可以向您的 cmd_expr 添加解析操作,以使用额外的条目来美化结果。为了保持代码和数据的分离,这里是一个字典,它根据前缀定义了一些添加的项目:
prefix_items = {
'aaa': {'Product': 'product1', 'Material': 'paper', },
'bbb': {'Product': 'product1', 'Material': 'wool', },
'ccc': {'Product': 'product2', 'Material': 'wood', },
'ddd': {'Product': 'product2', 'Material': 'plastic', },
}
并且此解析操作会将它们添加到解析结果中:
def add_prefix_items(tokens):
# find dict of items to add
adders = prefix_items.get(tokens.prefix, {})
# for each key-value in dict, add to the parsed tokens
for name, value in adders.items():
tokens[name] = value
cmd_expr.addParseAction(add_prefix_items)
这里还有一些测试和输出:
cmd_expr.runTests("""\
aaa run X
ddd hold Z
eee resume A
""")
给出:
aaa run X
['aaa', 'run', 'X']
- Material: 'paper'
- Product: 'product1'
- action: 'run'
- prefix: 'aaa'
- qualifiers: 'X'
ddd hold Z
['ddd', 'hold', 'Z']
- Material: 'plastic'
- Product: 'product2'
- action: 'hold'
- prefix: 'ddd'
- qualifiers: 'Z'
eee resume A
^
FAIL: Expected aaa | bbb | ccc | ddd (at char 0), (line:1, col:1)
如果此列表变长,您可能最终不得不从某种数据库中读取它。这是一个内存数据库的小例子(使用我的另一个开源库 littletable):
import littletable as lt
# create simple in-memory database table, indexed by item
prefix_items = lt.Table().create_index('prefix').csv_import("""\
prefix,name,value
aaa,Product,product1
aaa,Material,paper
bbb,Product,product1
bbb,Material,wool
ccc,Product,product2
ccc,Material,wood
ddd,Product,product2
ddd,Material,plastic
""")
def add_prefix_items_from_table(t):
# get all entries in the table with matching key
# (in a SQL database, this would be some kind of SELECT query)
adders = prefix_items.by.prefix[t.prefix]
# for each matching record, add the item-value to the parsed tokens
for rec in adders:
t[rec.name] = rec.value
# clear previous parse action and add new one
cmd_expr.setParseAction()
cmd_expr.addParseAction(add_prefix_items_from_table)
给出与之前所示相同的结果。