/home/andreas/src/svn/mapnik/include/mapnik/filter_parser_ast.hpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * 
00003  * This file is part of Mapnik (c++ mapping toolkit)
00004  *
00005  * Copyright (C) 2006 Artem Pavlenko
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020  *
00021  *****************************************************************************/
00022 
00023 //$Id$
00024 
00025 #ifndef FILTER_PARSER_AST_HPP
00026 #define FILTER_PARSER_AST_HPP
00027 // stl
00028 #include <iostream>
00029 // boost
00030 #include <boost/spirit/core.hpp>
00031 #include <boost/spirit/tree/ast.hpp>
00032 
00033 using namespace std;
00034 using namespace boost::spirit;
00035 
00036 namespace mapnik
00037 {
00038     
00039     struct filter_grammar_ast : public grammar<filter_grammar_ast>
00040     {
00041         
00042         static const int integerID = 1;
00043         static const int realID = 2;
00044         static const int stringID = 3;
00045         static const int propertyID = 4;
00046         static const int factorID = 5;
00047         static const int termID = 6;
00048         static const int expressionID = 7;
00049         static const int relationID = 8;
00050         static const int equationID = 9;
00051         static const int and_exprID = 10;
00052         static const int or_exprID = 11;
00053         
00054         template <typename ScannerT>
00055         struct definition
00056         {
00057             
00058             definition(filter_grammar_ast const& /*self*/)
00059             {                   
00060                 real = leaf_node_d[strict_real_p];
00061                 integer    = leaf_node_d[int_p];
00062                 number = real | integer;
00063                 
00064                 string_ = inner_node_d['\''>> leaf_node_d[( (alpha_p | '_')  >> 
00065                                                             * (alnum_p | '_' ))] >>  '\''];
00066                 
00067                 property = inner_node_d['[' >> leaf_node_d[ ( (alpha_p | '_') >> * (alnum_p | '_' )) ] >> ']'];
00068                 
00069                 literal = number | string_ | property;
00070                 
00071                 factor = literal 
00072                     | (root_node_d[str_p("not")] >> literal) 
00073                     | inner_node_d[ch_p('(') >> or_expr >> ch_p(')') ]
00074                     | (root_node_d[ch_p('-')] >> factor)
00075                     ;
00076                 
00077                 term = factor
00078                     >> *((root_node_d[ch_p('*')] >> factor) | (root_node_d[ch_p('/')] >> factor));
00079                 
00080                 expression = term >> *((root_node_d[ch_p('+')] >> term) | (root_node_d[ch_p('-')] >> term));
00081                 relation   = expression >> *((root_node_d[str_p(">=")] >> expression) 
00082                                              | (root_node_d[ch_p('>')] >> expression)
00083                                              | (root_node_d[ch_p('<')] >> expression)
00084                                              | (root_node_d[str_p("<=")] >> expression));
00085                 
00086                 equation = relation >> *( (root_node_d[ch_p('=')] >> relation)
00087                                           | (root_node_d[str_p("<>")] >> relation));
00088                 and_expr = equation >> *(root_node_d[str_p("and")] >> equation);
00089                 or_expr  = and_expr >> *(root_node_d[str_p("or")] >> and_expr);
00090                 
00091                 //spatial_op = str_p("Equals") | "Disjoint" | "Touches" | "Within" 
00092                 //   | "Overlaps" | "Crosses" | "Intersects" | "Contains" | "DWithin" | "Beyond" | "BBOX";
00093 
00094                 filter_statement = or_expr;
00095             }
00096             
00097             rule<ScannerT> const& start() const
00098             {
00099                 return filter_statement;
00100             }
00101                     
00102             rule<ScannerT,parser_context<>, parser_tag<factorID> > factor; 
00103             rule<ScannerT,parser_context<>, parser_tag<termID> > term;
00104             rule<ScannerT,parser_context<>, parser_tag<expressionID> > expression;
00105             rule<ScannerT,parser_context<>, parser_tag<relationID> > relation;
00106             rule<ScannerT,parser_context<>, parser_tag<equationID> > equation;
00107             
00108             rule<ScannerT,parser_context<>, parser_tag<and_exprID> > and_expr;
00109             rule<ScannerT,parser_context<>, parser_tag<or_exprID> > or_expr;
00110             
00111             rule<ScannerT> filter_statement;
00112             rule<ScannerT> literal,number;
00113             
00114             rule<ScannerT,parser_context<>, parser_tag<integerID> > integer;
00115             rule<ScannerT,parser_context<>, parser_tag<realID> > real;
00116             rule<ScannerT,parser_context<>, parser_tag<stringID> > string_;
00117             rule<ScannerT,parser_context<>, parser_tag<propertyID> > property;
00118             
00119 
00120             //rule<ScannerT> spatial_op;
00121 
00122         };
00123         
00124     }; 
00125 
00126     class node_data
00127     {
00128     public:
00129         enum node_e {
00130             Unknown=0,
00131             Integer=1,
00132             Real   =2,
00133             String =3,
00134             Property=4
00135         };
00136         node_data()
00137             : type_(Unknown) {}
00138 
00139         node_data(int type)
00140             : type_(type) {}
00141     
00142         node_data(node_data const& other)
00143             : type_(other.type_) {}
00144     
00145         node_data& operator=(node_data const& other)
00146         {
00147             if (this==&other) 
00148                 return *this;
00149             type_=other.type_;
00150             return *this;
00151         }
00152         ~node_data() {}
00153     private:
00154         int type_;    
00155     };
00156 
00157     typedef char const* iterator_t;
00158     typedef node_val_data_factory<node_data> factory_t;
00159     typedef tree_match<iterator_t,factory_t>::tree_iterator iter_t;
00160 
00161     void process_node(iter_t const&,string&);
00162     
00163     void walk_ast_tree(tree_parse_info<iterator_t,factory_t> info,string& text)
00164     {
00165         process_node(info.trees.begin(),text);
00166     }
00167     
00168     void process_node(iter_t const& i,string& text)
00169     {
00170         //clog << "In eval_expression. i->value = " <<
00171         //   string(i->value.begin(), i->value.end()) <<
00172         //   " i->children.size() = " << i->children.size() << endl;
00173         //std::clog<<typeid(*i).name()<<"\n";
00174 
00175         if (i->value.id() == filter_grammar_ast::integerID)
00176         {       
00177             assert(i->children.size()==0);
00178             string integer(i->value.begin(), i->value.end());   
00179             text+= integer;
00180         }
00181         else if (i->value.id() == filter_grammar_ast::realID)
00182         {       
00183             assert(i->children.size()==0);
00184             string real(i->value.begin(), i->value.end());
00185             text += real;
00186         }
00187         else if (i->value.id() == filter_grammar_ast::stringID)
00188         {       
00189             assert(i->children.size()==0);
00190             string str(i->value.begin(), i->value.end());
00191             text += str;
00192         }
00193         else if (i->value.id() == filter_grammar_ast::propertyID)
00194         {
00195             assert(i->children.size()==0);
00196             string property_name(i->value.begin(), i->value.end());
00197             text += property_name;
00198         }
00199         else if (i->value.id() == filter_grammar_ast::expressionID)
00200         {
00201             assert(i->children.size() == 2);
00202             assert(!i->children.begin()->value.is_root());
00203             process_node(i->children.begin(),text);          
00204             text += string(i->value.begin(), i->value.end());
00205             process_node(i->children.begin()+1,text);
00206             
00207             text +="\n";
00208         }
00209         else if (i->value.id() == filter_grammar_ast::termID)
00210         {
00211             assert(i->children.size() == 2);
00212             assert(!i->children.begin()->value.is_root());
00213             process_node(i->children.begin(),text);
00214             text +=  string(i->value.begin(), i->value.end());
00215             process_node(i->children.begin()+1,text);
00216             
00217             text +="\n";
00218         
00219         }
00220         else if (i->value.id() == filter_grammar_ast::relationID)
00221         {
00222             assert(i->children.size() == 2);
00223             assert(!i->children.begin()->value.is_root());
00224             process_node(i->children.begin(),text);
00225             text += string(i->value.begin(), i->value.end());
00226             process_node(i->children.begin()+1,text);
00227             
00228             text +="\n";
00229 
00230         }
00231         else if (i->value.id() == filter_grammar_ast::equationID)
00232         {
00233             assert(i->children.size() == 2);
00234             assert(!i->children.begin()->value.is_root());
00235             process_node(i->children.begin(),text);
00236             text += string(i->value.begin(), i->value.end());
00237             process_node(i->children.begin()+1,text);
00238             
00239             text +="\n";
00240         }
00241         else if (i->value.id() == filter_grammar_ast::and_exprID)
00242         {
00243             assert(i->children.size() == 2);
00244             assert(!i->children.begin()->value.is_root());
00245             process_node(i->children.begin(),text);
00246             text += string(i->value.begin(), i->value.end());
00247             process_node(i->children.begin()+1,text);
00248             
00249             text +="\n";
00250         }
00251         else if (i->value.id() == filter_grammar_ast::or_exprID)
00252         {
00253             assert(i->children.size() == 2);
00254             assert(!i->children.begin()->value.is_root());
00255             
00256             process_node(i->children.begin(),text);
00257             text += string(i->value.begin(), i->value.end());
00258             process_node(i->children.begin()+1,text);
00259             
00260             text +="\n";
00261 
00262         }
00263     }   
00264 }
00265 
00266 #endif //FILTER_PARSER_AST_HPP 

Generated on Thu Jul 19 17:59:26 2007 for Mapnik by  doxygen 1.4.7