0

いくつかのスペースを区切り記号として使用することは可能ですか? 私が言いたいのは...

いくつかの Python 演算子優先パーサーが与えられた場合、自然言語と演算子を組み合わせて、メモを取るための省略形として使用したいと考えています。つまり'caffeine : A1 antagonist -> caffeine : peripheral stimulant'、解釈があり'caffeine is an A1 antagonist implies that it is a peripheral stimulant'ます。

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')

可能?

4

1 に答える 1

4

よく考えてみると、定義しようとしている言語があいまいであると思いますが、それを修正する方法は複数あります。

あなたはこれを求めている:

parse('a:b -> c : d e')

これを与えるには:

[[['a', ':', 'b'], '->', ['c', ':', ['d', 'e']]]]

空白を演算子として機能させたいと暗示しています。しかし、なぜそれはのコンテキストで演算子ではないの'c :'ですか? 演算子である場合とそうでない場合のルールは何ですか?

それか、各オペランドをスペースで区切られた単語のリストにする必要があります。しかし、その場合、なぜ'a'代わりに['a']? オペランドのそれぞれがリストであるか、どれもそうでないかのどちらかですよね? 明らかに位置に依存しておらず、他のルールを指定していません。

あなたの考えに合う妥当なルールが (少なくとも) 1 つあります。それは、単一要素リストであるオペランドをその要素だけに折りたたむことです。しかし、これは奇妙なルールです。後でこの解析ツリーを使用している目的に関係なく使用する場合、単一の単語を 1 単語のリストであるかのように処理するコードを記述して、同じルールを効果的に逆にする必要があります。 . では…どうしてそんなことを?

3 つのより良い代替案を考えることができます。

  1. すべてのオペランドがスペースで区切られた単語のリストである必要があります。
  2. オペランドの途中にスペースを許可します。
  3. デフォルトの空白処理を使用し、演算子の両側に複数の用語を許可します。

これらはどれも解析が非常に簡単で、非常に使いやすい解析ツリーを提供します。おそらく#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']]]
于 2013-01-18T22:01:06.250 に答える