如何对待前缀关键字?

How to treat prefixed keywords?

我有以下解析问题。我的关键字可以用下划线作为前缀,用于停用选项、块等。

#coding: utf8
from pyparsing import Keyword, Combine, pyparsing_common, Literal, Suppress, Group, OneOrMore

test_string = r'''
keyword1list {
    keyword1 {
        option 213
    }

    _keyword1 {
        option 214
    }
}
'''

任何关键字都可能发生这种情况,此处为 keyword1listkeyword1option。我想要实现的是要么在解析过程中将这些块留在外面,要么解析它们但捕获停用前缀。

目前,我可以使用以下代码成功解析 "activated" test_string,但由于带下划线的关键字的明显原因,它失败了。

lparent = Suppress(Literal('{'))
rparent = Suppress(Literal('}'))

kw1_block = Keyword('keyword1') + lparent
kw1_block = kw1_block + Keyword('option') + pyparsing_common.number.setResultsName('option')
kw1_block = Group(kw1_block + rparent).setResultsName('keyw1')

kw2_block = Keyword('keyword1list') + lparent
kw2_block = kw2_block+ OneOrMore(kw1_block) + rparent
kw2_block = Group(kw2_block).setResultsName('keyword1list', listAllMatches=True)
result = kw2_block.parseString(test_string)
print(result.dump())
tmp = kw2_block.runTests(test_string.replace('\n', '\n'))
print tmp[0]

我目前的解决方案是,把所有的关键字都放在一个列表中,然后建立一个字典,将它们与下划线结合起来,并给它们一个标志。

#coding: utf8
from pyparsing import Keyword, Combine, pyparsing_common, Literal, Suppress, Group, OneOrMore, ZeroOrMore

test_string = r'''
keyword1list {

    _keyword1 {
        option 1
    }
    keyword1 {
        option 2
    }
    _keyword1 {
        option 3
    }
    keyword1 {
        option 4
    }
    keyword1 {
        option 5
    }
}
'''


kwlist = ['keyword1', 'keyword1list', 'option']
keywords = {}
for k in kwlist:
    keywords[k] = Keyword('_' + k).setResultsName('deactivated') | Keyword(
        k).setResultsName('activated')

lparent = Suppress(Literal('{'))
rparent = Suppress(Literal('}'))

kw1_block = keywords['keyword1'] + lparent
kw1_block = kw1_block + keywords[
    'option'] + pyparsing_common.number.setResultsName('option') + rparent
kw1_block = Group(kw1_block).setResultsName('keyword1', listAllMatches=True)

kw2_block = keywords['keyword1list'] + lparent
kw2_block = kw2_block + ZeroOrMore(kw1_block) + rparent
kw2_block = Group(kw2_block).setResultsName('keyword1list')
result = kw2_block.parseString(test_string)
print(result.dump())
tmp = kw2_block.runTests(test_string.replace('\n', '\n'))
print tmp[0]

虽然这允许正确解析所有内容,但我必须在之后重新创建逻辑(找到停用的关键字并将它们从结果中删除),我想避免这种情况。我相信我需要在带下划线的关键字上添加 parseAction 才能以某种方式删除这些标记,但我目前不知道该怎么做。

非常感谢任何帮助。

当我看到一个旨在过滤掉选定文本块的解析器时,我的第一种方法通常是编写一个仅匹配选定部分的解析器,然后将 transformString 与该解析器的抑制形式一起使用:

kwlist = ['keyword1', 'keyword1list', 'option']
to_suppress = MatchFirst(Keyword('_' + k) for k in kwlist)
kw_body = nestedExpr("{", "}") | Word(nums)

filter = (to_suppress + kw_body).suppress()
print(filter.transformString(test_string))

运行 这与您的测试字符串给出:

keyword1list {


    keyword1 {
        option 2
    }

    keyword1 {
        option 4
    }
    keyword1 {
        option 5
    }
}