2017-09-16 39 views
1

我最終的目標是應用sql-where-clause-style查詢來過濾熊貓數據框。一些搜索引導我使用pyparsing的infixNotation方法。將中綴插入到解析樹中:只有一個操作符在樹中結束?

我發現中間符號在這裏的一個例子:http://nullege.com/codes/show/src%40p%40y%40pyparsing-2.0.2%40examples%40simpleBool.py/15/pyparsing.infixNotation/python#

但實際處理的符號,我需要多次使用樹在不同的數據。尋找解析樹的幫助我發現這個: http://pyparsing.wikispaces.com/file/view/fourFn.py/30154950/fourFn.py

我從那裏拿到了堆棧實現。然而,這並不像我期望的那樣行事,所以我希望有人能告訴我我做錯了什麼。

這是我能想出的最簡單的例子:

from pyparsing import Word, alphas, infixNotation, opAssoc 

exprStack=[] 
def pushFirst(strg, loc, toks): 
    exprStack.append(toks[0]) 

def addAnd(): 
    exprStack.append("and") 

varname = Word(alphas).setParseAction(pushFirst) 

operators=[("and", 2, opAssoc.LEFT,addAnd)] 

whereExpr = infixNotation(varname,operators) 

exprStack=[] 
teststring = "cheese and crackers and wine" 
parsed=whereExpr.parseString(teststring) 
for p in exprStack: 
    print p 

我從這個代碼得到的是:

cheese 
crackers 
wine 
and 

我希望得到的,從我如何綴的理解符號法應該可以工作,是:

cheese 
crackers 
wine 
and 
and 

我也試着用「芝士和餅乾,贏了」電子和嗚嗚聲「但我仍然只有一個」和「在我的名單中。

我在使用infixNotation方法時有什麼誤解?

謝謝

+0

我最終放棄中端協議棧的方法,並使用保麥圭爾的首選對象的方法。對於任何正在尋找應用於熊貓數據框的SQL-where-type查詢的人,你可以在github上找到一個版本(只有有限的語法):[link](https://github.com/moink/askapanda) – moink

回答

2

與pyparsing的traceParseAction診斷deccorator裝飾你的解析動作的開始。

@traceParseAction 
def addAnd(): 
    exprStack.append("and") 

traceParseAction將顯示匹配的源線,匹配令牌的起始位置,並傳遞給解析動作令牌,和由解析動作的返回值:

>>entering addAnd(line: 'cheese and crackers and wine', 0, 
       ([(['cheese', 'and', 'crackers', 'and', 'wine'], {})], {})) 
<<leaving addAnd (ret: None) 

的令牌有點令人困惑,因爲你得到的是一個對象,它具有list和dict的語義,所以對象的Python repr首先顯示它的列表內容,然後顯示它的命名內容。看起來像一個帶有列表和字典的元組實際上是ParseResults,在這種情況下,它是一個ParseResults,其第一個元素是另一個ParseResults,並且此嵌套對象是包含匹配記號列表的元素。

這是一個比較容易看到,如果你添加一個tokens參數傳送給解析動作,然後打印出:

def addAnd(tokens): 
    print(tokens.dump()) 
    exprStack.append("and") 

,你會得到更多的可讀性:

[['cheese', 'and', 'crackers', 'and', 'wine']] 
[0]: 
    ['cheese', 'and', 'crackers', 'and', 'wine'] 

您可以看到匹配的標記不僅包含'and',還包含所有相關的術語,因此您需要將相同標記中的'and'推入exprStack。

def addAnd(tokens): 
    exprStack.extend(tokens[0][1::2]) 

隨着這一變化,您現在應該看到這是你的返回堆棧:

cheese 
crackers 
wine 
and 
and 
+1

哇,幫助從pyparsing自己的作者!謝謝! – moink