我正在用PLY编写JSON配置(即JSON格式的配置文件)解释器。
我想忽略大量的配置文件。我想忽略的一些部分包含我在文件的其他部分无法忽略的标记。
例如,我想忽略:
"features" : [{
"name" : "someObscureFeature",
"version": "1.2",
"options": {
"values" : ["a", "b", "c"]
"allowWithoutContentLength": false,
"enabled": true
}
...
}]
但我不想忽视:
"features" : [{
"name" : "importantFeature",
"version": "1.1",
"options": {
"value": {
"id": 587842,
"description": "ramy-single-hostmatch",
"products": [
"Fresca"
]
...
}]
如果名称值不是'importantFeature',我想要忽略的功能数组中还有很多其他标记。例如,重要和模糊特征中可能存在一系列值。我需要相应地忽略。
另请注意,我需要提取values
字段的某些元素,并且我希望将值字段标记化,以便我可以使用它。实际上,如果它位于importantMatch中,我想有条件地将值字段标记化。
另请注意,importantFeature只是代表最终会有十几个不同的功能,每个功能在各自的功能块中都有自己的语法。
我遇到的问题是,每个功能显然都有一个名称。我想写下这些内容:
def p_FEATURES(p):
'''FEATURES : ARRAY_START FEATURE COMMA FEATURES ARRAY_END
| ARRAY_START FEATURE ARRAY_END'''
def p_FEATURE(p):
'''FEATURE : TESTABLE_FEATURE
| UNTESTABLE_FEATURE'''
def p_TESTABLE_FEATURE(p):
'''TESTABLE_FEATURE : BLOCK_START QUOTE NAME_KEY QUOTE COLON QUOTE CPCODE_FEATURE QUOTE COMMA IGNORE_KEY_VAL_PAIRS COMMA CPCODE_OPTIONS COMMA IGNORE_KEY_VAL_PAIRS'''
def p_UNTESTABLE_FEATURE(p):
'''UNTESTABLE_FEATURE : IGNORE_BLOCK '''
def p_IGNORE_BLOCK(p):
'''IGNORE_BLOCK : BLOCK_START LINES BLOCK_END'''
然而,我遇到的问题是我不能只是“IGNORE_BLOCK”,因为带有'name'的块我在词法分析器中有一个名为'name'的标记:
def t_NAME_KEY(t): r'name'; return t
非常感谢任何帮助。
答案 0 :(得分:2)
定义正则表达式规则函数时,可以选择是否返回令牌。根据返回的内容,将忽略或考虑令牌。例如:
def t_BLOCK(t):
r'\{[\s]*name[\s]*:[\s]*(importantFeature)|(obscureFeature)\}' # will match a full block with the 'name' key in it
if 'obscureFeature' not in t:
return t
else:
pass
您可以在这些方面稍微构建规则,然后根据您的重要功能是否存在来选择是否返回令牌。
此外,将标记指定为字符串忽略的一般惯例是将t_IGNORE_
附加到名称。
基于OP的编辑。忘记在标记化期间的消除。你可以做的是,在你用语法解析它时手动重建json。例如。
替换
def p_FEATURE(p):
'''FEATURE : TESTABLE_FEATURE
| UNTESTABLE_FEATURE'''
def p_TESTABLE_FEATURE(p):
'''TESTABLE_FEATURE : BLOCK_START QUOTE NAME_KEY QUOTE COLON QUOTE CPCODE_FEATURE QUOTE COMMA IGNORE_KEY_VAL_PAIRS COMMA CPCODE_OPTIONS COMMA IGNORE_KEY_VAL_PAIRS'''
def p_UNTESTABLE_FEATURE(p):
'''UNTESTABLE_FEATURE : IGNORE_BLOCK '''
与
data = []
def p_FEATURE(p):
'''FEATURE : BLOCK_START DATA BLOCK_END FEATURE
| BLOCK_START DATA BLOCK_END'''
def p_DATA(p):
'''DATA : KEY COLON VALUE COMMA DATA
| KEY COLON VALUE ''' # and so on (have another function for values)
您现在可以做的是检查p[2]
并查看它是否重要。如果是,请将其添加到data
变量中。否则,忽略。
这只是一个粗略的想法。您仍然必须准确地找出语法规则(例如,VALUE
也可能导致另一个状态),并将正确的块添加到data
以及如何。但这是有可能的。