簡體   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