私は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)
免責事項:
ところで、インデントを解析する場合でも、ほとんどのレキシングでPLYを使用できます。レクサーを通してすべての(先頭の?)空白改行を持ち運び、トークンストリームを後処理して、適切なインデント/デデントトークンを挿入してください。私がこれをしたとき、私は解析ステップのためにPLYを使用しなかったので、私はそれを統合する必要はなく、したがってこの質問に答えることはできません。しかし、レクサーを簡単に書くことはIMHOになります。 – delnan
@delnanそれは_可能かもしれませんが、私も理解できないことは、インデントを処理するためにその1つのルールに対して複数のトークンを返す方法です。残りの部分は既にコード化することができます。 –