2012-03-31 7 views
2

私はPythonでコンパイラを書いていますが、手書きのレクサーを作ったのは、PLYで字下げを解析する方法がわからないからです。また、私のレクサーはそうのようないくつかのyieldステートメントを使用しています。手書きのレクサー用のPLYインターフェイスの作成方法は?

def scan(): 
... 
    for i in tokens: 
     if i[0]: yield Token(self.line, i[0] if i[0] in keywords else "ident", i[0]) 
      elif i[1]: 
       if "e" in i[1]: 
        base, exp = i[1].split("e") 
        val = float(base) * 10 ** int(exp) 
       else: val = float(i[1]) 
       yield Token(self.line, "float", val) 
     ... other cases ... 

はしかし、私はPLYパーサがtoken方法が必要であることを実現したので、私はこのようになります1作っ:

def token(self): 
    return next(self.scan()) 

実際のスキャンをscan()を使用して私のテストによると、平均124ミリ秒かかるが、私はPLYパーサーを使用すると、解析は数分後に開始されません。私のメソッドに問題があるようです。

また、がインターフェイスになるように、scan()メソッドの名前を変更しようとしました。 Pythonは次のような結果を返します

AttributeError: 'generator' object has no attribute 'type' 

したがって、PLYには一度に1つのトークンを返すメソッドが必要です。

メソッドを書き直して、次の反復をscan()に戻す方法はありますが、それほど遅くはありませんか?

def start(...): 
    self.lexer = self.scan() 

def token(...): 
    return next(self.lexer) 

免責事項:

+0

ところで、インデントを解析する場合でも、ほとんどのレキシングでPLYを使用できます。レクサーを通してすべての(先頭の?)空白改行を持ち運び、トークンストリームを後処理して、適切なインデント/デデントトークンを挿入してください。私がこれをしたとき、私は解析ステップのためにPLYを使用しなかったので、私はそれを統合する必要はなく、したがってこの質問に答えることはできません。しかし、レクサーを簡単に書くことはIMHOになります。 – delnan

+0

@delnanそれは_可能かもしれませんが、私も理解できないことは、インデントを処理するためにその1つのルールに対して複数のトークンを返す方法です。残りの部分は既にコード化することができます。 –

答えて

0

あなたは次のように、どこかにあなたのジェネレータを保存する必要があり、私はPLYについては何も知りません。

+0

それは動作しますが、プログラムはかなり遅くなります。約5msです。しかし、それは本当に私を悩ますことはありません。ありがとう! –

関連する問題