繁体   English   中英

在pyparsing中根据语法生成字符串

[英]generate string as per grammar in pyparsing

我在pyparsing中定义了一个语法

OCB, CCB, SQ = map(Suppress, "{}'")
name = SQ + Word(printables, excludeChars="{},'") + SQ
_name = CaselessKeyword("name").suppress()
_interface = Keyword("Component").suppress()
interface = Group(_interface + OCB + _name + name("interface_name") + CCB)
system = OneOrMore(interface + Optional(",").suppress())("interfaces")

如果我有一个输入字符串:

model = "Component { name '/comp1' }, 
         Component { name '/comp2' }"
result = system.parseString(model)
print(result.dump())

解析结果如预期:

[['/comp1'], ['/comp2']]
- interfaces: [['/comp1'], ['/comp2']]
  [0]:
    ['/comp1']
    - interface_name: ['/comp1']
  [1]:
    ['/comp2']
    - interface_name: ['/comp2']

我想知道是否有办法根据上面提到的语法生成字符串。 由于唯一的“变量”是comp1comp2 ,我需要一个 function 来生成文本:

def generate_string(comps: list):
    # do something
    return result

generate_string的结果(也许使用originalTextFor ?)应该是:

"Component { name '/comp1' }, Component { name '/comp2' }"

我已经看到了要编辑手动插入ParseResults的示例。 但他们不使用语法

我理解这个问题,所以您想从解析结果中生成字符串。 如果这是您想要的,我有一个有趣的解决方案。

from pyparsing import *

def to_string_parse_action(to_string_function):
  def parse_action(s, loc, toks):
    return toks, lambda : to_string_function(toks)
  return parse_action

OCB, CCB, SQ = map(Suppress, "{}'")
name = SQ + Word(printables, excludeChars="{},'") + SQ
_name = CaselessKeyword("name").suppress()
_interface = Keyword("Component").suppress()
interface = Group(_interface + OCB + _name + name + CCB)
system = OneOrMore(interface + Optional(",").suppress())("interfaces")

def name_to_string(toks):
  return "name '" + toks[0] + "'"

def interface_to_string(toks):
  result = "Component { " + toks[0][0][1]() + " }"
  return result
  
def system_to_string(toks):
  result = ""
  first=True
  for interface, interface_to_string_function in toks:
    if not(first):
     result = result + ", "
    first = False
    result = result + interface_to_string_function()
  return result

name.setParseAction(to_string_parse_action(name_to_string))
interface.setParseAction(to_string_parse_action(interface_to_string))
system.setParseAction(to_string_parse_action(system_to_string))

model = "Component { name '/comp1' }, \
         Component { name '/comp2' }"
         
results = system.parseString(model)

for result, result_to_string in results:
  print(result_to_string())

我无法想象这会是什么好事。 但这对我来说是一个有趣的练习。 它有效。 如果您解析某些内容然后调用 result_to_string,则会重新生成一个字符串。

这个想法是通过创建字符串的整个解析过程传递函数。 在解析结束时,您有一个 to_string function 用于解析结果。 您调用它,它会递归调用集成的 to_string 函数。

解析操作通常具有创建标记的目的。 在我的版本中,它的目的是与生成字符串的 function 一起创建令牌。

您只需要在设置解析操作时编写一个to_string function 并调用to_string_parse_action即可。 rest 与您的代码几乎没有变化。

奇怪的是,它不适用于结果名称。 因此,我已将其从您的示例中删除。 但是应该可以将这种机制也与结果名称一起使用。 抱歉,我没有找到解决方案。

另一个缺点是解析结果变得更加复杂,因为现在它们包含所有这些函数。 我假设您想要执行所有这些操作,因为您想要创建人工解析结果,然后让它们生成字符串。 如果这是您想要的,您现在还必须生成 to_string 函数,这使得一切都更加努力。 但是应该有很多替代方法来做不同的事情,例如通过使用具有适当构造函数的类或使用命名约定。 我在这里只说明这个想法。

如果需要,可以删除 lambda 和to_string_parse_action中的 toks 参数。 然后你必须在任何地方都明确地调用 function 。 例如,最后一行将是

print(result_to_string(result))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM