具有重复“元令牌”的解析器描述

时间:2012-04-12 23:16:59

标签: parsing bnf

是否有一种众所周知的解析器描述语言(如Backus-Naur)允许重复从令牌流中提取重复次数?对于奖励积分,有没有支持这种语法的C ++库?

示例:

让我们调用“元标记”#,然后我正在寻找一种能够处理以下形式的生产规则的描述语言:

RULE = # EXPRESSION

如:

RULE = '1' EXPRESSION
     | '2' EXPRESSION EXPRESSION
     | '3' EXPRESSION EXPRESSION EXPRESSION
     | '4' EXPRESSION EXPRESSION EXPRESSION EXPRESSION
     | ...

请注意,计数是实际的字符文字。这与augmented Backus-Naur form形成鲜明对比,{{3}}我们可以使用以下形式的规则:

RULE = 2*3EXPRESSION

相当于:

RULE = EXPRESSION EXPRESSION
     | EXPRESSION EXPRESSION EXPRESSION

对dgarant的回应:

我不确定这是我想要的。我正在考虑以下几点:

int i;

bool r = phrase_parse(first, last,
     (
       int_[ phoenix::ref(i) = _1] >> repeat(i)[/*EXPRESSION*/]
     )
     space );

更重要的是,虽然我希望有一些可以描述这个想法的正式架构。在一个侧节点上,Spirit确实需要一些使用,但非常棒。我是一个粉丝。

1 个答案:

答案 0 :(得分:0)

我想不出一种允许rule = # EXPRESSION指定重复的正式语言#是一个字符文字。在我看来,如果您发表评论以澄清您的意思,滥用正式语言规范应该不是问题。如果您真的想坚持标准,可以在ABNF中执行以下操作:

rule = '3' 3EXPRESSION
     | '4' 4EXPRESSION
     | '5' 5EXPRESSION

它看起来并不像你想要的那样,但它完成了工作。

我相信boost::spirit::qi可以满足你的解析需求。看看repeat directive

Spirit会允许你编写诸如

之类的规则
rule = char_("'") >> int_[qi::_a = qi::_1] >> char_("'") >> repeat(qi::_a)[EXPRESSION]

如果您对确定已解析的重复次数感兴趣,可以在规则中添加其他操作:[phoenix::ref(pCt) = qi::_a]

std::vector<double>& v;
int pCt;

bool r = phrase_parse(first, last,
         (
           // to parse a collection of double expressions
           char_("'") >> int_[qi::_a = qi::_1] >> char_("'") >> repeat(qi::_a)[double_[push_back(phoenix::ref(v), _1)]]
           [phoenix::ref(pCt) = qi::_a]
         )
         space);
// assuming the parse was successful
std::cout << "Parsed " << pCt << " elements" << std::endl;

Spirit :: Qi解析器的风格需要一段时间才能习惯,但它们非常强大,因为你可以将它们直接集成到你的代码中。