Boost Spirit X3解析文法a^(2n+1)
Boost Spirit X3 parse grammar a^(2n+1)
我正在使用 Boost Spirit X3 解析一些语法,但遇到了一些我无法解释的错误。下面的代码是我正在尝试做的简化版本。
#ifndef BOOST_SPIRIT_X3_NO_RTTI
#define BOOST_SPIRIT_X3_NO_RTTI
#endif
#include "boost/spirit/home/x3.hpp"
#include <iostream>
#include <string>
namespace spirit3 = boost::spirit::x3;
// Grammar for the language: a^(2n+1)
// S -> aPa
// P -> aPa | a
struct P_id;
constexpr auto P = spirit3::rule<P_id, spirit3::unused_type>{};
constexpr auto P_def = ('a' >> P >> 'a') | 'a';
constexpr auto S = 'a' >> P_def >> 'a';
BOOST_SPIRIT_DEFINE(P);
int
main()
{
int n_chars_list[] = {5, 7, 9};
for (auto n_chars : n_chars_list)
{
std::string content;
for (int i = 0; i < n_chars; ++i)
content += 'a';
auto iter = content.begin();
bool is_matched = spirit3::parse(iter, content.end(), S);
bool is_exhausted = (iter == content.end());
std::cout << "n_chars: " << n_chars << '\t';
std::cout << std::boolalpha << "is_matched: " << is_matched << '\t';
std::cout << std::boolalpha << "is_exhausted: " << is_exhausted << '\n';
}
}
// Output:
// n_chars: 5 is_matched: true is_exhausted: false
// n_chars: 7 is_matched: true is_exhausted: true
// n_chars: 9 is_matched: true is_exhausted: false
谁能解释为什么解析器在 n_chars 是 5 或 9 的情况下无法识别整个字符串,但在 7 的情况下却能成功识别?谢谢。
这是语法。为了帮助您诊断问题,我建议对其进行调试:
住在 Coliru
#define BOOST_SPIRIT_X3_DEBUG
#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;
// Grammar for the language: a^(2n+1)
// S -> aPa
// P -> aPa | a
constexpr auto P = x3::rule<struct P_id>{"P"};
constexpr auto P_def = ('a' >> P >> 'a') | 'a';
constexpr auto S = x3::rule<struct S_id>{"S"}
= 'a' >> P >> 'a';
BOOST_SPIRIT_DEFINE(P)
int main() {
for (int n_chars : {5, 7, 9}) {
std::string const content(n_chars, 'a');
bool matched = x3::parse(content.begin(), content.end(), S >> x3::eoi);
std::cout << "n_chars: " << n_chars << '\t';
std::cout << std::boolalpha << "matched: " << matched << "\n";
}
}
标准输出:
n_chars: 5 matched: false
n_chars: 7 matched: true
n_chars: 9 matched: false
标准错误调试信息:
<S>
<try>aaaaa</try>
<P>
<try>aaaa</try>
<P>
<try>aaa</try>
<P>
<try>aa</try>
<P>
<try>a</try>
<P>
<try></try>
<fail/>
</P>
<success></success>
</P>
<success>a</success>
</P>
<success></success>
</P>
<success>aaa</success>
</P>
<success>aa</success>
</S>
n_chars: 5 matched: false
<S>
<try>aaaaaaa</try>
<P>
<try>aaaaaa</try>
<P>
<try>aaaaa</try>
<P>
<try>aaaa</try>
<P>
<try>aaa</try>
<P>
<try>aa</try>
<P>
<try>a</try>
<P>
<try></try>
<fail/>
</P>
<success></success>
</P>
<success>a</success>
</P>
<success></success>
</P>
<success>aaa</success>
</P>
<success>aa</success>
</P>
<success>a</success>
</P>
<success></success>
</S>
n_chars: 7 matched: true
<S>
<try>aaaaaaaaa</try>
<P>
<try>aaaaaaaa</try>
<P>
<try>aaaaaaa</try>
<P>
<try>aaaaaa</try>
<P>
<try>aaaaa</try>
<P>
<try>aaaa</try>
<P>
<try>aaa</try>
<P>
<try>aa</try>
<P>
<try>a</try>
<P>
<try></try>
<fail/>
</P>
<success></success>
</P>
<success>a</success>
</P>
<success></success>
</P>
<success>aaa</success>
</P>
<success>aa</success>
</P>
<success>a</success>
</P>
<success></success>
</P>
<success>aaaaaaa</success>
</P>
<success>aaaaaa</success>
</S>
n_chars: 9 matched: false
旁注,我简化了一些代码(不必要的循环)以及单独的“耗尽”测试,而不是在解析器表达式的末尾断言 x3::eoi
。
我正在使用 Boost Spirit X3 解析一些语法,但遇到了一些我无法解释的错误。下面的代码是我正在尝试做的简化版本。
#ifndef BOOST_SPIRIT_X3_NO_RTTI
#define BOOST_SPIRIT_X3_NO_RTTI
#endif
#include "boost/spirit/home/x3.hpp"
#include <iostream>
#include <string>
namespace spirit3 = boost::spirit::x3;
// Grammar for the language: a^(2n+1)
// S -> aPa
// P -> aPa | a
struct P_id;
constexpr auto P = spirit3::rule<P_id, spirit3::unused_type>{};
constexpr auto P_def = ('a' >> P >> 'a') | 'a';
constexpr auto S = 'a' >> P_def >> 'a';
BOOST_SPIRIT_DEFINE(P);
int
main()
{
int n_chars_list[] = {5, 7, 9};
for (auto n_chars : n_chars_list)
{
std::string content;
for (int i = 0; i < n_chars; ++i)
content += 'a';
auto iter = content.begin();
bool is_matched = spirit3::parse(iter, content.end(), S);
bool is_exhausted = (iter == content.end());
std::cout << "n_chars: " << n_chars << '\t';
std::cout << std::boolalpha << "is_matched: " << is_matched << '\t';
std::cout << std::boolalpha << "is_exhausted: " << is_exhausted << '\n';
}
}
// Output:
// n_chars: 5 is_matched: true is_exhausted: false
// n_chars: 7 is_matched: true is_exhausted: true
// n_chars: 9 is_matched: true is_exhausted: false
谁能解释为什么解析器在 n_chars 是 5 或 9 的情况下无法识别整个字符串,但在 7 的情况下却能成功识别?谢谢。
这是语法。为了帮助您诊断问题,我建议对其进行调试:
住在 Coliru
#define BOOST_SPIRIT_X3_DEBUG
#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;
// Grammar for the language: a^(2n+1)
// S -> aPa
// P -> aPa | a
constexpr auto P = x3::rule<struct P_id>{"P"};
constexpr auto P_def = ('a' >> P >> 'a') | 'a';
constexpr auto S = x3::rule<struct S_id>{"S"}
= 'a' >> P >> 'a';
BOOST_SPIRIT_DEFINE(P)
int main() {
for (int n_chars : {5, 7, 9}) {
std::string const content(n_chars, 'a');
bool matched = x3::parse(content.begin(), content.end(), S >> x3::eoi);
std::cout << "n_chars: " << n_chars << '\t';
std::cout << std::boolalpha << "matched: " << matched << "\n";
}
}
标准输出:
n_chars: 5 matched: false
n_chars: 7 matched: true
n_chars: 9 matched: false
标准错误调试信息:
<S>
<try>aaaaa</try>
<P>
<try>aaaa</try>
<P>
<try>aaa</try>
<P>
<try>aa</try>
<P>
<try>a</try>
<P>
<try></try>
<fail/>
</P>
<success></success>
</P>
<success>a</success>
</P>
<success></success>
</P>
<success>aaa</success>
</P>
<success>aa</success>
</S>
n_chars: 5 matched: false
<S>
<try>aaaaaaa</try>
<P>
<try>aaaaaa</try>
<P>
<try>aaaaa</try>
<P>
<try>aaaa</try>
<P>
<try>aaa</try>
<P>
<try>aa</try>
<P>
<try>a</try>
<P>
<try></try>
<fail/>
</P>
<success></success>
</P>
<success>a</success>
</P>
<success></success>
</P>
<success>aaa</success>
</P>
<success>aa</success>
</P>
<success>a</success>
</P>
<success></success>
</S>
n_chars: 7 matched: true
<S>
<try>aaaaaaaaa</try>
<P>
<try>aaaaaaaa</try>
<P>
<try>aaaaaaa</try>
<P>
<try>aaaaaa</try>
<P>
<try>aaaaa</try>
<P>
<try>aaaa</try>
<P>
<try>aaa</try>
<P>
<try>aa</try>
<P>
<try>a</try>
<P>
<try></try>
<fail/>
</P>
<success></success>
</P>
<success>a</success>
</P>
<success></success>
</P>
<success>aaa</success>
</P>
<success>aa</success>
</P>
<success>a</success>
</P>
<success></success>
</P>
<success>aaaaaaa</success>
</P>
<success>aaaaaa</success>
</S>
n_chars: 9 matched: false
旁注,我简化了一些代码(不必要的循环)以及单独的“耗尽”测试,而不是在解析器表达式的末尾断言 x3::eoi
。