PEG规则识别功能原型 [英] PEG rule to identify function protoype
问题描述
我正在尝试创建一个可以解析C代码的解析器.我的用例分析可能包含函数原型的缓冲区.我想将此函数名称推送到符号表中.我是Spirit和PEG的新手,我试图弄清楚如何编写可以识别功能原型的规则.
I am trying to create a parser that can parse C code. My use case to parse a buffer that may contain a function prototype. I want to push this function name into a symbol table. I am new to Spirit and PEG and I am trying to figure out how I can write a rule that can identify function prototypes.
这是我当前的实现方式:
This is my current implementation:
auto nameRule = x3::alpha >> *x3::alnum;
auto fcnPrototypeRule = nameRule >> *nameRule;
auto fcnRule = fcnPrototypeRule >> space >> x3::char_('(') >> -(nameRule % ',') >> x3::char_(');');
这是我的应用程序代码:
This is my application code:
class Parser {
public:
std::string functionParser(const std::string& input) {
std::string output;
x3::phrase_parse(input.begin(), input.end(), fcnRule, space, output);
return output;
}
};
input is ="extern void myFunction();" 输出为空字符串.我想获得函数原型.
input is = "extern void myFunction();" The output is an empty string. I wanted to get the function prototype.
推荐答案
看起来像');'
应该是);"?
Looks like ');'
should have been ");"?
另外,由于您有一个船长(在phrase_parse
的调用中为x3::space
),因此没有什么意义:
Also since you have a skipper (x3::space
in the call to phrase_parse
) it doesn't make much sense to:
- 还要在解析器表达式中指定
space
(永远不会匹配) - 不将
nameRule
包装在lexeme
或noskip
指令中.另请参见 Boost Spirit队长问题
- also specify
space
in your parser expression (it will never match) - not wrap the
nameRule
inside alexeme
ornoskip
directive. See also Boost spirit skipper issues
所以首先要使它起作用:
So first stab at making it work:
std::string functionParser(const std::string& input) {
namespace x3 = boost::spirit::x3;
auto nameRule = x3::lexeme [x3::alpha >> *x3::alnum];
auto fcnPrototypeRule = nameRule >> *nameRule;
auto fcnRule = fcnPrototypeRule >> x3::char_('(') >> -(nameRule % ',') >> x3::char_(");");
std::string output;
x3::phrase_parse(input.begin(), input.end(), fcnRule, x3::space, output);
return output;
}
但是,您会注意到它返回ndn()
( 在Coliru上直播 ).
However, you'll notice it returns ndn()
(Live On Coliru).
我认为这基本上是由于您的AS(std::string
)与语法不太匹配这一事实造成的.我想说的是您要匹配"而不是解析",我会使用x3::raw
公开原始匹配:
I think it's basically caused by the fact that your AS (std::string
) doesn't match the grammar much. I'd say it looks likeyou mean to "match" instead of "parse" and I'd use x3::raw
to expose the raw match:
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <iomanip>
std::string functionParser(const std::string& input) {
namespace x3 = boost::spirit::x3;
auto nameRule = x3::lexeme [x3::alpha >> *x3::alnum];
auto fcnPrototypeRule = nameRule >> *nameRule;
auto fcnRule = x3::raw[ fcnPrototypeRule >> '(' >> -(nameRule % ',') >> ')' >> ';' ];
std::string output;
x3::phrase_parse(input.begin(), input.end(), fcnRule, x3::space, output);
return output;
}
int main() {
for (auto s : {
"extern void myFunction();",
})
{
std::cout << std::quoted(s) << " -> " << std::quoted(functionParser(s)) << "\n";
}
}
这篇关于PEG规则识别功能原型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!