boost.spirit用户手册翻译(32):片段分析器

Confix Parsers

片段分析器


Confix Parsers

片段分析器

Confix Parsers recognize a sequence out of three independent elements: an opening, an expression and a closing. A simple example is a C comment:


片段分析器识别一个包含三个元素的序列:一个开头,一个表达式和一个结尾。简单的例子就是C的注释:

    /* This is a C comment */

which could be parsed through the following rule definition:

它可以用下面定义的规则来分析:

    rule<> c_comment_rule
        =   confix_p("/*", *anychar_p, "*/")
        ;

The confix_p parser generator should be used for generating the required Confix Parser. The three parameters to confix_p can be single characters (as above), strings or, if more complex parsing logic is required, auxiliary parsers, each of which is automatically converted to the corresponding parser type needed for successful parsing.

confix_p分析器生成器用来生成所要求的片段分析器。confix_p的三个参数可以是单个字符(就像上面的)、字符串,或者,如果需要更复杂的分析逻辑,任意分析器,三者都被自动转化为成功分析所需的恰当的分析器类型。

The generated parser is equivalent to the following rule:


所生成的分析器等价于下面的规则:

    open >> (expr - close) >> close

If the expr parser is an action_parser_category type parser (a parser with an attached semantic action) we have to do something special. This happens, if the user wrote something like:

如果expr表达式是一个action_parser_category类型的分析器(可挂接语义动作的分析器),我们就需要进行特别处理。这是在用户写出类似下面的代码时会发生的:

    confix_p(open, expr[func], close)

where expr is the parser matching the expr of the confix sequence and func is a functor to be called after matching the expr. If we would do nothing, the resulting code would parse the sequence as follows:

这里expr是匹配片段中的expr部分,而func则是在匹配expr后所调用的仿函数。如果我们直接这么干,那么所产生的代码就会进行类似下面的分析:

    open >> (expr[func] - close) >> close

which in most cases is not what the user expects. (If this is what you've expected, then please use the confix_p generator function direct(), which will inhibit the parser refactoring). To make the confix parser behave as expected:

而这不是大多数用户所要的(如果这你想要的,那么使用confix_p生成器函数direct(),它将返回所重构的分析器)。为了让片段分析器按照如下所预期的方式工作:

    open >> (expr - close)[func] >> close

the actor attached to the expr parser has to be re-attached to the (expr - close) parser construct, which will make the resulting confix parser 'do the right thing'. This refactoring is done by the help of the Refactoring Parsers. Additionally special care must be taken, if the expr parser is a unary_parser_category type parser as

挂接于expr分析器之上的动作器必须重挂接到(expr-close)分析器上,才能使得所产生的片段分析器"行为的当"。这一重构借由重构分析器完成。还有必须要注意的是,如果expr分析器属于unary_parser_category类型的分析器,比如:

    confix_p(open, *anychar_p, close)

which without any refactoring would result in

以上如果不经重构则变成:

    open >> (*anychar_p - close) >> close

and will not give the expected result (*anychar_p will eat up all the input up to the end of the input stream). So we have to refactor this into:

而这将无法得出所期望的结果(*anychar_p将接受任意字符,直到输入耗尽)。因此我们必须把这个重构为:

    open >> *(anychar_p - close) >> close

what will give the correct result.

从而得出正确的结果

The case, where the expr parser is a combination of the two mentioned problems (i.e. the expr parser is a unary parser with an attached action), is handled accordingly too, so:

expr分析器揉杂了以上两个问题的情况(比如expr分析器是一个一元的且挂接了语义动作),也是通过同样的方法处理,因此:

    confix_p(open, (*anychar_p)[func], close)

will be parsed as expected:

将会像下面所期望地那样分析:

    open >> (*(anychar_p - end))[func] >> close

The required refactoring is implemented here with the help of the Refactoring Parsers too.

必要的重构也是借由重构分析器来完成的。

Summary of Confix Parser refactorings

片段分析器重构汇总

You write it as:

源代码:

It is refactored to:

重构为:

confix_p(open, expr, close)

open >> (expr - close)>> close

confix_p(open, expr[func], close)

open >> (expr - close)[func] >> close

confix_p(open, *expr, close)

open >> *(expr - close) >> close

confix_p(open, (*expr)[func], close)

open >> (*(expr - close))[func] >> close

Comment Parsers

注释分析器

The Comment Parser generator template comment_p is helper for generating a correct Confix Parser from auxiliary parameters, which is able to parse comment constructs as follows:


注释分析器生成器模板comment_p是一个用于从附加的参数生成正确的片段分析器的辅助生成器,它可以正确分析类似下面结构的注释:

    StartCommentToken >> Comment text >> EndCommentToken

There are the following types supported as parameters: parsers, single characters and strings (see as_parser). If it is used with one parameter, a comment starting with the given first parser parameter up to the end of the line is matched. So for instance the following parser matches C++ style comments:

参数可以是如下类型:分析器、单个字符和字符串(见as_parser)。如果只有一个参数,那么就认为一个注释就从给定的参数开始直到一行的结束。所以,例如下面的分析器就匹配C++风格的注释:

    comment_p("//")

If it is used with two parameters, a comment starting with the first parser parameter up to the second parser parameter is matched. For instance a C style comment parser could be constrcuted as:

如果使用两个参数,则一个注释从第一个参数开始,直到匹配了第二个参数才结束。比如C风格的注释就可以构造如下:

    comment_p("/*", "*/")

The comment_p parser generator allows to generate parsers for matching non-nested comments (as for C/C++ comments). Sometimes it is necessary to parse nested comments as for instance allowed in Pascal.

comment_p生成器允许生成非嵌套的注释(就像C/C++的注释)。有时需要分析嵌套的注释,就像下面给出的Pascal里的:

    { This is a { nested } PASCAL-comment }

Such nested comments are parseable through parsers generated by the comment_nest_p generator template functor. The following example shows a parser, which can be used for parsing the two different (nestable) Pascal comment styles:

这样的嵌套注释可以用生成器模板仿函数 comment_nest_p所生成的分析器分析。下面的例子给出了一个分析器,它可以用于分析两种不同风格(可嵌套)的Pascal注释:

    rule<> pascal_comment
        =   comment_nest_p("(*", "*)")
        |   comment_nest_p('{', '}')
        ;

Please note, that a comment is parsed implicitly as if the whole comment_p(...) statement were embedded into a lexeme_d[] directive, i.e. during parsing of a comment no token skipping will occur, even if you've defined a skip parser for your whole parsing process.

请注意,这样分析的注释暗示着类似把整个comment_p(...)语句放到一个lexeme_d[]里面,举例而言,在整个分析注释的过程中,将不会有忽略符号的情况发生,即使你已经为你的整个分析过程指定了忽略分析器。

comments.cpp demonstrates various comment parsing schemes:

comments.cpp给出了各种各样的注释分析方案:

  1. Parsing of different comment styles
    分析不同风格的注释
    • parsing C/C++-style comment
      分析C/C++风格的注释
    • parsing C++-style comment
      分析C++风格的注释
    • parsing PASCAL-style comment
      分析PASCAL风格的注释
  2. Parsing tagged data with the help of the confix_parser
    借助confix_parser分析标记语言的数据
  3. Parsing tagged data with the help of the confix_parser but the semantic
    action is directly attached to the body sequence parser

    借助confix_parser分析标记语言的数据,但语义动作直接挂接到片段的内容上

This is part of the Spirit distribution.

这是Spirit发布包的组成部分。



Powered by Zoundry

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值