gpt4 book ai didi

javascript - 使用 javascript 正则表达式在 C++ 中列出函数的参数

转载 作者:行者123 更新时间:2023-11-30 01:47:36 25 4
gpt4 key购买 nike

我正在使用 javascript 解析由 doxygen 生成的文档。

我要匹配的函数可能具有以下签名:
funcName (type1 * param1, const myNamespace::type2 param2, myNamespace::type3 param3)

参数的数量可以变化,我想得到以下输出(或类似的东西):
[type1, const myNamespace::type2, myNamespace::type3]

注意:我不想知道它是指针还是引用

到目前为止,这是我尝试过的:

var signature = "funcName (type1 * param1, const myNamespace::type2 param2, myNamespace::type3 param3)";
/(?:.*?)\((?:((?:const\s)?(?:\w+\:\:)?\w+)(?:.*?,\s)?)+/g.exec(signature);

但这只给了我函数中的最后一个类型,或者更确切地说:
["funcName (type1 * param1, const myNamespace::type2 param2, myNamespace::type3", "myNamespace::type3"]

我相信我对非贪婪运算符和非捕获组的广泛使用可能是问题的根源,但我仍然无法解决这个问题......

注意:使用选项 /g 似乎没有任何改变

最佳答案

隔离签名后:

var signature = "funcName (type1 * param1, const myNamespace::type2 param2, myNamespace::type3 param3)";

下面给你参数:

var parameters = /\((.*)\)/.exec(signature)[1];

现在,在一般情况下,您不能只是 .split(",")它们,因为模板化类型,例如 std::map<int, std::string>例如。

如果你说没有这样的模板化类型,那很简单:

var paramTypes = parameters.split(/\s*,\s*/).map(function(i) {
return i.replace(/\s*[*&]*\s*\w+$/, "");
});

结果:

["type1", "const myNamespace::type2", "myNamespace::type3"]

让我们看看\s*[*&]*\s*\w+$正则表达式,从末尾开始:

  • $确保我们在最后
  • \w+匹配参数名
  • [*&]*匹配您要去除的指针和引用限定符
  • \s*匹配中间可能的空格

这个匹配被替换为一个空字符串,所以只剩下类型名称。


现在,为了好玩,让我们考虑一下这个糟糕的情况:

var signature = "funcName (int param1, const std::map<int, std::string>& param2, std::map<int, std::map<int, double>>& param3)";

这仍然成立:

var parameters = /\((.*)\)/.exec(signature)[1];

对于其余部分,我们需要一个状态机,它实际上是一个非常基本的解析器:

function getArgTypes(signature) {
var parameters = /\((.*)\)/.exec(signature)[1],
result = [],
level = 0,
re = /[^<>,]+|./g,
match,
currentParam = "";

while (match = re.exec(parameters)) {
currentParam += match[0];

switch (match[0]) {
case "<":
++level;
break;

case ">":
--level;
break;

case ",":
if (!level) {
result.push(currentParam.replace(/\s*[*&]*\s*\w+\s*,$/, "").trim());
currentParam = "";
}
break;
}
}

currentParam = currentParam.trim();

if (currentParam)
result.push(currentParam.replace(/\s*[*&]*\s*\w+\s*$/, ""));

return result;
}

结果:

["int", "const std::map<int, std::string>", "std::map<int, std::map<int, double>>"]

也没有复杂 :-)

[^<>,]+|.正则表达式执行标记化,这意味着它的目标是将相关的文本位分成标记。注意 .实际上是 [<>,] 的简写在那种特殊情况下。

对于这个例子,我们只对 < 感兴趣, >, token 。其余的可以粘在一起(例如,我们可以使用 std::map,不需要像编译器那样将它分成 std :: map

这应该给我们以下标记:

int param1 , const std::map < int , std::string > & param2 , std::map < int , std::map < int , double > > & param3

现在,处理这只是跟踪嵌套级别的问题。

关于javascript - 使用 javascript 正则表达式在 C++ 中列出函数的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31391713/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com