Boost.Spiritのconfix_pパーサーについて少し調べた


Boost.Spiritにはきめの細かいparserがいろいろある。。

confix_pというパーサーがある。

<pre>
 open >> (expr - close) >> close
</pre>

<pre>
    16          definition( const RegExpLiteral& ) {                                                                                                                                         
    17              using phoenix::arg1;                                                                                                                                                     
    18              top  = expr;                                                                                                                                                             
    19              expr = confix_p( '/', *anychar_p, '/' );                                                                                                                                 
    20          }                    
</pre>

confix_pは３つの引数を取る。

<pre>
    19              expr = confix_p( '/', *anychar_p, '/' );    
</pre>

↑は、"/" があり、任意の文字の連続があり、"/"があるという意味。
コードを見てみる。

     1#include <iostream>                                                                                                                                                                    
     2#include <string>                                                                                                                                                                      
     3#include <boost/spirit.hpp>                                                                                                                                                            
     4using namespace std;                                                                                                                                                                   
     5using namespace boost::spirit;                                                                                                                                                         
     6                                                                                                                                                                                       
     7struct RegExpLiteral : grammar<RegExpLiteral>                                                                                                                                          
     8{                                                                                                                                                                                      
     9    struct Bracket : closure<Bracket,char> { member1 br; };                                                                                                                            
    10                                                                                                                                                                                       
    11    template<typename ScannerT>                                                                                                                                                        
    12      struct definition                                                                                                                                                                
    13      {                                                                                                                                                                                
    14          rule<ScannerT> top;                                                                                                                                                          
    15          rule<ScannerT,Bracket::context_t> expr;                                                                                                                                      
    16          definition( const RegExpLiteral& ) {                                                                                                                                         
    17              using phoenix::arg1;                                                                                                                                                     
    18              top  = expr;                                                                                                                                                             
    19              expr = confix_p( '/', *anychar_p, '/' );                                                                                                                                 
    20          }                                                                                                                                                                            
    21          const rule<ScannerT>& start() const  { return top; }                                                                                                                         
    22      };                                                                                                                                                                               
    23};                                                                                                                                                                                     
    24                                                                                                                                                                                       
    25int main()                                                                                                                                                                             
    26{                                                                                                                                                                                      
    27    RegExpLiteral parser;                                                                                                                                                              
    28                                                                                                                                                                                       
    29    string line;                                                                                                                                                                       
    30    while( cout<<"# ", getline(cin, line) )                                                                                                                                            
    31    {                                                                                                                                                                                  
    32        parse_info<string::const_iterator> info =                                                                                                                                      
    33            parse( line.begin(), line.end(), parser );                                                                                                                                 
    34        cout << (info.full ? "parsed." : "failed.") << endl;                                                                                                                           
    35    }                                                                                                                                                                                  
    36    return 0;                                                                                                                                                                          
    37}                                     

https://github.com/RuoAndo/qiita/blob/master/confix_p.cpp

実行してみる。。。

<pre>
# ./a.out 
# /hoge
failed.
# /hoge/
parsed.
# /http
failed.
# /http/
parsed.
# htt
failed.
# /http//
failed.
# /http:/
parsed.
# /http://
failed.
</pre>

（｀ー´）b

Confix Parsers recognize a sequence out of three independent elements: an opening, an expression and a closing. 

Confixパーサーは、３つの要素からなる：opening, express, closing.  
C言語のコメント認識にも使われる。

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