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
7#ifndef MATLIB_H_05102009
8#define MATLIB_H_05102009
9#include <boost/spirit/include/lex.hpp>
10#include <vector>
11#include <string>
12
13struct set_lexer_state
14{
15 std::string state;
16 set_lexer_state(const std::string &a):state(a){}
17 template <class Iterator,class Context>
18 void operator () (Iterator const&, Iterator const&
19 , BOOST_SCOPED_ENUM(boost::spirit::lex::pass_flags)&, std::size_t
20 , Context &ctx) const
21 {
22 ctx.set_state_name(state.c_str());
23 }
24};
25
26#ifdef _MSC_VER
27# pragma warning(push)
28# pragma warning(disable: 4512) // assignment operator could not be generated.
29#endif
30struct store_double
31{
32 std::vector<double> &out;
33 store_double(std::vector<double> &a):out(a){}
34 template <class Iterator,class LexerContext>
35 void operator () (Iterator const& start, Iterator const& end
36 , BOOST_SCOPED_ENUM(boost::spirit::lex::pass_flags)&, std::size_t
37 , LexerContext &) const
38 {
39 std::string work(start, end);
40 out.push_back(x: std::atof(nptr: work.c_str()));
41 }
42};
43
44struct add_row
45{
46 std::vector<std::vector<double> > &matrix;
47 std::vector<double> &row;
48
49 add_row(std::vector<std::vector<double> > &a,std::vector<double> &b)
50 :matrix(a),row(b) {}
51 template <class Iterator,class Context>
52 void operator () (Iterator const&, Iterator const&
53 , BOOST_SCOPED_ENUM(boost::spirit::lex::pass_flags)&, std::size_t
54 , Context &ctx) const
55 {
56 matrix.push_back(x: std::vector<double>());
57 matrix.back().swap(x&: row);
58 ctx.set_state_name("A");
59 }
60};
61
62template <class Lexer>
63struct matlib_tokens : boost::spirit::lex::lexer<Lexer>
64{
65 matlib_tokens(std::vector<std::vector<double> > &a)
66 : matrix(a)
67 {
68 typedef boost::spirit::lex::token_def<> token_def_;
69
70 this->self.add_pattern("REAL1", "[0-9]+(\\.[0-9]*)?");
71 this->self.add_pattern("REAL2", "\\.[0-9]+");
72
73 number = "[-+]?({REAL1}|{REAL2})([eE][-+]?[0-9]+)?";
74
75 this->self
76 = token_def_('[') [set_lexer_state("A")]
77 ;
78
79 this->self("A")
80 = token_def_('[') [set_lexer_state("B")]
81 | ','
82 | token_def_(']') [set_lexer_state("INITIAL")]
83 ;
84
85 this->self("B")
86 = number [store_double(row)]
87 | ','
88 | token_def_(']') [add_row(matrix,row)]
89 ;
90 }
91
92 boost::spirit::lex::token_def<> number;
93 std::vector<std::vector<double> > &matrix;
94 std::vector<double> row;
95};
96#ifdef _MSC_VER
97# pragma warning(pop)
98#endif
99
100#endif
101
102

source code of boost/libs/spirit/test/lex/matlib.h