Main Page | Class Hierarchy | Class List | Directories | File List | Class Members

range_expression.h

00001 /***************************************************************************
00002  *   Copyright (C) 2006 by Radko Mihal                                     *
00003  *   rmihal@pobox.sk                                                       *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.              *
00019  ***************************************************************************/
00020 #ifndef BRACKET_EXPRESSIONRANGE_EXPRESSION_H
00021 #define BRACKET_EXPRESSIONRANGE_EXPRESSION_H
00022 
00023 namespace bracket_expression {
00024 
00025 template<typename E>
00026 class range_expression
00027 {
00028 typedef typename grammar_to_parser::basic_parser<E>::parser_list 
00029                                                                                                                                 parser_list;
00030         
00031         class start_range_and_end_range
00032         {
00033                 grammar_to_parser::basic_non_terminal<E,start_range<E> >        
00034                                                                                                                         m_start_range;
00035                 grammar_to_parser::basic_choice<E,collating_choice<E> >
00036                                                                                                                         m_end_range;
00037                 
00038         public:
00039                 unsigned long recognize( const E* buf, const unsigned long buf_length )
00040                 {
00041                         int start_ret = m_start_range->compare(buf,buf_length);
00042                         int size = m_start_range->matched_size();
00043                         while( start_ret < 0 && size > 1) 
00044                         {
00045                                 size--;
00046                                 // while the buf is not higher as start range, try smaller -
00047                                 // collating symbol in buffer
00048                                 start_ret = m_start_range->compare(buf,size);
00049                         }
00050                         int end_ret = 0;
00051                         if( start_ret > 0 )
00052                         {
00053                                 end_ret = m_end_range->compare(buf,size);
00054                                 while( end_ret > 0 && 
00055                                                 size > 1 && 
00056                                                 m_start_range->compare(buf,size-1) >= 0 )
00057                                 {
00058                                         size--;
00059                                         end_ret = m_end_range->compare(buf,size);
00060                                 }
00061                         }
00062                         if( start_ret >=0 && end_ret <= 0 )
00063                                 return size;
00064                         else
00065                                 return 0;
00066                 }
00067                 
00068                 start_range_and_end_range() : m_start_range() {};
00069                 ~start_range_and_end_range() {};
00070                 void push_parsers( parser_list &l )
00071                 {
00072                         l.push_back( &m_start_range );
00073                         l.push_back( &m_end_range );
00074                 }       
00075         };
00076         
00077         class start_range_and_hyphen
00078         {
00079                 grammar_to_parser::basic_non_terminal<E,start_range<E> >        
00080                                                                                                                                 m_start_range;
00081                 grammar_to_parser::basic_terminal<E,'-'>                                m_hyphen;
00082                 
00083         public:
00084                 unsigned long recognize( const E* buf, const unsigned long buf_length )
00085                 {
00086                         int start_ret = m_start_range->compare(buf,buf_length);
00087                         int size = m_start_range->matched_size();
00088                         while( start_ret < 0 && size > 1) 
00089                         {
00090                                 size--;
00091                                 // while the buf is not higher as start range, try smaller -
00092                                 // collating symbol in buffer
00093                                 start_ret = m_start_range->compare(buf,size);
00094                         }
00095                         int end_ret = 0;
00096                         if( start_ret > 0 )
00097                         {
00098                                 end_ret = std::use_facet< std::collate<E> >(std::locale()).compare(
00099                                                                                                 buf,
00100                                                                                                 buf+size,
00101                                                                                                 m_hyphen.get(),
00102                                                                                                 m_hyphen.get()+1 );
00103                                 while( end_ret > 0 && 
00104                                                 size > 1 && 
00105                                                 m_start_range->compare(buf,size-1) >= 0 )
00106                                 {
00107                                         size--;
00108                                         end_ret = std::use_facet< std::collate<E> >(std::locale()).compare(
00109                                                                                                 buf,
00110                                                                                                 buf+size,
00111                                                                                                 m_hyphen.get(),
00112                                                                                                 m_hyphen.get()+1 );
00113                                 }
00114                         }
00115                         if( start_ret >=0 && end_ret <= 0 )
00116                                 return size;
00117                         else
00118                                 return 0;
00119                 }
00120                 
00121                 start_range_and_hyphen() : m_start_range() {};
00122                 ~start_range_and_hyphen() {};
00123                 void push_parsers( parser_list &l )
00124                 {
00125                         l.push_back( &m_start_range );
00126                         l.push_back( &m_hyphen );
00127                 }       
00128         };      
00129         
00130         grammar_to_parser::basic_non_terminal<E,start_range_and_end_range >     
00131                                                                                                                 m_start_end_range;
00132         grammar_to_parser::basic_non_terminal<E,start_range_and_hyphen >                
00133                                                                                                                 m_start_and_hyphen;
00134         
00135 public:
00136         unsigned long recognize( const E* buf, const unsigned long buf_length )
00137         {
00138                 if( m_start_end_range.is_parsed() )
00139                 {
00140                         return m_start_end_range->recognize(buf,buf_length);
00141                 }
00142                 else
00143                 {
00144                         return m_start_and_hyphen->recognize(buf,buf_length);
00145                 }
00146         }
00147     range_expression() : m_start_end_range(), m_start_and_hyphen() {};
00148 
00149     ~range_expression() {};
00150         void push_parsers( parser_list &l )
00151         {
00152                 l.push_back( &m_start_end_range );
00153                 l.push_back( &m_start_and_hyphen );
00154         }       
00155 
00156 };
00157 
00158 };
00159 
00160 #endif

Generated on Sun Jul 2 18:39:43 2006 for grammar2parser.kdevelop by  doxygen 1.4.1