Blame pcre_scanner.h

Packit 78a954
// Copyright (c) 2005, Google Inc.
Packit 78a954
// All rights reserved.
Packit 78a954
//
Packit 78a954
// Redistribution and use in source and binary forms, with or without
Packit 78a954
// modification, are permitted provided that the following conditions are
Packit 78a954
// met:
Packit 78a954
//
Packit 78a954
//     * Redistributions of source code must retain the above copyright
Packit 78a954
// notice, this list of conditions and the following disclaimer.
Packit 78a954
//     * Redistributions in binary form must reproduce the above
Packit 78a954
// copyright notice, this list of conditions and the following disclaimer
Packit 78a954
// in the documentation and/or other materials provided with the
Packit 78a954
// distribution.
Packit 78a954
//     * Neither the name of Google Inc. nor the names of its
Packit 78a954
// contributors may be used to endorse or promote products derived from
Packit 78a954
// this software without specific prior written permission.
Packit 78a954
//
Packit 78a954
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit 78a954
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit 78a954
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Packit 78a954
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
Packit 78a954
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
Packit 78a954
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Packit 78a954
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Packit 78a954
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Packit 78a954
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Packit 78a954
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit 78a954
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 78a954
//
Packit 78a954
// Author: Sanjay Ghemawat
Packit 78a954
//
Packit 78a954
// Regular-expression based scanner for parsing an input stream.
Packit 78a954
//
Packit 78a954
// Example 1: parse a sequence of "var = number" entries from input:
Packit 78a954
//
Packit 78a954
//      Scanner scanner(input);
Packit 78a954
//      string var;
Packit 78a954
//      int number;
Packit 78a954
//      scanner.SetSkipExpression("\\s+"); // Skip any white space we encounter
Packit 78a954
//      while (scanner.Consume("(\\w+) = (\\d+)", &var, &number)) {
Packit 78a954
//        ...;
Packit 78a954
//      }
Packit 78a954
Packit 78a954
#ifndef _PCRE_SCANNER_H
Packit 78a954
#define _PCRE_SCANNER_H
Packit 78a954
Packit 78a954
#include <assert.h>
Packit 78a954
#include <string>
Packit 78a954
#include <vector>
Packit 78a954
Packit 78a954
#include <pcrecpp.h>
Packit 78a954
#include <pcre_stringpiece.h>
Packit 78a954
Packit 78a954
namespace pcrecpp {
Packit 78a954
Packit 78a954
class PCRECPP_EXP_DEFN Scanner {
Packit 78a954
 public:
Packit 78a954
  Scanner();
Packit 78a954
  explicit Scanner(const std::string& input);
Packit 78a954
  ~Scanner();
Packit 78a954
Packit 78a954
  // Return current line number.  The returned line-number is
Packit 78a954
  // one-based.  I.e. it returns 1 + the number of consumed newlines.
Packit 78a954
  //
Packit 78a954
  // Note: this method may be slow.  It may take time proportional to
Packit 78a954
  // the size of the input.
Packit 78a954
  int LineNumber() const;
Packit 78a954
Packit 78a954
  // Return the byte-offset that the scanner is looking in the
Packit 78a954
  // input data;
Packit 78a954
  int Offset() const;
Packit 78a954
Packit 78a954
  // Return true iff the start of the remaining input matches "re"
Packit 78a954
  bool LookingAt(const RE& re) const;
Packit 78a954
Packit 78a954
  // Return true iff all of the following are true
Packit 78a954
  //    a. the start of the remaining input matches "re",
Packit 78a954
  //    b. if any arguments are supplied, matched sub-patterns can be
Packit 78a954
  //       parsed and stored into the arguments.
Packit 78a954
  // If it returns true, it skips over the matched input and any
Packit 78a954
  // following input that matches the "skip" regular expression.
Packit 78a954
  bool Consume(const RE& re,
Packit 78a954
               const Arg& arg0 = RE::no_arg,
Packit 78a954
               const Arg& arg1 = RE::no_arg,
Packit 78a954
               const Arg& arg2 = RE::no_arg
Packit 78a954
               // TODO: Allow more arguments?
Packit 78a954
               );
Packit 78a954
Packit 78a954
  // Set the "skip" regular expression.  If after consuming some data,
Packit 78a954
  // a prefix of the input matches this RE, it is automatically
Packit 78a954
  // skipped.  For example, a programming language scanner would use
Packit 78a954
  // a skip RE that matches white space and comments.
Packit 78a954
  //
Packit 78a954
  //    scanner.SetSkipExpression("\\s+|//.*|/[*](.|\n)*?[*]/");
Packit 78a954
  //
Packit 78a954
  // Skipping repeats as long as it succeeds.  We used to let people do
Packit 78a954
  // this by writing "(...)*" in the regular expression, but that added
Packit 78a954
  // up to lots of recursive calls within the pcre library, so now we
Packit 78a954
  // control repetition explicitly via the function call API.
Packit 78a954
  //
Packit 78a954
  // You can pass NULL for "re" if you do not want any data to be skipped.
Packit 78a954
  void Skip(const char* re);   // DEPRECATED; does *not* repeat
Packit 78a954
  void SetSkipExpression(const char* re);
Packit 78a954
Packit 78a954
  // Temporarily pause "skip"ing. This
Packit 78a954
  //   Skip("Foo"); code ; DisableSkip(); code; EnableSkip()
Packit 78a954
  // is similar to
Packit 78a954
  //   Skip("Foo"); code ; Skip(NULL); code ; Skip("Foo");
Packit 78a954
  // but avoids creating/deleting new RE objects.
Packit 78a954
  void DisableSkip();
Packit 78a954
Packit 78a954
  // Reenable previously paused skipping.  Any prefix of the input
Packit 78a954
  // that matches the skip pattern is immediately dropped.
Packit 78a954
  void EnableSkip();
Packit 78a954
Packit 78a954
  /***** Special wrappers around SetSkip() for some common idioms *****/
Packit 78a954
Packit 78a954
  // Arranges to skip whitespace, C comments, C++ comments.
Packit 78a954
  // The overall RE is a disjunction of the following REs:
Packit 78a954
  //    \\s                     whitespace
Packit 78a954
  //    //.*\n                  C++ comment
Packit 78a954
  //    /[*](.|\n)*?[*]/        C comment (x*? means minimal repetitions of x)
Packit 78a954
  // We get repetition via the semantics of SetSkipExpression, not by using *
Packit 78a954
  void SkipCXXComments() {
Packit 78a954
    SetSkipExpression("\\s|//.*\n|/[*](?:\n|.)*?[*]/");
Packit 78a954
  }
Packit 78a954
Packit 78a954
  void set_save_comments(bool comments) {
Packit 78a954
    save_comments_ = comments;
Packit 78a954
  }
Packit 78a954
Packit 78a954
  bool save_comments() {
Packit 78a954
    return save_comments_;
Packit 78a954
  }
Packit 78a954
Packit 78a954
  // Append to vector ranges the comments found in the
Packit 78a954
  // byte range [start,end] (inclusive) of the input data.
Packit 78a954
  // Only comments that were extracted entirely within that
Packit 78a954
  // range are returned: no range splitting of atomically-extracted
Packit 78a954
  // comments is performed.
Packit 78a954
  void GetComments(int start, int end, std::vector<StringPiece> *ranges);
Packit 78a954
Packit 78a954
  // Append to vector ranges the comments added
Packit 78a954
  // since the last time this was called. This
Packit 78a954
  // functionality is provided for efficiency when
Packit 78a954
  // interleaving scanning with parsing.
Packit 78a954
  void GetNextComments(std::vector<StringPiece> *ranges);
Packit 78a954
Packit 78a954
 private:
Packit 78a954
  std::string   data_;          // All the input data
Packit 78a954
  StringPiece   input_;         // Unprocessed input
Packit 78a954
  RE*           skip_;          // If non-NULL, RE for skipping input
Packit 78a954
  bool          should_skip_;   // If true, use skip_
Packit 78a954
  bool          skip_repeat_;   // If true, repeat skip_ as long as it works
Packit 78a954
  bool          save_comments_; // If true, aggregate the skip expression
Packit 78a954
Packit 78a954
  // the skipped comments
Packit 78a954
  // TODO: later consider requiring that the StringPieces be added
Packit 78a954
  // in order by their start position
Packit 78a954
  std::vector<StringPiece> *comments_;
Packit 78a954
Packit 78a954
  // the offset into comments_ that has been returned by GetNextComments
Packit 78a954
  int           comments_offset_;
Packit 78a954
Packit 78a954
  // helper function to consume *skip_ and honour
Packit 78a954
  // save_comments_
Packit 78a954
  void ConsumeSkip();
Packit 78a954
};
Packit 78a954
Packit 78a954
}   // namespace pcrecpp
Packit 78a954
Packit 78a954
#endif /* _PCRE_SCANNER_H */