2017-01-02 55 views
1

我正在嘗試遵循this教程,並且很難將本教程中使用的語法轉換爲pyparsing語法。博客的要點是創建表達式語言來解析和執行字典比較。使用自己的類pyparsing

properties = { 
    "name": "David Bowie", 
    "years_active2": 47 
} 

表達來評估:

​​

它們所使用的語法是:

expr: literal      { return $1 } 
    | "properties" "[" literal "]" { return PropertyLookup($3) } 
    | expr "[" expr "]"   { return Index($1, $3) } 
    | expr "and" expr    { return And($1, $3) } 
    | expr "==" expr    { return Equals($1, $3) } 
    | expr ">" expr    { return GreaterThan($1, $3) } 
; 

literal: QUOTED_STRING { return Literal($1) } 
    | DECIMAL_NUMBER { return Literal($1) } 
; 

到目前爲止我有:

string_literal = pp.Word(pp.alphas, pp.alphanums) 
numeric_literal = pp.Word(pp.nums) 
literal = string_literal | numeric_literal 
properties = "properties" + "[" + literal + "]" 

PropertyLookup(),索引() ,和(),Equals()和GreaterThan()是自定義的cl爲創建表達而創建的屁股。

我該如何改變我的第四行屬性,以與第二行相同的方式進行操作?我主要困惑如何將文字傳遞到一個自定義類,如PropertyLookup()這是

class PropertyLookup(object): 
    def evaluate(self, props): 
     return props[self.key] 

任何幫助表示讚賞!

+0

你有什麼嘗試?結果是什麼?它與你的預期有什麼不同?有時,從教程中分離出來的好方法是將其精確地複製*,然後開始進行修改。如果它壞了,回到它仍然有效的位置,然後找出你做了什麼破壞了它。 –

回答

3

要使用pyparsing爲您構建類,請將它們作爲解析操作附加到表達式。下面是如何做到這一點的一個小例子:

import pyparsing as pp 

class Node(object): 
    def __init__(self, tokens): 
     self._tokens = tokens 
    def __repr__(self): 
     return "{}: ({})".format(self.__class__.__name__, self._tokens.asList()) 

class AlphaNode(Node): pass 
class NumericNode(Node): pass 
class BinExprNode(Node): pass 
class OperatorNode(Node): pass 

alpha_expr = pp.Word(pp.alphas) 
numeric_expr = pp.Word(pp.nums) 
operand = alpha_expr | numeric_expr 
operator = pp.oneOf("+ - * /") 
bin_expr = operand + pp.OneOrMore(operator + operand) 

# by setting the node classes as each expression's parse action, 
# the node instances will be constructed at parse time and returned 
# as pyparsing's parse results 
alpha_expr.addParseAction(AlphaNode) 
numeric_expr.addParseAction(NumericNode) 
operator.addParseAction(OperatorNode) 
bin_expr.addParseAction(BinExprNode) 

result = bin_expr.parseString("a + 27 * X") 
print(repr(result[0])) 

打印

BinExprNode: ([AlphaNode: (['a']), OperatorNode: (['+']), NumericNode: (['27']), OperatorNode: (['*']), AlphaNode: (['X'])]) 

您還必須澄清一些左遞歸在你的語法 - 你將無法實現一個exprexpr開始,這隻會在自己遞歸,直到你達到遞歸限制。爲索引的重複進入「屬性」

expr: literal     
    | "properties" ("[" expr "]")... 
; 

使用pyparsing的一次或更多類:通過定義您的基本操作數表達的開始。然後使用類似SimpleBool.py或evalArith.py等pyparsing示例中的方法來構建中綴表示法和評估器。