[英]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']
我想知道是否有辦法根據上面提到的語法生成字符串。 由於唯一的“變量”是comp1
和comp2
,我需要一個 function 來生成文本:
def generate_string(comps: list):
# do something
return result
generate_string
的結果(也許使用originalTextFor
?)應該是:
"Component { name '/comp1' }, Component { name '/comp2' }"
我理解這個問題,所以您想從解析結果中生成字符串。 如果這是您想要的,我有一個有趣的解決方案。
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.