使用memoize解决PEG解析器无法左递归的问题

文章探讨了PEG解析器处理左递归的挑战,指出传统的PEG解析器在遇到左递归文法时可能导致无限递归和栈溢出。Guido的Pegen解析器采用memoize技术,源自Packrat解析器,通过维护一个缓存来存储解析状态,从而有效地解决这个问题。缓存记录了解析位置和对应的状态返回值,避免了重复计算,确保了解析的效率和正确性。

*** 本篇文章是个人对 Guido 有关 Packrat PEG 解析器文章的处理左递归部分的理解和总结。***

左递归

众所周知,PEG 解析器的一个缺陷就在于无法解析具有左递归的文法,而大多数情况下,CFG 使用左递归文法会让很多事情变得简单。下面的 PEG 文法列出了一个简单的左递归实例:

expr: expr '+' term | term
term: NAME

如果我们使用 PEG 解析器生成器生成对应的 Parser,那它大概率会有如下形式:

def expr(p):
    # ...
    if expr(p) and p.except('+') and term(p):
        # ...
    # ...

不难发现,这个函数将会不断递归调用下去,直至函数调用栈溢出。这就是所谓的 “左递归”,也是传统 PEG 解析器的问题。

面对左递归,生成式文法可以使用许多办法来处理左递归,然而实际上,解析式文法处理左递归也已经有很多学术上的方法。

Guido 的 Pegen 受到了 这位大佬 的启发,解决了左递归的问题。

memoize

pegen 的一个重要的实现是 memoize,实际上这来源于 Packrat 解析器。memoize 的核心是维护一个缓存(下文将其称为 memo),这个缓存记录了 Parser 的解析光标位置和对应的状态的返回值:

memo: pos -> (state, arg) -> return
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值