lex を試す。Lexer の複製
マニュアルによると、こういうこと?
クラスで定義していないときは、以下のようにやれば良い。
これは、lex() を呼んで再度ルールなどを構築し直すよりも速い。
lexer = lex.lex() ... newlexer = lexer.clone()
一方、クラス定義した場合は、ちょっと考えどころ。
同じように以下のようにすると、オブジェクト m が同じだから、
インスタンス変数が同じものになりまずい。
m = MyLexer() a = lex.lex(object=m) # Create a lexer b = a.clone() # Clone the lexer
ということらしいのだが、どんな感じでダメになるのか確認するコードが書けなかった。
そもそも、a や b から m にアクセスする方法が分からなかった。
ちょっと調べたら、lexmodule というのがそれらしい。
でも、Lexer を作っているくせに、lex.lex() に Lexer を渡して良く分からない a とか b とかいうものを作ること自体どうなんだろうか?
#!/usr/bin/env python import ply.lex as lex def lex_data(lexer, data): lexer.input(data) while 1: tok = lexer.token() if not tok: break # No more input print tok class MyLexer: tokens = ( 'A', 'PLUS', ) t_A = r'a' t_PLUS = r'\+' def t_error(self, t): print "Illegal character '%s'" % t.value[0] t.lexer.skip(1) def __init__(self, name): self.name = name m = MyLexer("my lexer") lexer1 = lex.lex(object=m) lexer2 = lexer1.clone() print lexer1.lexmodule.name print lexer2.lexmodule.name lex_data(lexer1, "a+a") print lex_data(lexer2, "a+a+a")
で、
my lexer my lexer LexToken(A,'a',1,0) LexToken(PLUS,'+',1,1) LexToken(A,'a',1,2) LexToken(A,'a',1,0) LexToken(PLUS,'+',1,1) LexToken(A,'a',1,2) LexToken(PLUS,'+',1,3) LexToken(A,'a',1,4)
別のオブジェクトを使うコード
#!/usr/bin/env python import ply.lex as lex class MyLexer: tokens = ( 'A', 'PLUS', ) t_A = r'a' t_PLUS = r'\+' def t_error(self, t): print "Illegal character '%s'" % t.value[0] t.lexer.skip(1) def __init__(self, name): self.name = name def lexer(self, lexer): self.lexer = lexer def clone(self, name): c = MyLexer(name) # Create a new instance of myself # Copy attributes from self to c as appropriate # Clone the lexer c.lexer = self.lexer.clone(c) return c def lex_data(self, data): self.lexer.input(data) while 1: tok = self.lexer.token() if not tok: break # No more input print tok m = MyLexer("my lexer1") m.lexer(lex.lex(object=m)) lexer1 = m lexer2 = m.clone("my lexer2") print lexer1.name print lexer2.name lexer1.lex_data("a+a") print lexer2.lex_data("a+a+a")
で、
my lexer1 my lexer2 LexToken(A,'a',1,0) LexToken(PLUS,'+',1,1) LexToken(A,'a',1,2) LexToken(A,'a',1,0) LexToken(PLUS,'+',1,1) LexToken(A,'a',1,2) LexToken(PLUS,'+',1,3) LexToken(A,'a',1,4)
- そもそも lex() の呼び出しコストなんて気にする必要があるのだろうか?
- 同じ lex を同時に二つ持つ場面って?