2016-07-08 16 views
2

私はPLYで自分のパーサーを作成しています。PLYのlexとyaccを2つの別々のクラスにカプセル化する方法

class Lex: 
    tokens = (
     'NAME', 'NUMBER', 
    ) 

    literals = ['=', '+', '-', '*', '/', '(', ')'] 

    # Tokens 

    t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*' 

    ... 

(YACCを使用)パーサコード:

class Parser: 

    # Parsing rules 
    tokens = Lex.tokens 

    def p_statement_assign(self, p): 
     'statement : NAME "=" expression' 
     self.names[p[1]] = p[3] 

    ... 

    def run(self): 
     print self.tokens 
     lex.lex(module=Lex) # ----what should I do here?----- 
     parser = yacc.yacc(module=self) 
     parser.parse("1+2") 

そして、私は次しまった私はここでクラスレックスのコード がある

それぞれのlexとyaccをカプセル化したいですエラー: バインドされていないメソッドt_NUMBER()は最初の引数としてLexインスタンスとともに呼び出される必要があります(代わりにLexTokenインスタンスがあります)

私はyacc.yacc(module=self)のように、module=Lexをlexに使ってみましたが、うまくいきませんでした。

答えて

1

私がインタプリタを構築しようとしたのはこれが初めてです。現代のPythonではPLYが好きではありません。正規表現を格納するためにdocstringを使うのは気が気です。 PLYサンプルもかなり古いようです。しかし、ねえ、PLYの最初のバージョンは2001年にリリースされ、それはまだ16年後に生きているので、それを維持するための著者/コミュニティへの名誉です。

言われて、ここで私は仕事にいくつかのカプセルを得た方法であること:

class MyLexer(object): 
    tokens = (
     'NUMBER', 
     'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 
     'LPAREN', 'RPAREN', 
    ) 

    t_PLUS = r'\+' 
    t_MINUS = r'-' 
    t_TIMES = r'\*' 
    t_DIVIDE = r'/' 
    t_LPAREN = r'\(' 
    t_RPAREN = r'\)' 

    ... 

    def __init__(self): 
     # Build the lexer 
     self.lexer = lex.lex(module=self) 


class MyParser(object): 

    tokens = MyLexer.tokens 

    ... 

    def p_expression_binop(self, t): 
     ''' 
     expression : expression PLUS expression 
        | expression MINUS expression 
        | expression TIMES expression 
        | expression DIVIDE expression 
     ''' 
     left_hand_side = t[1] 
     right_hand_side = t[3] 
     operator = t[2] 
     if operator == '+': 
      value = left_hand_side + right_hand_side 
     elif operator == '-': 
      value = left_hand_side - right_hand_side 
     elif operator == '*': 
      value = left_hand_side * right_hand_side 
     elif operator == '/': 
      value = left_hand_side/right_hand_side 
     else: 
      raise AssertionError('Unknown operator: {}'.format(operator)) 

     t[0] = value 

    ... 

    def __init__(self): 
     self.lexer = MyLexer() 
     self.parser = yacc.yacc(module=self) 
関連する問題