matlib.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // Copyright (c) 2001-2009 Hartmut Kaiser
  2. // Copyright (c) 2009 Carl Barron
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef MATLIB_H_05102009
  7. #define MATLIB_H_05102009
  8. #include <boost/spirit/include/lex.hpp>
  9. #include <vector>
  10. #include <string>
  11. struct set_lexer_state
  12. {
  13. std::string state;
  14. set_lexer_state(const std::string &a):state(a){}
  15. template <class Iterator,class Context>
  16. void operator () (Iterator const&, Iterator const&
  17. , BOOST_SCOPED_ENUM(boost::spirit::lex::pass_flags)&, std::size_t
  18. , Context &ctx) const
  19. {
  20. ctx.set_state_name(state.c_str());
  21. }
  22. };
  23. struct store_double
  24. {
  25. std::vector<double> &out;
  26. store_double(std::vector<double> &a):out(a){}
  27. template <class Iterator,class LexerContext>
  28. void operator () (Iterator const& start, Iterator const& end
  29. , BOOST_SCOPED_ENUM(boost::spirit::lex::pass_flags)&, std::size_t
  30. , LexerContext &) const
  31. {
  32. std::string work(start, end);
  33. out.push_back(std::atof(work.c_str()));
  34. }
  35. // silence MSVC warning C4512: assignment operator could not be generated
  36. BOOST_DELETED_FUNCTION(store_double& operator= (store_double const&));
  37. };
  38. struct add_row
  39. {
  40. std::vector<std::vector<double> > &matrix;
  41. std::vector<double> &row;
  42. add_row(std::vector<std::vector<double> > &a,std::vector<double> &b)
  43. :matrix(a),row(b) {}
  44. template <class Iterator,class Context>
  45. void operator () (Iterator const&, Iterator const&
  46. , BOOST_SCOPED_ENUM(boost::spirit::lex::pass_flags)&, std::size_t
  47. , Context &ctx) const
  48. {
  49. matrix.push_back(std::vector<double>());
  50. matrix.back().swap(row);
  51. ctx.set_state_name("A");
  52. }
  53. // silence MSVC warning C4512: assignment operator could not be generated
  54. BOOST_DELETED_FUNCTION(add_row& operator= (add_row const&));
  55. };
  56. template <class Lexer>
  57. struct matlib_tokens : boost::spirit::lex::lexer<Lexer>
  58. {
  59. matlib_tokens(std::vector<std::vector<double> > &a)
  60. : matrix(a)
  61. {
  62. typedef boost::spirit::lex::token_def<> token_def_;
  63. this->self.add_pattern("REAL1", "[0-9]+(\\.[0-9]*)?");
  64. this->self.add_pattern("REAL2", "\\.[0-9]+");
  65. number = "[-+]?({REAL1}|{REAL2})([eE][-+]?[0-9]+)?";
  66. this->self
  67. = token_def_('[') [set_lexer_state("A")]
  68. ;
  69. this->self("A")
  70. = token_def_('[') [set_lexer_state("B")]
  71. | ','
  72. | token_def_(']') [set_lexer_state("INITIAL")]
  73. ;
  74. this->self("B")
  75. = number [store_double(row)]
  76. | ','
  77. | token_def_(']') [add_row(matrix,row)]
  78. ;
  79. }
  80. boost::spirit::lex::token_def<> number;
  81. std::vector<std::vector<double> > &matrix;
  82. std::vector<double> row;
  83. };
  84. #endif