Boost logo

Boost-Commit :

From: eric_at_[hidden]
Date: 2007-10-07 20:44:52


Author: eric_niebler
Date: 2007-10-07 20:44:52 EDT (Sun, 07 Oct 2007)
New Revision: 39774
URL: http://svn.boost.org/trac/boost/changeset/39774

Log:
add awesome number parser from Dave Jenkins
Added:
   trunk/libs/xpressive/example/numbers.cpp (contents, props changed)
Text files modified:
   trunk/libs/xpressive/example/Jamfile.v2 | 7 +++++++
   1 files changed, 7 insertions(+), 0 deletions(-)

Modified: trunk/libs/xpressive/example/Jamfile.v2
==============================================================================
--- trunk/libs/xpressive/example/Jamfile.v2 (original)
+++ trunk/libs/xpressive/example/Jamfile.v2 2007-10-07 20:44:52 EDT (Sun, 07 Oct 2007)
@@ -14,3 +14,10 @@
     :
         <include>$(BOOST_ROOT)
     ;
+
+exe numbers
+ :
+ numbers.cpp
+ :
+ <include>$(BOOST_ROOT)
+ ;

Added: trunk/libs/xpressive/example/numbers.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/xpressive/example/numbers.cpp 2007-10-07 20:44:52 EDT (Sun, 07 Oct 2007)
@@ -0,0 +1,161 @@
+///////////////////////////////////////////////////////////////////////////////
+// main.hpp
+//
+// Copyright 2007 David Jenkins. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if defined(_MSC_VER)
+//disbale warning C4996: 'std::xxx' was declared deprecated
+# pragma warning(disable:4996)
+#endif
+
+#include <iostream>
+#include <string>
+#include <map>
+#include <boost/assign/list_of.hpp> // for 'map_list_of()'
+#include <boost/xpressive/xpressive.hpp>
+#include <boost/xpressive/regex_actions.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// Match all named numbers in a string and return their integer values
+//
+// For example, given the input string:
+// "one two sixty three thousand ninety five eleven"
+// the program will output:
+// "one = 1"
+// "two = 2"
+// "sixty three thousand ninety five = 63095"
+// "eleven = 11"
+
+void example1()
+{
+ using namespace boost::xpressive;
+ using namespace boost::assign;
+
+ // initialize the maps for named numbers
+ std::map< std::string, int > ones_map =
+ map_list_of("one",1)("two",2)("three",3)("four",4)("five",5)
+ ("six",6)("seven",7)("eight",8)("nine",9);
+
+ std::map< std::string, int > teens_map =
+ map_list_of("ten",10)("eleven",11)("twelve",12)("thirteen",13)
+ ("fourteen",14)("fifteen",15)("sixteen",16)("seventeen",17)
+ ("eighteen",18)("nineteen",19);
+
+ std::map< std::string, int > tens_map =
+ map_list_of("twenty",20)("thirty",30)("fourty",40)
+ ("fifty",50)("sixty",60)("seventy",70)("eighty",80)("ninety",90);
+
+ std::map< std::string, int > specials_map =
+ map_list_of("zero",0)("dozen",12)("score",20);
+
+ // n is the integer result
+ long n = 0;
+ // temp stores intermediate values
+ long temp = 0;
+
+ // initialize the delimiters between words
+ sregex delim =
+ +_s | eos | '-' | ',';
+
+ // initialize the regular expressions for named numbers
+ sregex ones_rx =
+ ( a1 = ones_map ) [ ref(n) += a1 ] >> delim;
+
+ sregex tens_rx =
+ ones_rx
+ |
+ (
+ ( a1 = tens_map ) [ ref(n) += a1 ] >> delim
+ >> !ones_rx
+ )
+ |
+ ( ( a1 = teens_map ) [ ref(n) += a1 ] >> delim
+ );
+
+ sregex hundreds_rx =
+ ( ( tens_rx >> "hundred" >> delim )
+ [ ref(n) *= 100 ]
+ >> !tens_rx
+ )
+ | tens_rx;
+
+ sregex thousands_rx =
+ ( ( hundreds_rx >> "thousand" >> delim )
+ [ ref(temp) += ref(n) * 1000, ref(n) = 0 ]
+ >> !hundreds_rx
+ )
+ | hundreds_rx
+ ;
+
+ sregex millions_rx =
+ ( ( hundreds_rx >> "million" >> delim )
+ [ ref(temp) += ref(n) * 1000000, ref(n) = 0 ]
+ >> !thousands_rx
+ )
+ | thousands_rx;
+
+ sregex specials_rx =
+ ( !((a1 = ones_map) >> delim) >> (a2 = specials_map) )
+ [ ref(n) = (a1 | 1) * a2 ]
+ >> delim
+ >> !("and" >> delim >> ones_rx);
+
+ sregex number_rx =
+ bow
+ >>
+ ( specials_rx
+ |
+ millions_rx
+ [ref(n) += ref(temp), ref(temp) = 0 ]
+ );
+
+ // this is the input string
+ std::string str( "one two three eighteen twenty two "
+ "nine hundred ninety nine twelve "
+ "eight hundred sixty three thousand ninety five "
+ "sixty five hundred ten "
+ "two million eight hundred sixty three thousand ninety five "
+ "zero sixty five hundred thousand "
+ "extra stuff -- skip me "
+ "two dozen "
+ "four score and seven ");
+
+ // the results of iterating through the string are:
+ // one = 1
+ // two = 2
+ // three = 3
+ // eighteen = 18
+ // twenty two = 22
+ // nine hundred ninety nine = 999
+ // twelve = 12
+ // eight hundred sixty three thousand ninety five = 863095
+ // sixty five hundred ten = 6510
+ // two million eight hundred sixty three thousand ninety five = 2863095
+ // zero = 0
+ // sixty five hundred thousand = 6500000
+ // two dozen = 24
+ // four score and seven = 87
+ sregex_token_iterator cur( str.begin(), str.end(), number_rx );
+ sregex_token_iterator end;
+
+ for( ; cur != end; ++cur )
+ {
+ std::cout << *cur << " = " << n << '\n';
+ n = 0;
+ }
+ std::cout << '\n';
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// main
+int main()
+{
+ std::cout << "\n\nExample 1:\n\n";
+ example1();
+
+ std::cout << "\n\n" << std::flush;
+
+ return 0;
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk