2016-08-21 1 views
0

Mon problème est le suivant. J'ai un noeud ast qui est défini comme comme ce qui suit:analyse d'une seule valeur dans un nœud ast avec un conteneur

struct foo_node{ 
    std::vector<std::string> value; 
} 

et j'ai un analyseur comme celui-ci pour l'analyse syntaxique dans le struct, qui fonctionne très bien:

typedef x3::rule<struct foo_node_class, foo_node> foo_node_type; 
const foo_node_type foo_node = "foo_node"; 
auto const foo_node_def = "(" >> +x3::string("bar") >> ")"; 

Maintenant, je veux y parvenir l'analyseur analyse également "bar", sans crochets, mais seulement si c'est une barre unique. J'ai essayé de le faire comme ceci:

auto const foo_node_def = x3::string("bar") 
          | "(" > +x3::string("bar") > ")"; 

mais cela me donne une erreur de compilation, car x3::string("bar") retourne une chaîne et non un std::vector<std::string>. Ma question est, comment puis-je réaliser, que l'analyseur syntaxique x3::string("bar") (et tous les autres analyseurs qui retournent une chaîne) analyse un vecteur?

+1

s'il vous plaît toujours après a [mcve] –

+0

Je suis entièrement d'accord avec l'exigence d'un MCVE/SSCCE. Dans votre cas vous aviez des conflits de nommage impossibles et des choses essentielles manquantes ("SPIRIT_DEFINE") que seuls les experts sauraient "deviner" – sehe

+0

Je suis vraiment désolé je n'étais pas en ligne jusqu'à maintenant – Exagon

Répondre

2

La façon d'analyser un seul élément et l'exposer comme un attribut de conteneur à un seul élément est x3::repeat(1) [ p ]:

Live On Coliru

#include <boost/fusion/adapted/struct.hpp> 
#include <boost/spirit/home/x3.hpp> 
#include <iostream> 

namespace x3 = boost::spirit::x3; 

struct foo_node { 
    std::vector<std::string> value; 
}; 

BOOST_FUSION_ADAPT_STRUCT(foo_node, value) 

namespace rules { 
    auto const bar 
     = x3::string("bar"); 

    auto const foo_node 
     = '(' >> +bar >> ')' 
     | x3::repeat(1) [ +bar ] 
     ; 
} 

int main() { 
    for (std::string const input : { 
      "bar", 
      "(bar)", 
      "(barbar)", 
      }) 
    { 
     auto f = input.begin(), l = input.end(); 

     foo_node data; 
     bool ok = x3::parse(f, l, rules::foo_node, data); 

     if (ok) { 
      std::cout << "Parse success: " << data.value.size() << " elements\n"; 
     } else { 
      std::cout << "Parse failed\n"; 
     } 

     if (f != l) 
      std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n"; 
    } 
} 

Prints

Parse success: 1 elements 
Parse success: 1 elements 
Parse success: 2 elements