我试图使用PyParsing解析字符串,并在解析时检测它们是否包含至少一次定义的符号(比如'$')。
例如,将解析以下字符串:
"('a$x' & 'b') | $ | ('c' <-> $)"
但是这个不会(并且会引发解析异常):
"('a$x' & 'b') | 'c'"
如何做到这一点?
我的目标是构建抽象语法树(AST),它必须至少包含一个特殊符号&#39; $&#39;。目前,我认为&#39; $&#39;作为一个简单的文字:
my_symbol = Literal('$')
my_symbol.setParseAction(lambda tokens: Symbol())
我验证了&#34;至少一次发生&#34;解析后的条件,即一旦构建了我的AST(请注意Symbol()
是一个代表我的AST中的&#39; $)的类。但是,我认为在解析时检测会更有效。
编辑:我不知道它是否有用,但这里是我要解析的语法的简化版本:
<a> ::= '$' | '~' <a> | <a> '&' <b> | <b> '&' <a> | <a> '|' <b>
| <b> '|' <a> | <a> '->' <b> | <b> '->' <a> | <a> '<->' <b>
| <b> '<->' <a> | '(' <a> ')'
<b> ::= 'True' | 'False' | <atom> | '~' <b> | <b> '&' <b> | <b> '|' <b>
| <b> '->' <b> | <b> '<->' <b> | '(' <b> ')'
<atom> is defined by any string surrounded by single quotes
答案 0 :(得分:0)
这种验证在语法本身并不容易实现,所以我通常在分析时回调或listType
中进行。这是一个例子,一个简单的解析器,用于查找由字母组成的单词。
parse action
使用此测试字符串,我们可以看到它将匹配大写和小写字词。
alpha_word = Word(alphas)
假设我们想要拒绝大写的单词(但仍然接受混合或全部小写的单词)。这实际上很难在纯粹的pyparsing语法中表达,因此我们定义了一个在解析时调用的验证回调:
print alpha_word.searchString("abc DEF ghi Jkl")
[['abc'], ['DEF'], ['ghi'], ['Jkl']]
然后将解析操作附加到def reject_all_upper_case(src, locn, tokens):
if tokens[0].upper() == tokens[0]:
raise ParseException(src,locn,'reject words in all caps')
表达式:
alpha_word
现在,如果我们重新运行测试:
alpha_word.setParseAction(reject_all_upper_case)
在您的情况下,您将为整个表达式定义一个解析操作,然后只有在解析结果中某处有'$'符号时才接受它。
修改强>
所以看起来print alpha_word.searchString("abc DEF ghi Jkl")
[['abc'], ['ghi'], ['Jkl']]
,True & True
和False | "lskdjf"
都可以,但$ -> True
会失败。我想我会从这个简单的解析器开始:
$ -> $
然后对解析结果进行后处理以执行'$'的附加验证语义。