2017-01-02 11 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()、インデックス() 、and()、Equals()、GreaterThan()はcustom clです表現を構築するために作成された尻。

4行目のプロパティを2行目と同じように変更するにはどうすればよいですか?私は、このような

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

すべてのヘルプは高く評価されているPropertyLookup()などのカスタムクラスにリテラルを渡す方法については、主に困惑しています!

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

あなたはまた、あなたの文法でいくつかの左再帰をクリアする必要があります - あなたはexprを実装することができませんこれはexprで始まり、再帰制限に達するまでそれ自体が再帰します。 「プロパティ」へのインデックスの繰り返しのため

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

使用pyparsingのOneOrMoreクラス:としてあなたのベースオペランド式を定義することによって開始します。次に、SimpleBool.pyやevalArith.pyなどのpyparsingサンプルのメソッドを使用して、挿入表記の式と評価子を構築します。

関連する問題