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 ); } |