Salut!

Je m'amuse avec un parser Newick, le but etant de parser =par exemple cette string: "(A:0.1,B:0.2,(C:0.3,D:0.4):0.5);"
Malheureusement, bien que les tests passent pour les nodes grammaticaux les plus simples (name, length, leaf), je ne parviens pas a debugger la grammaire complete: quelquechose semble bugger avec la recursion.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
namespace quetzal::newick::parser
{
  namespace x3 = boost::spirit::x3;
 
  using x3::alpha;
  using x3::alnum;
  using x3::double_;
  using x3::rule;
  using x3::phrase_parse;
  using x3::space;
 
  rule<struct branch> branch{"branch"};
  rule<struct branch_set> branch_set{"branch_set"};
 
  auto name    = alpha >> *alnum;
  auto length  = ':' > double_;
  auto leaf    = -name;
  auto internal= '(' >> branch_set >> ')' >> -name;
  auto subtree = leaf | internal;
  auto tree    = subtree >> ';';
 
  auto const branch_def = subtree >> -length;
  auto const branch_set_def = branch | branch >> ',' >> branch_set;
 
  BOOST_SPIRIT_DEFINE(branch, branch_set);
}
Ici sont les tests qui ne passent pas (je ne sais pas encore comment avoir un diagnostique plus precis avec Spirit)

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
BOOST_AUTO_TEST_CASE(internal_grammar)
{
  std::vector<std::string> inputs =
  {
    "(,)",
    "(A,B)F"
  };
 
  for(const auto& input : inputs)
  {
    auto iter = input.begin();
    auto iter_end = input.end();
    bool r = phrase_parse(iter, iter_end, quetzal::newick::parser::internal, x3::space );
    BOOST_CHECK(r);
  }
}
 
BOOST_AUTO_TEST_CASE(full_grammar)
{
  std::vector<std::string> inputs =
  {
    "(,,(,));",
    "(A,B,(C,D));",
    "(A,B,(C,D)E)F;",
    "(:0.1,:0.2,(:0.3,:0.4):0.5);",
    "(:0.1,:0.2,(:0.3,:0.4):0.5):0.0;",
    "(A:0.1,B:0.2,(C:0.3,D:0.4):0.5);",
    "(A:0.1,B:0.2,(C:0.3,D:0.4)E:0.5)F;",
    "((B:0.2,(C:0.3,D:0.4)E:0.5)F:0.1)A;"
  };
 
  for(const auto& input : inputs)
  {
    auto iter = input.begin();
    auto iter_end = input.end();
    bool r = phrase_parse(iter, iter_end, quetzal::newick::parser::tree, x3::space );
    BOOST_CHECK(r);
  }
}