码迷,mamicode.com
首页 > 其他好文 > 详细

boost spirit 语法解析

时间:2015-08-20 15:21:14      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:boost   编译器   regex      

使用spirit能很方便的解析自定义的语法规则,在他的文档中也说明了spirit与regex还有其他库的不同点。灵活,伸缩性好,可以用来搭建小的语法解析器也可以用来开发大型编译器等等。

定义语法规则之前首先要了解一下Extended Backus-Normal Form (EBNF)
EBNF可以定义一下生成合法字符串的公式,例如:

1:
rule1 = "0" | "1" | "2" | "3".
rule2 = "4" | "5" | "6" | "7" | "8" | "9"  | rule1.

字符 | 表示 或,则 rule2 可以表示0-9所有的数字;一个复杂点的例子:

2:
expression = term  { ("+" | "-") term} .
term       = factor  { ("*"|"/") factor} .
factor     = constant | variable | "("  expression  ")" .
variable   = "x" | "y" | "z" .
constant   = digit {digit} .
digit      = "0" | "1" | "..." | "9" .

表示一个合法的数学计算公式。

使用EBNF表示的语法可以很方便地用boost spirit表示:

3:

EBNF:
    group       ::= ‘(‘ expression ‘)‘
    factor      ::= integer | group
    term        ::= factor ((‘*‘ factor) | (‘/‘ factor))*
    expression  ::= term ((‘+‘ term) | (‘-‘ term))*

Boost Spirit:
    group       = ‘(‘ >> expression >> ‘)‘;
    factor      = integer | group;
    term        = factor >> *((‘*‘ >> factor) | (‘/‘ >> factor));
    expression  = term >> *((‘+‘ >> term) | (‘-‘ >> term));

其中 ::= 表示 被定义为 的意思,与=号表示的意思相同,integer表示所有整数,在例3中如下这些表达式都是合法的:

    12345
    -12345
    +12345
    1 + 2
    1 * 2
    1/2 + 3/4
    1 + 2 + 3 + 4
    1 * 2 * 3 * 4
    (1 + 2) * (3 + 4)
    (-1 + 2) * (3 + -4)
    1 + ((6 * 200) - 20) / 6
    (1 + (2 + (3 + (4 + 5))))

但是这些表达式则不合法:

    1/2 +-+ 3/4
    1 +/ 2 += 3 + 4
    1 + 2 * 3.14 * 4
    (1 + 2) .* (3 + 4)

直接上代码:

    #include <...>
    using namespace ...
    int main()
    {
        std::string cmd_str = "$aaa[bbb]==ccc LINE 123"
        std::vector<char> name1;
        std::vector<char> name2;
        std::vector<char> value;
        int var=0;
        std::string::iterator iter_begin = cmd_str.begin();
        bool parse_ok = qi::phrase_parse(iter_begin, cmd_str.end(),
                //  Begin grammar
                (
                         (‘$‘
                         >>(+(qi::char_ - ‘[‘))[boost::phoenix::ref( component_name ) = qi::_1]  // 获得aaa
                         >> ‘[‘
                         >> (+(qi::char_ - ‘]‘))[boost::phoenix::ref( variable_name ) = qi::_1]  // 获得bbb
                         >> ‘]‘
                         >> lit("==")
                         >> (+(qi::char_-lit("LINE")))[boost::phoenix::ref( target_value ) = qi::_1]  // 获得ccc
                         ^
                        (-(lit("LINE") >> qi::int_[boost::phoenix::ref(var) = qi::_1]))  // 获得123
                ),
                //  End grammar
                ascii::space  // skip the space
                );
        // 判断是否符合语法规则
        if (!parse_ok || iter_begin != cmd_str.end())
        {
            return -1
        }
        std::cout << std::string(name1.begin(), name1.end()) << std::endl;
        std::cout << std::string(name2.begin(), name2.end()) << std::endl;
        std::cout << std::string(value.begin(), value.end()) << std::endl;
        return 0;
    }

版权声明:本文为博主原创文章,未经博主允许不得转载。

boost spirit 语法解析

标签:boost   编译器   regex      

原文地址:http://blog.csdn.net/gw569453350game/article/details/47807123

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!