是否可以使用一些空格作为分隔符?我的意思是......
给定一些python运算符优先级解析器,我希望将自然语言与运算符混合,用于记笔记的简写,即'caffeine : A1 antagonist -> caffeine : peripheral stimulant'
具有解释'caffeine is an A1 antagonist implies that it is a peripheral stimulant'
。
e.g。我希望能够将此parse('a:b -> c : d e')
解析为[[['a', ':', 'b'], '->', ['c', ':', ['d', 'e']]]]
有这样的东西
operands = delimitedList(Word(alphanums), delim=',')
# delim=' ' obviously doesn't work
precedence = [
(":", 2, opAssoc.LEFT),
("->", 2, opAssoc.LEFT),
]
parser = operatorPrecedence(operands, precedence)
def parse(s): return parser.parseString(s, parseAll=True)
print parse('a:b -> c : d e')
可能?
答案 0 :(得分:4)
在考虑完之后,我认为您尝试定义的语言含糊不清,但有多种方法可以解决这个问题。
你想要这个:
parse('a:b -> c : d e')
给你这个:
[[['a', ':', 'b'], '->', ['c', ':', ['d', 'e']]]]
您暗示您希望空格充当运算符。但那么为什么它不是'c :'
背景下的算子?它何时以及何时不是运营商的规则是什么?
或者您希望每个操作数都是以空格分隔的单词列表。但在这种情况下,为什么'a'
代替['a']
?每个操作数都是一个列表,或者它们都不是,对吧?它显然不依赖于位置,并且您没有指定任何其他规则。
有(至少)一个合理的规则适合您的想法:将单个元素列表的任何操作数折叠到该元素。但这是一个奇怪的规则 - 当你以后使用这个解析树用于你正在使用它的任何目的时,你必须通过编写处理单个单词的代码来有效地反转相同的规则,就像它是一个单词列表一样。所以...为什么这样做?
我可以想到三个更好的选择:
其中任何一个都很容易解析,并为您提供一个非常容易使用的解析树。我可能会选择#2,但由于我已经在上面的评论中解释了如何做到这一点,让我们在这里做#3:
>>> operands = OneOrMore(Word(alphanums))
>>> precedence = [
... (":", 2, opAssoc.LEFT),
... ("->", 2, opAssoc.LEFT),
... ]
>>> parser = operatorPrecedence(operands, precedence)
>>> def parse(s): return parser.parseString(s, parseAll=True)
>>> print(parse('a:b -> c : d e'))
[[['a', ':', 'b'], '->', ['c', ':', 'd', 'e']]]
>>> print(parse('caffeine : A1 antagonist -> caffeine : peripheral stimulant'))
[[['caffeine', ':', 'A1', 'antagonist'], '->', ['caffeine', ':', 'peripheral', 'stimulant']]]