2012-03-31 48 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方法,所以我做了一個看起來是這樣的:

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

實際掃描根據我的測試,使用scan()平均需要124毫秒,但是當我使用PLY解析器時,幾分鐘後解析不會開始。看來我的方法有問題。

此外,我試圖重命名scan()方法,以便可能成爲接口。 Python返回類似於

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

因此,似乎PLY需要一種方法,該方法一次將返回一個令牌。

有什麼方法可以重寫方法,以便它會返回scan()的下一次迭代,而不會那麼慢嗎?

+0

順便說一句,即使你想解析縮進,你也可以使用PLY進行大多數抽取。只需通過詞法分析器載入所有(領先的?)空白換行符,並對令牌流進行後處理以插入適當的INDENT/DEDENT標記。當我這樣做時,我沒有使用PLY進行解析步驟,所以我不必整合它,因此不能回答這個問題。但它確實使編寫詞法分析器變得更容易。 – delnan 2012-03-31 17:28:39

+0

@delnan這可能可能會工作,但我也無法弄清楚如何返回多個標記來處理縮進。剩下的我可以編碼了。 – 2012-03-31 17:47:04

回答

0

您需要保存在某個地方你的發電機,如:

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

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

聲明:我不知道什麼PLY。

+0

它的工作原理,但它肯定會使程序變得相當慢,大約5ms。但是這並不會讓我感到困擾。謝謝! – 2012-03-31 21:54:08

相關問題