You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyParsing解析Solidity方法签名时出现无限递归错误求助

Solidity函数签名解析的递归深度超限问题

问题描述

我编写了用于解析Solidity函数方法签名的PyParsing语法,代码如下:

from pyparsing import Word, alphas, alphanums, oneOf, Group, Forward, ZeroOrMore, Optional, delimitedList

solidity_type = Forward()
primitive = oneOf("address uint uint8 uint16 uint32 uint64 uint128 uint256 int int8 int16 int32 int64 int128 int256 bool bytes bytes1 bytes4 bytes32")
array = solidity_type + "[]"
tuple_type = "(" + delimitedList(solidity_type) + ")"
solidity_type <<= (primitive | array | tuple_type)
function_name = Word(alphas, alphanums + "_")
arguments = Optional(delimitedList(solidity_type))
function_signature = function_name + "(" + arguments + ")"

sig = "diamondCut((address,uint8,bytes4[])[],address,bytes)"
parsed_sig = function_signature.parseString(sig)
print(parsed_sig.dump())

运行时触发{RecursionError}maximum recursion depth exceeded错误,测试array.parseString("(bytes4)[]")也会出现同样问题。尝试过用Group包裹表达式、调整选项顺序、将array设为独立Forward,都无法解决,需要修改代码解析目标签名。

解决方法

递归超限的原因是array和tuple_type都直接依赖solidity_type,而solidity_type又包含这两者,导致解析器在尝试匹配时陷入无限递归。解决思路是调整语法定义的优先级,让解析器优先匹配最底层的类型,再逐步向上匹配复合类型,同时用Group明确结构避免歧义:

from pyparsing import Word, alphas, alphanums, oneOf, Group, Forward, Optional, delimitedList

solidity_type = Forward()
# 先定义最基础的原始类型
primitive = oneOf("address uint uint8 uint16 uint32 uint64 uint128 uint256 int int8 int16 int32 int64 int128 int256 bool bytes bytes1 bytes4 bytes32")
# 定义元组:用Group包裹,确保内部结构被正确识别
tuple_type = Group("(" + delimitedList(solidity_type) + ")")
# 定义数组:优先匹配原始类型或元组后再匹配数组后缀,避免递归循环
array = Group((primitive | tuple_type) + "[]")
# 最后把所有类型选项按优先级加入solidity_type
solidity_type <<= (primitive | tuple_type | array)

function_name = Word(alphas, alphanums + "_")
arguments = Optional(delimitedList(Group(solidity_type)))
function_signature = Group(function_name + "(" + arguments + ")")

sig = "diamondCut((address,uint8,bytes4[])[],address,bytes)"
parsed_sig = function_signature.parseString(sig)
print(parsed_sig.dump())

关键修改点

  • 调整类型匹配顺序:让解析器先匹配primitive,再匹配tuple_type,最后匹配array,避免一开始就进入复合类型的递归匹配
  • 用Group包裹复合类型:明确元组和数组的结构,让解析结果更清晰,同时帮助解析器识别完整的复合类型单元
  • 数组定义优化:数组不再直接依赖solidity_type,而是基于已匹配的primitive或tuple_type,打破无限递归的循环

运行修改后的代码,就能成功解析目标签名,输出的结构化结果也能清晰展示函数名和每个参数的类型结构。


内容的提问来源于stack exchange,提问作者aram10

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 11:43:23