|
From: <bl...@us...> - 2003-05-04 22:13:54
|
Update of /cvsroot/cpptool/rfta/include/xtl
In directory sc8-pr-cvs1:/tmp/cvs-serv24589/include/xtl
Modified Files:
MiniParser.h
Log Message:
* added 'at least one spaces parser': space
* added repeat parser
* added trivial callback mecanism using Boost.Function.
Index: MiniParser.h
===================================================================
RCS file: /cvsroot/cpptool/rfta/include/xtl/MiniParser.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** MiniParser.h 4 May 2003 18:19:27 -0000 1.1
--- MiniParser.h 4 May 2003 22:13:51 -0000 1.2
***************
*** 2,5 ****
--- 2,6 ----
#define XTL_MINIPARSER_H_INCLUDED
+ #include <boost/function.hpp>
#include <xtl/CStringView.h>
#include <stdexcept>
***************
*** 18,22 ****
class AlternativeMiniParser;
!
class Scanner
{
--- 19,23 ----
class AlternativeMiniParser;
! /// Scanner, hold the text being parsed and provide iterator and backtracking.
class Scanner
{
***************
*** 78,82 ****
}
! private:
const Iterator start_;
const Iterator end_;
--- 79,83 ----
}
! protected:
const Iterator start_;
const Iterator end_;
***************
*** 85,90 ****
!
!
struct ParseResult
{
--- 86,90 ----
! /// Result of a parse (returned by each mini-parser).
struct ParseResult
{
***************
*** 107,126 ****
! struct MandatoryMiniParserCategory
! {
! enum { isOptional = false };
! };
!
!
! struct OptionalMiniParserCategory
! {
! enum { isOptional = true };
! };
!
!
class MiniParser
{
public:
! typedef MandatoryMiniParserCategory Category;
virtual ParseResult parse( Scanner &scanner ) const = 0;
--- 107,115 ----
! /// Base abstract class for all parser
class MiniParser
{
public:
! typedef boost::function1<void, const Xtl::CStringView &> MatchedCallback;
virtual ParseResult parse( Scanner &scanner ) const = 0;
***************
*** 132,149 ****
ParseResult matched( Scanner::Iterator start,
const Scanner &scanner ) const
{
! return ParseResult( start, scanner.current() );
}
ParseResult concatResult( const ParseResult &left, const ParseResult &right ) const
{
! return ParseResult( left.matchStart_, right.matchEnd_ );
}
ParseResult emptyMatch( Scanner::Iterator start ) const
{
! return ParseResult( start, start );
}
};
--- 121,158 ----
ParseResult matched( Scanner::Iterator start,
+ Scanner::Iterator end ) const
+ {
+ if ( callback_ )
+ {
+ Xtl::CStringView text( start, end );
+ callback_( text );
+ }
+ return ParseResult( start, end );
+ }
+
+ ParseResult matched( Scanner::Iterator start,
const Scanner &scanner ) const
{
! return matched( start, scanner.current() );
}
ParseResult concatResult( const ParseResult &left, const ParseResult &right ) const
{
!
! return matched( left.matchStart_, right.matchEnd_ );
}
ParseResult emptyMatch( Scanner::Iterator start ) const
{
! return matched( start, start );
! }
!
! protected:
! void setCallback( MatchedCallback callback )
! {
! callback_ = callback;
}
+
+ MatchedCallback callback_;
};
***************
*** 153,180 ****
{
public:
template<typename RightParserType>
SequenceMiniParser<DerivedParserType,RightParserType>
operator >>( const RightParserType &parser) const
{
! return makeSequenceParser( static_cast<const DerivedParserType &>(*this), parser );
}
-
template<typename RightParserType>
AlternativeMiniParser<DerivedParserType,RightParserType>
operator |( const RightParserType &parser) const
{
! return makeAlternativeParser( static_cast<const DerivedParserType &>(*this), parser );
}
-
OptionalMiniParser<DerivedParserType> operator !() const
{
! return makeOptionalParser( static_cast<const DerivedParserType &>(*this) );
}
- };
class CharMiniParser : public MiniParserBase<CharMiniParser>
{
--- 162,203 ----
{
public:
+ const DerivedParserType &derived() const
+ {
+ return static_cast<const DerivedParserType &>(*this);
+ }
+
+ DerivedParserType &derived()
+ {
+ return static_cast<DerivedParserType &>(*this);
+ }
+
template<typename RightParserType>
SequenceMiniParser<DerivedParserType,RightParserType>
operator >>( const RightParserType &parser) const
{
! return makeSequenceParser( derived(), parser );
}
template<typename RightParserType>
AlternativeMiniParser<DerivedParserType,RightParserType>
operator |( const RightParserType &parser) const
{
! return makeAlternativeParser( derived(), parser );
}
OptionalMiniParser<DerivedParserType> operator !() const
{
! return makeOptionalParser( derived() );
}
+ DerivedParserType &operator[]( MatchedCallback callback )
+ {
+ setCallback( callback );
+ return derived();
+ }
+ };
+ /// Matches a single character
class CharMiniParser : public MiniParserBase<CharMiniParser>
{
***************
*** 205,208 ****
--- 228,254 ----
+ /// Matches one or more spaces
+ class SpacesMiniParser : public MiniParserBase<SpacesMiniParser>
+ {
+ public:
+ ParseResult parse( Scanner &scanner ) const
+ {
+ if ( scanner.hasNext() && *scanner == ' ' )
+ {
+ Scanner::Iterator start = scanner.current();
+ ++scanner;
+ while ( scanner.hasNext() && *scanner == ' ' )
+ ++scanner;
+ return matched( start, scanner );
+ }
+
+ return noMatch();
+ }
+ };
+
+
+ const SpacesMiniParser spaces = SpacesMiniParser();
+
+
class StringMiniParser : public MiniParserBase<StringMiniParser>
{
***************
*** 388,393 ****
typedef UnaryMiniParser<ParserType,OptionalMiniParser<ParserType> > SuperClass;
- typedef OptionalMiniParserCategory Category;
-
OptionalMiniParser( const ParserType &parser )
: SuperClass( parser )
--- 434,437 ----
***************
*** 457,460 ****
--- 501,562 ----
{
return AlternativeMiniParser<LeftParserType,RightParserType>( left, right );
+ }
+
+
+ template<typename ParserType>
+ class RepeatMiniParser : public UnaryMiniParser<ParserType
+ ,RepeatMiniParser<ParserType> >
+ {
+ public:
+ typedef UnaryMiniParser<ParserType,RepeatMiniParser<ParserType> > SuperClass;
+
+ RepeatMiniParser( const ParserType &parser,
+ int minOccurrence )
+ : SuperClass( parser )
+ , minOccurrence_( minOccurrence )
+ {
+ }
+
+ ParseResult parse( Scanner &scanner ) const
+ {
+ Scanner::Iterator initial = scanner.current();
+ int count = 0;
+ while ( scanner.hasNext() )
+ {
+ Scanner::Iterator rollback = scanner.current();
+ ParseResult result = parser_.parse( scanner );
+ if ( !result.matched_ )
+ {
+ scanner.backtrack( rollback );
+ break;
+ }
+ ++count;
+ }
+
+ if ( count < minOccurrence_ )
+ {
+ scanner.backtrack( initial );
+ return noMatch();
+ }
+
+ return matched( initial, scanner );
+ }
+
+ int minOccurrence_;
+ int maxOccurrence_;
+ };
+
+
+ template<typename ParserType>
+ RepeatMiniParser<ParserType> makeRepeatParser( const ParserType &parser, int minOccurrence = 0 )
+ {
+ return RepeatMiniParser<ParserType>( parser, minOccurrence );
+ }
+
+
+ template<typename ParserType>
+ RepeatMiniParser<ParserType> makeOnceOrMoreParser( const ParserType &parser )
+ {
+ return RepeatMiniParser<ParserType>( parser, 1 );
}
|