Basic tagfile parser
authorMichael Andres <ma@suse.de>
Mon, 9 Jan 2006 09:59:13 +0000 (09:59 +0000)
committerMichael Andres <ma@suse.de>
Mon, 9 Jan 2006 09:59:13 +0000 (09:59 +0000)
zypp/parser/tagfile/Grammar.h [new file with mode: 0644]
zypp/parser/tagfile/Makefile.am
zypp/parser/tagfile/ParseException.cc [new file with mode: 0644]
zypp/parser/tagfile/ParseException.h [new file with mode: 0644]
zypp/parser/tagfile/Parser.cc [new file with mode: 0644]
zypp/parser/tagfile/Parser.h [new file with mode: 0644]
zypp/parser/tagfile/Tags.h

diff --git a/zypp/parser/tagfile/Grammar.h b/zypp/parser/tagfile/Grammar.h
new file mode 100644 (file)
index 0000000..1846f26
--- /dev/null
@@ -0,0 +1,189 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file      zypp/parser/tagfile/Grammar.h
+ *
+*/
+#ifndef ZYPP_PARSER_TAGFILE_GRAMMAR_H
+#define ZYPP_PARSER_TAGFILE_GRAMMAR_H
+
+#include <iosfwd>
+
+#include "zypp/parser/tagfile/Tags.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////
+  namespace parser
+  { /////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////
+    namespace tagfile
+    { /////////////////////////////////////////////////////////////////
+
+      typedef scanner<iterator_t>  scanner_t;
+      typedef rule<scanner_t>      rule_t;
+
+      ////////////////////////////////////////////////////////////////////////////
+      //
+      //  Closures
+      //
+      ////////////////////////////////////////////////////////////////////////////
+
+      struct TagClosure : public spirit::closure<TagClosure, Tag>
+      {
+        member1 val;
+      };
+      typedef TagClosure::context_t TagVal;
+
+      struct STagClosure : public spirit::closure<STagClosure, STag>
+      {
+        member1 val;
+      };
+      typedef STagClosure::context_t STagVal;
+
+      struct MTagClosure : public spirit::closure<MTagClosure, MTag, std::string>
+      {
+        member1 val;
+        member2 expect;
+      };
+      typedef MTagClosure::context_t MTagVal;
+
+      ////////////////////////////////////////////////////////////////////////////
+      //
+      //  SingleTag Grammar
+      //
+      ////////////////////////////////////////////////////////////////////////////
+
+      struct SingleTag : public grammar<SingleTag, STagVal>
+      {
+        template <typename ScannerT>
+          struct definition
+          {
+            definition( const SingleTag & self )
+            {
+              first =
+              (
+                line
+                    = stag                [bind(&STag::stag)(self.val)=arg1]
+                      >> *blank_p
+                      >> (!data)          [bind(&STag::data)(self.val)=construct_<Range>(arg1,arg2)]
+                                          [bind(&STag::value)(self.val)=construct_<std::string>(arg1,arg2)]
+                      >> *blank_p
+                      >> (eol_p|end_p)
+                ,
+                stag
+                    = ( ch_p('=')
+                        >> (+alpha_p)     [bind(&Tag::ident)(stag.val)=construct_<std::string>(arg1,arg2)]
+                        >> !( '.'
+                              >> (+alpha_p) [bind(&Tag::ext)(stag.val)=construct_<std::string>(arg1,arg2)]
+                            )
+                        >> ':'
+                      )                   [bind(&Tag::range)(stag.val)=construct_<Range>(arg1,arg2)]
+                ,
+                data
+                    = +~space_p
+                      >> *( +blank_p
+                            >> +~space_p
+                          )
+              );
+            }
+
+            subrule<0>        line;
+            subrule<1,TagVal> stag;
+            subrule<2>        data;
+
+            rule<ScannerT> first;
+            const rule<ScannerT> & start() const
+            { return first; }
+          };
+      };
+
+      ////////////////////////////////////////////////////////////////////////////
+      //
+      //  MultiTag Grammar
+      //
+      ////////////////////////////////////////////////////////////////////////////
+
+      struct MultiTag : public grammar<MultiTag, MTagVal>
+      {
+        template <typename ScannerT>
+          struct definition
+          {
+            definition( const MultiTag & self )
+            {
+              first =
+              (
+                line
+                    = stag                  [bind(&MTag::stag)(self.val)=arg1]
+                      >> *(anychar_p - eol_p)
+                      >> eol_p
+                      >> data               [bind(&MTag::data)(self.val)=construct_<Range>(arg1,arg2)]
+                      >> ( etag             [bind(&MTag::etag)(self.val)=arg1]
+                         | error_report_p( "Missing end tag" )
+                         )
+                      >> *(anychar_p - eol_p)
+                      >> (eol_p|end_p)
+                ,
+                stag
+                    = ( ch_p('+')
+                        >> ( (+alpha_p)     [bind(&Tag::ident)(stag.val)=construct_<std::string>(arg1,arg2)]
+                             >> !( '.'
+                                    >> (+alpha_p) [bind(&Tag::ext)(stag.val)=construct_<std::string>(arg1,arg2)]
+                                 )
+                           )                [self.expect=construct_<std::string>(arg1,arg2)]
+                        >> ':'
+                      )                     [bind(&Tag::range)(stag.val)=construct_<Range>(arg1,arg2)]
+                ,
+                data
+                    = while_p( ~eps_p(dataend) )
+                      [
+                        ( !( *blank_p >> +~space_p
+                              >> *( +blank_p >> +~space_p )
+                           )
+                        )                   [push_back(bind(&MTag::value)(self.val),construct_<std::string>(arg1,arg2))]
+                        >> *blank_p
+                        >> eol_p
+                      ]
+                ,
+                dataend
+                    = ( ch_p('-') | ch_p('+') )
+                      >> f_str_p(self.expect)
+                      >> ':'
+                ,
+                etag
+                    = ( ch_p('-')
+                        >> f_str_p(self.expect)
+                        >> ':'
+                      )                     [bind(&Tag::range)(etag.val)=construct_<Range>(arg1,arg2)]
+
+              );
+            }
+
+            subrule<0>        line;
+            subrule<1,TagVal> stag;
+            subrule<2>        data;
+            subrule<3>        dataend;
+            subrule<4,TagVal> etag;
+
+            rule<ScannerT> first;
+            const rule<ScannerT> & start() const
+            { return first; }
+          };
+      };
+
+      /////////////////////////////////////////////////////////////////
+    } // namespace tagfile
+    ///////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////
+  } // namespace parser
+  ///////////////////////////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_PARSER_TAGFILE_GRAMMAR_H
index ba07894..e1d9a39 100644 (file)
@@ -8,14 +8,19 @@ INCLUDES =
 ## ##################################################
 
 include_HEADERS = \
-       Tags.h
+       ParseException.h\
+       Tags.h          \
+       Grammar.h       \
+       Parser.h
 
 noinst_LTLIBRARIES =   lib@PACKAGE@_parser_tagfile.la
 
 ## ##################################################
 
 lib@PACKAGE@_parser_tagfile_la_SOURCES = \
-       Tags.cc
+       ParseException.cc\
+       Tags.cc         \
+       Parser.cc
 
 lib@PACKAGE@_parser_tagfile_la_LIBADD =
 
diff --git a/zypp/parser/tagfile/ParseException.cc b/zypp/parser/tagfile/ParseException.cc
new file mode 100644 (file)
index 0000000..9472894
--- /dev/null
@@ -0,0 +1,73 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file      zypp/parser/tagfile/ParseException.cc
+ *
+*/
+#include <iostream>
+//#include "zypp/base/Logger.h"
+
+#include "zypp/parser/tagfile/ParseException.h"
+
+using std::endl;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////
+  namespace parser
+  { /////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////
+    namespace tagfile
+    { /////////////////////////////////////////////////////////////////
+
+      ///////////////////////////////////////////////////////////////////
+      //
+      //       METHOD NAME : ParseException::ParseException
+      //       METHOD TYPE : Ctor
+      //
+      ParseException::ParseException()
+      : Exception( "Parse exception" )
+      {}
+
+      ///////////////////////////////////////////////////////////////////
+      //
+      //       METHOD NAME : ParseException::ParseException
+      //       METHOD TYPE : Ctor
+      //
+      ParseException::ParseException( const std::string & msg_r )
+      : Exception( msg_r )
+      {}
+
+      ///////////////////////////////////////////////////////////////////
+      //
+      //       METHOD NAME : ParseException::~ParseException
+      //       METHOD TYPE : Dtor
+      //
+      ParseException::~ParseException() throw()
+      {}
+
+      ///////////////////////////////////////////////////////////////////
+      //
+      //       METHOD NAME : ParseException::dumpOn
+      //       METHOD TYPE : std::ostream &
+      //
+      std::ostream & ParseException::dumpOn( std::ostream & str ) const
+      {
+        return Exception::dumpOn( str );
+      }
+
+      /////////////////////////////////////////////////////////////////
+    } // namespace tagfile
+    ///////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////
+  } // namespace parser
+  ///////////////////////////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
diff --git a/zypp/parser/tagfile/ParseException.h b/zypp/parser/tagfile/ParseException.h
new file mode 100644 (file)
index 0000000..e92ddbb
--- /dev/null
@@ -0,0 +1,58 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file      zypp/parser/tagfile/ParseException.h
+ *
+*/
+#ifndef ZYPP_PARSER_TAGFILE_PARSEEXCEPTION_H
+#define ZYPP_PARSER_TAGFILE_PARSEEXCEPTION_H
+
+#include <iosfwd>
+#include <string>
+
+#include "zypp/base/Exception.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////
+  namespace parser
+  { /////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////
+    namespace tagfile
+    { /////////////////////////////////////////////////////////////////
+
+      ///////////////////////////////////////////////////////////////////
+      //
+      //       CLASS NAME : ParseException
+      //
+      /** */
+      class ParseException : public Exception
+      {
+      public:
+        /** Default ctor */
+        ParseException();
+        /** Ctor */
+        ParseException( const std::string & msg_r );
+         /** Dtor */
+        virtual ~ParseException() throw();
+      protected:
+        virtual std::ostream & dumpOn( std::ostream & str ) const;
+      };
+      ///////////////////////////////////////////////////////////////////
+
+      /////////////////////////////////////////////////////////////////
+    } // namespace tagfile
+    ///////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////
+  } // namespace parser
+  ///////////////////////////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_PARSER_TAGFILE_PARSEEXCEPTION_H
diff --git a/zypp/parser/tagfile/Parser.cc b/zypp/parser/tagfile/Parser.cc
new file mode 100644 (file)
index 0000000..2b1da09
--- /dev/null
@@ -0,0 +1,149 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file      zypp/parser/tagfile/Parser.cc
+ *
+*/
+#include <iostream>
+#include "zypp/base/Logger.h"
+#include "zypp/base/PtrTypes.h"
+
+#include "zypp/parser/tagfile/Parser.h"
+#include "zypp/parser/tagfile/Grammar.h"
+
+using std::endl;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////
+  namespace parser
+  { /////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////
+    namespace tagfile
+    { /////////////////////////////////////////////////////////////////
+
+      // translate operator= into Parser::consume calls
+      struct ParserConnect
+      {
+        ParserConnect( Parser & consumer_r )
+        : _consumer( consumer_r )
+        {}
+
+        const ParserConnect & operator=( const STag & stag_r ) const
+        { _consumer.consume( stag_r ); return *this; }
+
+        const ParserConnect & operator=( const MTag & mtag_r ) const
+        { _consumer.consume( mtag_r ); return *this; }
+
+        Parser & _consumer;
+      };
+
+      static void doParse( iterator_t begin_r, iterator_t end_r,
+                           const ParserConnect & consumer_r );
+
+      ///////////////////////////////////////////////////////////////////
+      //
+      //       METHOD NAME : Parser::parse
+      //       METHOD TYPE : void
+      //
+      void Parser::parse( const Pathname & file_r )
+      {
+        // Create a file iterator for this file
+        fiterator_t first( file_r.asString() );
+        if (!first)
+          {
+            ZYPP_THROW( ParseException( std::string("Unable to open file ")
+                                        + file_r.asString() ) );
+          }
+        // Create an EOF iterator
+        fiterator_t last = first.make_end();
+
+        // Create position iterators
+        iterator_t begin( first, last, file_r.asString() );
+        iterator_t end;
+
+        // go
+        doParse( begin, end, *this );
+      }
+
+      ///////////////////////////////////////////////////////////////////
+      // Just for the stats
+      struct Measure
+      {
+        time_t _begin;
+        Measure()
+        : _begin( time(NULL) )
+        {
+          USR << "START MEASURE..." << endl;
+        }
+        ~Measure()
+        {
+          USR << "DURATION: " << (time(NULL)-_begin) << " sec." << endl;
+        }
+      };
+      ///////////////////////////////////////////////////////////////////
+
+      ///////////////////////////////////////////////////////////////////
+      //
+      //       doParse
+      //
+      ///////////////////////////////////////////////////////////////////
+
+      static void doParse( iterator_t begin_r,
+                           iterator_t end_r,
+                           const ParserConnect & consumer_r )
+      {
+        SingleTag stag;
+        MultiTag  mtag;
+
+        rule_t file =   end_p
+                      | ( stag [var(consumer_r)=arg1]
+                        | mtag [var(consumer_r)=arg1]
+                        | ( *blank_p
+                            >> !( ch_p('#')
+                                  >> *(anychar_p - eol_p)
+                                )
+                            >> (eol_p|end_p)
+                          )
+                          | error_report_p( "illegal line" )
+                        )
+                        >> file
+                    ;
+
+        shared_ptr<Measure> duration( new Measure );
+        parse_info<iterator_t> info = parse( begin_r, end_r, file );
+        duration.reset();
+
+        if ( info.full )
+          USR << "Parse succeeded!\n";
+        else
+          {
+            if ( info.hit )
+              {
+                ERR << "Parse partial!\n";
+                ERR << " at pos " << info.length << endl;
+              }
+            else
+              {
+                ERR << "Parse failed!\n";
+                ERR << " at pos " << info.length << endl;
+              }
+            ZYPP_THROW( ParseException("Parse failed") );
+          }
+      }
+
+      /////////////////////////////////////////////////////////////////
+    } // namespace tagfile
+    ///////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////
+  } // namespace parser
+  ///////////////////////////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
diff --git a/zypp/parser/tagfile/Parser.h b/zypp/parser/tagfile/Parser.h
new file mode 100644 (file)
index 0000000..3b455c8
--- /dev/null
@@ -0,0 +1,66 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file      zypp/parser/tagfile/Parser.h
+ *
+*/
+#ifndef ZYPP_PARSER_TAGFILE_PARSER_H
+#define ZYPP_PARSER_TAGFILE_PARSER_H
+
+#include <iosfwd>
+
+#include "zypp/parser/tagfile/Tags.h"
+#include "zypp/parser/tagfile/ParseException.h"
+
+#include "zypp/Pathname.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////
+  namespace parser
+  { /////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////
+    namespace tagfile
+    { /////////////////////////////////////////////////////////////////
+
+      ///////////////////////////////////////////////////////////////////
+      //
+      //       CLASS NAME : Parser
+      //
+      /** Tagfile parser. */
+      struct Parser
+      {
+        virtual ~Parser()
+        {}
+
+        /* Overload to consume SingleTag data. */
+        virtual void consume( const STag & stag_r )
+        {}
+        /* Overload to consume MulitTag data. */
+        virtual void consume( const MTag & mtag_r )
+        {}
+
+        /* Parse file and invoke consume on each tag found.
+         * \throw ParseException
+         * \todo more doc on Ecaptions.
+        */
+        void parse( const Pathname & file_r );
+      };
+      ///////////////////////////////////////////////////////////////////
+
+      /////////////////////////////////////////////////////////////////
+    } // namespace tagfile
+    ///////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////
+  } // namespace parser
+  ///////////////////////////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_PARSER_TAGFILE_PARSER_H
index ca6cb34..4746e31 100644 (file)
@@ -89,154 +89,6 @@ namespace zypp
       /** \relates MTag Stream output.*/
       std::ostream & operator<<( std::ostream & str, const MTag & obj );
 
-      ////////////////////////////////////////////////////////////////////////////
-      //
-      //  Closures
-      //
-      ////////////////////////////////////////////////////////////////////////////
-
-      struct TagClosure : public spirit::closure<TagClosure, Tag>
-      {
-        member1 val;
-      };
-      typedef TagClosure::context_t TagVal;
-
-      struct STagClosure : public spirit::closure<STagClosure, STag>
-      {
-        member1 val;
-      };
-      typedef STagClosure::context_t STagVal;
-
-      struct MTagClosure : public spirit::closure<MTagClosure, MTag, std::string>
-      {
-        member1 val;
-        member2 expect;
-      };
-      typedef MTagClosure::context_t MTagVal;
-
-      ////////////////////////////////////////////////////////////////////////////
-      //
-      //  SingleTag Grammar
-      //
-      ////////////////////////////////////////////////////////////////////////////
-
-      struct SingleTag : public grammar<SingleTag, STagVal>
-      {
-        template <typename ScannerT>
-          struct definition
-          {
-            definition( const SingleTag & self )
-            {
-              first =
-              (
-                line
-                    = stag                [bind(&STag::stag)(self.val)=arg1]
-                      >> *blank_p
-                      >> (!data)          [bind(&STag::data)(self.val)=construct_<Range>(arg1,arg2)]
-                                          [bind(&STag::value)(self.val)=construct_<std::string>(arg1,arg2)]
-                      >> *blank_p
-                      >> (eol_p|end_p)
-                ,
-                stag
-                    = ( ch_p('=')
-                        >> (+alpha_p)     [bind(&Tag::ident)(stag.val)=construct_<std::string>(arg1,arg2)]
-                        >> !( '.'
-                              >> (+alpha_p) [bind(&Tag::ext)(stag.val)=construct_<std::string>(arg1,arg2)]
-                            )
-                        >> ':'
-                      )                   [bind(&Tag::range)(stag.val)=construct_<Range>(arg1,arg2)]
-                ,
-                data
-                    = +~space_p
-                      >> *( +blank_p
-                            >> +~space_p
-                          )
-              );
-            }
-
-            subrule<0>        line;
-            subrule<1,TagVal> stag;
-            subrule<2>        data;
-
-            rule<ScannerT> first;
-            const rule<ScannerT> & start() const
-            { return first; }
-          };
-      };
-
-      ////////////////////////////////////////////////////////////////////////////
-      //
-      //  MultiTag Grammar
-      //
-      ////////////////////////////////////////////////////////////////////////////
-
-      struct MultiTag : public grammar<MultiTag, MTagVal>
-      {
-        template <typename ScannerT>
-          struct definition
-          {
-            definition( const MultiTag & self )
-            {
-              first =
-              (
-                line
-                    = stag                  [bind(&MTag::stag)(self.val)=arg1]
-                      >> *(anychar_p - eol_p)
-                      >> eol_p
-                      >> data               [bind(&MTag::data)(self.val)=construct_<Range>(arg1,arg2)]
-                      >> ( etag             [bind(&MTag::etag)(self.val)=arg1]
-                         | error_report_p( "Missing end tag" )
-                         )
-                      >> *(anychar_p - eol_p)
-                      >> (eol_p|end_p)
-                ,
-                stag
-                    = ( ch_p('+')
-                        >> ( (+alpha_p)     [bind(&Tag::ident)(stag.val)=construct_<std::string>(arg1,arg2)]
-                             >> !( '.'
-                                    >> (+alpha_p) [bind(&Tag::ext)(stag.val)=construct_<std::string>(arg1,arg2)]
-                                 )
-                           )                [self.expect=construct_<std::string>(arg1,arg2)]
-                        >> ':'
-                      )                     [bind(&Tag::range)(stag.val)=construct_<Range>(arg1,arg2)]
-                ,
-                data
-                    = while_p( ~eps_p(dataend) )
-                      [
-                        ( !( *blank_p >> +~space_p
-                              >> *( +blank_p >> +~space_p )
-                           )
-                        )                   [push_back(bind(&MTag::value)(self.val),construct_<std::string>(arg1,arg2))]
-                        >> *blank_p
-                        >> eol_p
-                      ]
-                ,
-                dataend
-                    = ( ch_p('-') | ch_p('+') )
-                      >> f_str_p(self.expect)
-                      >> ':'
-                ,
-                etag
-                    = ( ch_p('-')
-                        >> f_str_p(self.expect)
-                        >> ':'
-                      )                     [bind(&Tag::range)(etag.val)=construct_<Range>(arg1,arg2)]
-
-              );
-            }
-
-            subrule<0>        line;
-            subrule<1,TagVal> stag;
-            subrule<2>        data;
-            subrule<3>        dataend;
-            subrule<4,TagVal> etag;
-
-            rule<ScannerT> first;
-            const rule<ScannerT> & start() const
-            { return first; }
-          };
-      };
-
       /////////////////////////////////////////////////////////////////
     } // namespace tagfile
     ///////////////////////////////////////////////////////////////////