0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Boost Spirit フレーズレベル解析と文字レベル解析を少し検証してみる

Last updated at Posted at 2020-09-15

Boost Spiritのパーサーには、2つの解析のレベルがある。

■ フレーズレベル解析
■ 文字レベル解析

コードを見てみる。。。

 1#include <iostream>
 2#include <string>
 3#include <boost/spirit.hpp>
 4using namespace std;
 5using namespace boost::spirit;
 6
 7struct VariableWordList : grammar<VariableWordList>
 8{
 9    template<typename ScannerT>
10      struct definition
11      {
12          rule<ScannerT> word, word_list;
13          definition( const VariableWordList& )
14          {
15              word = (alpha_p|'_') >> *(alpha_p|'_'|digit_p);
16              word_list = word % ',';
17          }
18          const rule<ScannerT>& start() const { return word_list; }
19      };
20};
21
22int main()
23{
24    for( string line; cout<<"# ", getline(cin, line); )
25       if( parse(line.c_str(), VariableWordList()).full )
26             cout << "OK" << endl;
27        else cout << "fail" << endl;
28    return 0;
29}

実行してみる。。。


# g++ -o directive0 directive0.cpp -lboost_system
In file included from directive0.cpp:3:0:
/usr/include/boost/spirit.hpp:18:4: warning: #warning "This header is deprecated. Please use: boost/spirit/include/classic.hpp" [-Wcpp]
 #  warning "This header is deprecated. Please use: boost/spirit/include/classic.hpp"
    ^~~~~~~
# ./directive0
# fuge,guwa 
OK
# huge, guwa
fail

コンマ(,)の後にスペースを入れるとfailになる。。。
これを避けるには、space_pを使う。


    25      if( parse(line.c_str(), VariableWordList(), space_p).full )

Boost的には、「space_pを使ってフレーズレベル解析をするようにする」と云ふ。

 1#include <iostream>
 2#include <string>
 3#include <boost/spirit.hpp>
 4using namespace std;
 5using namespace boost::spirit;
 6
 7struct VariableWordList : grammar<VariableWordList>
 8{
 9    template<typename ScannerT>
10      struct definition
11      {
12          rule<ScannerT> word, word_list;
13          definition( const VariableWordList& )
14          {
15              word = (alpha_p|'_') >> *(alpha_p|'_'|digit_p);
16              word_list = word % ',';
17          }
18          const rule<ScannerT>& start() const { return word_list; }
19      };
20};
21
22int main()
23{
24    for( string line; cout<<"# ", getline(cin, line); )
25      if( parse(line.c_str(), VariableWordList(), space_p).full )
26             cout << "OK" << endl;
27        else cout << "fail" << endl;
28    return 0;
29}

実行してみる。。。


# g++ -o directive1 directive1.cpp -lboost_system
In file included from directive1.cpp:3:0:
/usr/include/boost/spirit.hpp:18:4: warning: #warning "This header is deprecated. Please use: boost/spirit/include/classic.hpp" [-Wcpp]
 #  warning "This header is deprecated. Please use: boost/spirit/include/classic.hpp"
    ^~~~~~~
# ./directive1
# gege,huga 
OK
# huge, hyogya
OK

すかし、このような入力↓でもOKが出るようになってしまう。 (´Д`;)


# ./directive1
# huge, gyao
OK
# h ge, gu wa
OK

この場合、15行目にlexeme_dを使う。


    15              word = lexeme_d[ (alpha_p|'_') >> *(alpha_p|'_'|digit_p) ];
 1#include <iostream>
 2#include <string>
 3#include <boost/spirit.hpp>
 4using namespace std;
 5using namespace boost::spirit;
 6
 7struct VariableWordList : grammar<VariableWordList>
 8{
 9    template<typename ScannerT>
10      struct definition
11      {
12          rule<ScannerT> word, word_list;
13          definition( const VariableWordList& )
14          {
15              word = lexeme_d[ (alpha_p|'_') >> *(alpha_p|'_'|digit_p) ];
16              word_list = word % ',';
17          }
18          const rule<ScannerT>& start() const { return word_list; }
19      };
20};
21
22int main()
23{
24    for( string line; cout<<"# ", getline(cin, line); )
25      if( parse(line.c_str(), VariableWordList(), space_p).full )
26             cout << "OK" << endl;
27        else cout << "fail" << endl;
28    return 0;
29}

実行してみる。。。


# ./directive_lexmed 
# huge,goga
OK
# huge, fuga
OK
# h ge, gya o
fail

(`ー´)b

図にするとこうなる。。。

qiita-lexmed.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?