[Boost Spirit] Zeichenketten und Zahlen parsen
-
Hallo zusammen
Möchte gern chemische Formeln einlesen (C6H12O6, Mg1Cl2 ). Also immer mindestens ein Grossbuchstabe und 0-2 Kleinbuchstaben, ( gefolgt von einer Zahl oder auch nicht bei 1, das gibt noch ein Problem )
Also mit folgender Regel: (Bsp aus der Doku abgeändert)
bool parse_numbers(char const* str, vector<unsigned int>& v/*, vector<std::string>& c*/) { return parse(str, // Begin grammar ( *( range_p('A','Z') >> !( *( range_p('a','z') ) ) >> uint_p[push_back_a(v)]) ) // End grammar ).full; }kann ich strings wie die obigen Parsen und erhalte die Zahlen im Vector v. Nun bräucht ich aber noch die Symbole als Strings in nem anderen Vector c (oder am liebsten als Paare). Wie kann ich die einzelnen Zeichen verketten und so wie mit push_back_a(v) irgendwo rein schreiben?
Danke schonmal im voraus
-
Gibts auch reguläre ausdrücke in boost?
-
Gibts?? Wär noch dick

-
Boost.Regex. Das ist auch im TR1 drin.
-
Hab vorhin grad erst den Artiel im Forum zu Spirit gefunden. Spitze

Habs nun mit einem Funktionsobjekt gemacht, und es klappt
Danke trotzdem und überhaupt
-
Hallo nochmal
Also das ist nun meine Lösung, erhalte die einzelnen Fraktionen als Paare aus Zeichen und Koeffizient, alles wunderbar.
Fast. Ich muss immer eine eins eingeben "H1Cl1", würde gerne aber auch folgendes eingeben
"HCl", also 1 Cl und 1 H. Das gibt aber immer Parserfehler. Vielleicht kann mir jemand nen Tipp geben, wie ich das umgehen kann.typedef std::pair< std::string, unsigned int > SymbolT; typedef std::vector< SymbolT > SymbolTableT; class Parser { enum What { SYMBOL, COEFF }; struct GetSymbol { GetSymbol( SymbolTableT& symbol_table, enum What& switcher, SymbolT& act_item ) : m_symbol_table( symbol_table ), m_switcher( switcher ), m_act_item( act_item ) {} template<typename IteratorT> void operator()( IteratorT begin, IteratorT end ) const { std::string str( begin, end ); switch( m_switcher ) { case SYMBOL: m_act_item.first = str; break; case COEFF: std::stringstream sstr( str ); sstr >> m_act_item.second; m_symbol_table.push_back( m_act_item ); break; } } SymbolTableT& m_symbol_table; enum What& m_switcher; SymbolT& m_act_item; }; public: Parser() {} ~Parser() {} SymbolTableT parse_totals_formula( char const* str ); }; SymbolTableT Parser::parse_totals_formula( char const* str ) { SymbolT act; SymbolTableT ret; enum What symbol = SYMBOL; enum What coeff = COEFF; GetSymbol func_symb( ret, symbol, act ); GetSymbol func_numb( ret, coeff, act ); rule<> symbol_p = ( range_p('A','Z') >> !( *( range_p('a','z') ) ) ); rule<> coeff_p = uint_p; rule<> formel_p = *( symbol_p[func_symb] >> coeff_p[func_numb] ); parse_info<> info = parse(str, formel_p ); if( !info.full ) { std::cout << "Parser error at: " << info.stop << std::endl; } return ret; }Danke mal wieder im voraus
-
...ihr mögt mich nicht

-
Deine Regel erwartet die Formel als Folge aus Symbol+Nummer, d.h. wenn du auch alleinstehende Symbole akzeptieren willst, mußt du den Nummer-Teil optional setzen:
rule<> formel_p = *( symbol_p[func_symb] >> !coeff_p[func_numb] ); //dabei solltest du Dafür sorgen, daß func_symb() den Defaultwert 1 für die Anzahl vorbereitet