2012-03-31 86 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