我需要解析一个像func1(arg1, arg2); func2(arg3, arg4);
. 这不是一个非常复杂的解析问题,所以我宁愿避免使用 flex/bison 或类似的实用程序。
我的第一个方法是尝试使用 POSIX Cregcomp/regexec
或 C++ 的 Boost 实现std::regex
。我编写了以下正则表达式,但它不起作用(我将进一步解释原因)。
"^"
"[ ;\t\n]*"
"(" // (1) identifier
"[a-zA-Z_][a-zA-Z0-9_]*"
")"
"[ \t\n]*"
"(" // (2) non-marking
"\["
"(" // (3) non-marking
"[ \t]*"
"(" // (4..n-1) argument
"[a-zA-Z0-9_]+"
")"
"[ \t\n]*"
","
")*"
"[ \t\n]*"
"(" // (n) last argument
"[a-zA-Z0-9_]+"
")"
"]"
")?"
"[ \t\n]*"
";"
请注意,组1
捕获标识符,组4..n-1
旨在捕获除最后一个之外的参数,后者由 group 捕获n
。
当我将此正则表达式应用于时,说func(arg1, arg2, arg3)
我得到的结果是一个数组{func, arg2, arg3}
。这是错误的,因为arg1
不在其中!
问题是在标准正则表达式库中,子标记只捕获最后一个匹配项。换句话说,例如,如果您将正则表达式"((a*|b*))*"
应用于"babb"
,则内部匹配的结果将是bb
并且所有先前的捕获都将被遗忘。
让我烦恼的另一件事是,如果出现错误,则无法知道哪个字符未被识别,因为当输入被拒绝时,这些函数提供的有关解析器状态的信息非常少。
所以我不知道我是否在这里遗漏了一些东西......在这种情况下我应该使用sscanf
或类似的东西吗?
请注意,我更喜欢使用 C/C++ 标准库(也可能是 boost)。