// Copyright 2006-2007 The RE2 Authors.  All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Tested by search_test.cc.
//
// Prog::SearchNFA, an NFA search.
// This is an actual NFA like the theorists talk about,
// not the pseudo-NFA found in backtracking regexp implementations.
//
// IMPLEMENTATION
//
// This algorithm is a variant of one that appeared in Rob Pike's sam editor,
// which is a variant of the one described in Thompson's 1968 CACM paper.
// See http://swtch.com/~rsc/regexp/ for various history.  The main feature
// over the DFA implementation is that it tracks submatch boundaries.
//
// When the choice of submatch boundaries is ambiguous, this particular
// implementation makes the same choices that traditional backtracking
// implementations (in particular, Perl and PCRE) do.
// Note that unlike in Perl and PCRE, this algorithm *cannot* take exponential
// time in the length of the input.
//
// Like Thompson's original machine and like the DFA implementation, this
// implementation notices a match only once it is one byte past it.

#include "re2/prog.h"
#include "re2/regexp.h"
#include "util/sparse_array.h"
#include "util/sparse_set.h"

namespace re2 {

class NFA {
 public:
  NFA(Prog* prog);
  ~NFA();

  // Searches for a matching string.
  //   * If anchored is true, only considers matches starting at offset.
  //     Otherwise finds lefmost match at or after offset.
  //   * If longest is true, returns the longest match starting
  //     at the chosen start point.  Otherwise returns the so-called
  //     left-biased match, the one traditional backtracking engines
  //     (like Perl and PCRE) find.
  // Records submatch boundaries in submatch[1..nsubmatch-1].
  // Submatch[0] is the entire match.  When there is a choice in
  // which text matches each subexpression, the submatch boundaries
  // are chosen to match what a backtracking implementation would choose.
  bool Search(const StringPiece& text, const StringPiece& context,
              bool anchored, bool longest,
              StringPiece* submatch, int nsubmatch);

  static const int Debug = 0;

 private:
  struct Thread {
    union {
      int ref;
      Thread* next;  // when on free list
    };
    const char** capture;
  };

  // State for explicit stack in AddToThreadq.
  struct AddState {
    int id;     // Inst to process
    Thread* t;  // if not null, set t0 = t before processing id

    AddState()
        : id(0), t(NULL) {}
    explicit AddState(int id)
        : id(id), t(NULL) {}
    AddState(int id, Thread* t)
        : id(id), t(t) {}
  };

  // Threadq is a list of threads.  The list is sorted by the order
  // in which Perl would explore that particular state -- the earlier
  // choices appear earlier in the list.
  typedef SparseArray<Thread*> Threadq;

  inline Thread* AllocThread();
  inline Thread* Incref(Thread* t);
  inline void Decref(Thread* t);

  // Follows all empty arrows from id0 and enqueues all the states reached.
  // Enqueues only the ByteRange instructions that match byte c.
  // The bits in flag (Bol, Eol, etc.) specify whether ^, $ and \b match.
  // p is the current input position, and t0 is the current thread.
  void AddToThreadq(Threadq* q, int id0, int c, int flag,
                    const char* p, Thread* t0);

  // Run runq on byte c, appending new states to nextq.
  // Updates matched_ and match_ as new, better matches are found.
  // p is the position of the previous byte (the one before c)
  // in the input string, used when processing Match instructions.
  // flag is the bitwise OR of Bol, Eol, etc., specifying whether
  // ^, $ and \b match the current input position (after c).
  // Frees all the threads on runq.
  // If there is a shortcut to the end, returns that shortcut.
  inline int Step(Threadq* runq, Threadq* nextq, int c, int flag, const char* p);

  // Returns text version of capture information, for debugging.
  string FormatCapture(const char** capture);

  inline void CopyCapture(const char** dst, const char** src);

  Prog* prog_;          // underlying program
  int start_;           // start instruction in program
  int ncapture_;        // number of submatches to track
  bool longest_;        // whether searching for longest match
  bool endmatch_;       // whether match must end at text.end()
  const char* btext_;   // beginning of text being matched (for FormatSubmatch)
  const char* etext_;   // end of text being matched (for endmatch_)
  Threadq q0_, q1_;     // pre-allocated for Search.
  const char** match_;  // best match so far
  bool matched_;        // any match so far?
  AddState* astack_;    // pre-allocated for AddToThreadq
  int nastack_;

  Thread* free_threads_;  // free list

  DISALLOW_COPY_AND_ASSIGN(NFA);
};

NFA::NFA(Prog* prog) {
  prog_ = prog;
  start_ = prog_->start();
  ncapture_ = 0;
  longest_ = false;
  endmatch_ = false;
  btext_ = NULL;
  etext_ = NULL;
  q0_.resize(prog_->size());
  q1_.resize(prog_->size());
  // See NFA::AddToThreadq() for why this is so.
  nastack_ = 2*prog_->inst_count(kInstCapture) +
             prog_->inst_count(kInstEmptyWidth) +
             prog_->inst_count(kInstNop) + 1;  // + 1 for start inst
  astack_ = new AddState[nastack_];
  match_ = NULL;
  matched_ = false;
  free_threads_ = NULL;
}

NFA::~NFA() {
  delete[] match_;
  delete[] astack_;
  Thread* next;
  for (Thread* t = free_threads_; t; t = next) {
    next = t->next;
    delete[] t->capture;
    delete t;
  }
}

NFA::Thread* NFA::AllocThread() {
  Thread* t = free_threads_;
  if (t == NULL) {
    t = new Thread;
    t->ref = 1;
    t->capture = new const char*[ncapture_];
    return t;
  }
  free_threads_ = t->next;
  t->ref = 1;
  return t;
}

NFA::Thread* NFA::Incref(Thread* t) {
  DCHECK(t != NULL);
  t->ref++;
  return t;
}

void NFA::Decref(Thread* t) {
  if (t == NULL)
    return;
  t->ref--;
  if (t->ref > 0)
    return;
  DCHECK_EQ(t->ref, 0);
  t->next = free_threads_;
  free_threads_ = t;
}

void NFA::CopyCapture(const char** dst, const char** src) {
  for (int i = 0; i < ncapture_; i+=2) {
    dst[i] = src[i];
    dst[i+1] = src[i+1];
  }
}

// Follows all empty arrows from id0 and enqueues all the states reached.
// Enqueues only the ByteRange instructions that match byte c.
// The bits in flag (Bol, Eol, etc.) specify whether ^, $ and \b match.
// p is the current input position, and t0 is the current thread.
void NFA::AddToThreadq(Threadq* q, int id0, int c, int flag,
                       const char* p, Thread* t0) {
  if (id0 == 0)
    return;

  // Use astack_ to hold our stack of instructions yet to process.
  // It was preallocated as follows:
  //   two entries per Capture;
  //   one entry per EmptyWidth; and
  //   one entry per Nop.
  // This reflects the maximum number of stack pushes that each can
  // perform. (Each instruction can be processed at most once.)
  AddState* stk = astack_;
  int nstk = 0;

  stk[nstk++] = AddState(id0);
  while (nstk > 0) {
    DCHECK_LE(nstk, nastack_);
    AddState a = stk[--nstk];

  Loop:
    if (a.t != NULL) {
      // t0 was a thread that we allocated and copied in order to
      // record the capture, so we must now decref it.
      Decref(t0);
      t0 = a.t;
    }

    int id = a.id;
    if (id == 0)
      continue;
    if (q->has_index(id)) {
      if (Debug)
        fprintf(stderr, "  [%d%s]\n", id, FormatCapture(t0->capture).c_str());
      continue;
    }

    // Create entry in q no matter what.  We might fill it in below,
    // or we might not.  Even if not, it is necessary to have it,
    // so that we don't revisit id0 during the recursion.
    q->set_new(id, NULL);

    Thread** tp = &q->find(id)->second;
    int j;
    Thread* t;
    Prog::Inst* ip = prog_->inst(id);
    switch (ip->opcode()) {
    default:
      LOG(DFATAL) << "unhandled " << ip->opcode() << " in AddToThreadq";
      break;

    case kInstFail:
      break;

    case kInstAltMatch:
      // Save state; will pick up at next byte.
      t = Incref(t0);
      *tp = t;

      DCHECK(!ip->last());
      a = AddState(id+1);
      goto Loop;

    case kInstNop:
      if (!ip->last())
        stk[nstk++] = AddState(id+1);

      // Continue on.
      a = AddState(ip->out());
      goto Loop;

    case kInstCapture:
      if (!ip->last())
        stk[nstk++] = AddState(id+1);

      if ((j=ip->cap()) < ncapture_) {
        // Push a dummy whose only job is to restore t0
        // once we finish exploring this possibility.
        stk[nstk++] = AddState(0, t0);

        // Record capture.
        t = AllocThread();
        CopyCapture(t->capture, t0->capture);
        t->capture[j] = p;
        t0 = t;
      }
      a = AddState(ip->out());
      goto Loop;

    case kInstByteRange:
      if (!ip->Matches(c))
        goto Next;
      // Fallthrough intended.

    case kInstMatch:
      // Save state; will pick up at next byte.
      t = Incref(t0);
      *tp = t;
      if (Debug)
        fprintf(stderr, " + %d%s\n", id, FormatCapture(t0->capture).c_str());

    Next:
      if (ip->last())
        break;
      a = AddState(id+1);
      goto Loop;

    case kInstEmptyWidth:
      if (!ip->last())
        stk[nstk++] = AddState(id+1);

      // Continue on if we have all the right flag bits.
      if (ip->empty() & ~flag)
        break;
      a = AddState(ip->out());
      goto Loop;
    }
  }
}

// Run runq on byte c, appending new states to nextq.
// Updates matched_ and match_ as new, better matches are found.
// p is the position of the previous byte (the one before c)
// in the input string, used when processing Match instructions.
// flag is the bitwise OR of Bol, Eol, etc., specifying whether
// ^, $ and \b match the current input position (after c).
// Frees all the threads on runq.
// If there is a shortcut to the end, returns that shortcut.
int NFA::Step(Threadq* runq, Threadq* nextq, int c, int flag, const char* p) {
  nextq->clear();

  for (Threadq::iterator i = runq->begin(); i != runq->end(); ++i) {
    Thread* t = i->second;
    if (t == NULL)
      continue;

    if (longest_) {
      // Can skip any threads started after our current best match.
      if (matched_ && match_[0] < t->capture[0]) {
        Decref(t);
        continue;
      }
    }

    int id = i->index();
    Prog::Inst* ip = prog_->inst(id);

    switch (ip->opcode()) {
      default:
        // Should only see the values handled below.
        LOG(DFATAL) << "Unhandled " << ip->opcode() << " in step";
        break;

      case kInstByteRange:
        AddToThreadq(nextq, ip->out(), c, flag, p+1, t);
        break;

      case kInstAltMatch:
        if (i != runq->begin())
          break;
        // The match is ours if we want it.
        if (ip->greedy(prog_) || longest_) {
          CopyCapture(match_, t->capture);
          matched_ = true;

          Decref(t);
          for (++i; i != runq->end(); ++i)
            Decref(i->second);
          runq->clear();
          if (ip->greedy(prog_))
            return ip->out1();
          return ip->out();
        }
        break;

      case kInstMatch:
        if (endmatch_ && p != etext_)
          break;

        if (longest_) {
          // Leftmost-longest mode: save this match only if
          // it is either farther to the left or at the same
          // point but longer than an existing match.
          if (!matched_ || t->capture[0] < match_[0] ||
              (t->capture[0] == match_[0] && p > match_[1])) {
            CopyCapture(match_, t->capture);
            match_[1] = p;
            matched_ = true;
          }
        } else {
          // Leftmost-biased mode: this match is by definition
          // better than what we've already found (see next line).
          CopyCapture(match_, t->capture);
          match_[1] = p;
          matched_ = true;

          // Cut off the threads that can only find matches
          // worse than the one we just found: don't run the
          // rest of the current Threadq.
          Decref(t);
          for (++i; i != runq->end(); ++i)
            Decref(i->second);
          runq->clear();
          return 0;
        }
        break;
    }
    Decref(t);
  }
  runq->clear();
  return 0;
}

string NFA::FormatCapture(const char** capture) {
  string s;

  for (int i = 0; i < ncapture_; i+=2) {
    if (capture[i] == NULL)
      StringAppendF(&s, "(?,?)");
    else if (capture[i+1] == NULL)
      StringAppendF(&s, "(%d,?)", (int)(capture[i] - btext_));
    else
      StringAppendF(&s, "(%d,%d)",
                    (int)(capture[i] - btext_),
                    (int)(capture[i+1] - btext_));
  }
  return s;
}

// Returns whether haystack contains needle's memory.
static bool StringPieceContains(const StringPiece haystack, const StringPiece needle) {
  return haystack.begin() <= needle.begin() &&
         haystack.end() >= needle.end();
}

bool NFA::Search(const StringPiece& text, const StringPiece& const_context,
            bool anchored, bool longest,
            StringPiece* submatch, int nsubmatch) {
  if (start_ == 0)
    return false;

  StringPiece context = const_context;
  if (context.begin() == NULL)
    context = text;

  if (!StringPieceContains(context, text)) {
    LOG(FATAL) << "Bad args: context does not contain text "
                << reinterpret_cast<const void*>(context.begin())
                << "+" << context.size() << " "
                << reinterpret_cast<const void*>(text.begin())
                << "+" << text.size();
    return false;
  }

  if (prog_->anchor_start() && context.begin() != text.begin())
    return false;
  if (prog_->anchor_end() && context.end() != text.end())
    return false;
  anchored |= prog_->anchor_start();
  if (prog_->anchor_end()) {
    longest = true;
    endmatch_ = true;
    etext_ = text.end();
  }

  if (nsubmatch < 0) {
    LOG(DFATAL) << "Bad args: nsubmatch=" << nsubmatch;
    return false;
  }

  // Save search parameters.
  ncapture_ = 2*nsubmatch;
  longest_ = longest;

  if (nsubmatch == 0) {
    // We need to maintain match[0], both to distinguish the
    // longest match (if longest is true) and also to tell
    // whether we've seen any matches at all.
    ncapture_ = 2;
  }

  match_ = new const char*[ncapture_];
  matched_ = false;

  // For debugging prints.
  btext_ = context.begin();

  if (Debug) {
    fprintf(stderr, "NFA::Search %s (context: %s) anchored=%d longest=%d\n",
            text.as_string().c_str(), context.as_string().c_str(), anchored,
            longest);
  }

  // Set up search.
  Threadq* runq = &q0_;
  Threadq* nextq = &q1_;
  runq->clear();
  nextq->clear();
  memset(&match_[0], 0, ncapture_*sizeof match_[0]);
  int wasword = 0;

  if (text.begin() > context.begin())
    wasword = Prog::IsWordChar(text.begin()[-1] & 0xFF);

  // Loop over the text, stepping the machine.
  for (const char* p = text.begin();; p++) {
    // Check for empty-width specials.
    int flag = 0;

    // ^ and \A
    if (p == context.begin())
      flag |= kEmptyBeginText | kEmptyBeginLine;
    else if (p <= context.end() && p[-1] == '\n')
      flag |= kEmptyBeginLine;

    // $ and \z
    if (p == context.end())
      flag |= kEmptyEndText | kEmptyEndLine;
    else if (p < context.end() && p[0] == '\n')
      flag |= kEmptyEndLine;

    // \b and \B
    int isword = 0;
    if (p < context.end())
      isword = Prog::IsWordChar(p[0] & 0xFF);

    if (isword != wasword)
      flag |= kEmptyWordBoundary;
    else
      flag |= kEmptyNonWordBoundary;

    if (Debug) {
      int c = 0;
      if (p == context.begin())
        c = '^';
      else if (p > text.end())
        c = '$';
      else if (p < text.end())
        c = p[0] & 0xFF;

      fprintf(stderr, "%c[%#x/%d/%d]:", c, flag, isword, wasword);
      for (Threadq::iterator i = runq->begin(); i != runq->end(); ++i) {
        Thread* t = i->second;
        if (t == NULL)
          continue;
        fprintf(stderr, " %d%s", i->index(), FormatCapture(t->capture).c_str());
      }
      fprintf(stderr, "\n");
    }

    // Note that we pass p-1 to Step() because it needs the previous pointer
    // value in order to handle Match instructions appropriately. It plumbs
    // c and flag through to AddToThreadq() along with p-1+1, which is p.
    //
    // This is a no-op the first time around the loop because runq is empty.
    int id = Step(runq, nextq, p < text.end() ? p[0] & 0xFF : -1, flag, p-1);
    DCHECK_EQ(runq->size(), 0);
    swap(nextq, runq);
    nextq->clear();
    if (id != 0) {
      // We're done: full match ahead.
      p = text.end();
      for (;;) {
        Prog::Inst* ip = prog_->inst(id);
        switch (ip->opcode()) {
          default:
            LOG(DFATAL) << "Unexpected opcode in short circuit: " << ip->opcode();
            break;

          case kInstCapture:
            if (ip->cap() < ncapture_)
              match_[ip->cap()] = p;
            id = ip->out();
            continue;

          case kInstNop:
            id = ip->out();
            continue;

          case kInstMatch:
            match_[1] = p;
            matched_ = true;
            break;
        }
        break;
      }
      break;
    }

    if (p > text.end())
      break;

    // Start a new thread if there have not been any matches.
    // (No point in starting a new thread if there have been
    // matches, since it would be to the right of the match
    // we already found.)
    if (!matched_ && (!anchored || p == text.begin())) {
      // If there's a required first byte for an unanchored search
      // and we're not in the middle of any possible matches,
      // use memchr to search for the byte quickly.
      int fb = prog_->first_byte();
      if (!anchored && runq->size() == 0 &&
          fb >= 0 && p < text.end() && (p[0] & 0xFF) != fb) {
        p = reinterpret_cast<const char*>(memchr(p, fb, text.end() - p));
        if (p == NULL) {
          p = text.end();
          isword = 0;
        } else {
          isword = Prog::IsWordChar(p[0] & 0xFF);
        }
        flag = Prog::EmptyFlags(context, p);
      }

      Thread* t = AllocThread();
      CopyCapture(t->capture, match_);
      t->capture[0] = p;
      AddToThreadq(runq, start_, p < text.end() ? p[0] & 0xFF : -1, flag, p, t);
      Decref(t);
    }

    // If all the threads have died, stop early.
    if (runq->size() == 0) {
      if (Debug)
        fprintf(stderr, "dead\n");
      break;
    }

    wasword = isword;
  }

  for (Threadq::iterator i = runq->begin(); i != runq->end(); ++i)
    Decref(i->second);

  if (matched_) {
    for (int i = 0; i < nsubmatch; i++)
      submatch[i].set(match_[2*i],
                      static_cast<int>(match_[2*i+1] - match_[2*i]));
    if (Debug)
      fprintf(stderr, "match (%d,%d)\n",
              static_cast<int>(match_[0] - btext_),
              static_cast<int>(match_[1] - btext_));
    return true;
  }
  VLOG(1) << "No matches found";
  return false;
}

// Computes whether all successful matches have a common first byte,
// and if so, returns that byte.  If not, returns -1.
int Prog::ComputeFirstByte() {
  int b = -1;
  SparseSet q(size());
  q.insert(start());
  for (SparseSet::iterator it = q.begin(); it != q.end(); ++it) {
    int id = *it;
    Prog::Inst* ip = inst(id);
    switch (ip->opcode()) {
      default:
        LOG(DFATAL) << "unhandled " << ip->opcode() << " in ComputeFirstByte";
        break;

      case kInstMatch:
        // The empty string matches: no first byte.
        return -1;

      case kInstByteRange:
        if (!ip->last())
          q.insert(id+1);

        // Must match only a single byte
        if (ip->lo() != ip->hi())
          return -1;
        if (ip->foldcase() && 'a' <= ip->lo() && ip->lo() <= 'z')
          return -1;
        // If we haven't seen any bytes yet, record it;
        // otherwise must match the one we saw before.
        if (b == -1)
          b = ip->lo();
        else if (b != ip->lo())
          return -1;
        break;

      case kInstNop:
      case kInstCapture:
      case kInstEmptyWidth:
        if (!ip->last())
          q.insert(id+1);

        // Continue on.
        // Ignore ip->empty() flags for kInstEmptyWidth
        // in order to be as conservative as possible
        // (assume all possible empty-width flags are true).
        if (ip->out())
          q.insert(ip->out());
        break;

      case kInstAltMatch:
        DCHECK(!ip->last());
        q.insert(id+1);
        break;

      case kInstFail:
        break;
    }
  }
  return b;
}

bool
Prog::SearchNFA(const StringPiece& text, const StringPiece& context,
                Anchor anchor, MatchKind kind,
                StringPiece* match, int nmatch) {
  if (NFA::Debug)
    Dump();

  NFA nfa(this);
  StringPiece sp;
  if (kind == kFullMatch) {
    anchor = kAnchored;
    if (nmatch == 0) {
      match = &sp;
      nmatch = 1;
    }
  }
  if (!nfa.Search(text, context, anchor == kAnchored, kind != kFirstMatch, match, nmatch))
    return false;
  if (kind == kFullMatch && match[0].end() != text.end())
    return false;
  return true;
}

// For each instruction i in the program reachable from the start, compute the
// number of instructions reachable from i by following only empty transitions
// and record that count as fanout[i].
//
// fanout holds the results and is also the work queue for the outer iteration.
// reachable holds the reached nodes for the inner iteration.
void Prog::Fanout(SparseArray<int>* fanout) {
  DCHECK_EQ(fanout->max_size(), size());
  SparseSet reachable(size());
  fanout->clear();
  fanout->set_new(start(), 0);
  for (SparseArray<int>::iterator i = fanout->begin(); i != fanout->end(); ++i) {
    int* count = &i->second;
    reachable.clear();
    reachable.insert(i->index());
    for (SparseSet::iterator j = reachable.begin(); j != reachable.end(); ++j) {
      int id = *j;
      Prog::Inst* ip = inst(id);
      switch (ip->opcode()) {
        default:
          LOG(DFATAL) << "unhandled " << ip->opcode() << " in Prog::Fanout()";
          break;

        case kInstByteRange:
          if (!ip->last())
            reachable.insert(id+1);

          (*count)++;
          if (!fanout->has_index(ip->out())) {
            fanout->set_new(ip->out(), 0);
          }
          break;

        case kInstAltMatch:
          DCHECK(!ip->last());
          reachable.insert(id+1);
          break;

        case kInstCapture:
        case kInstEmptyWidth:
        case kInstNop:
          if (!ip->last())
            reachable.insert(id+1);

          reachable.insert(ip->out());
          break;

        case kInstMatch:
          if (!ip->last())
            reachable.insert(id+1);
          break;

        case kInstFail:
          break;
      }
    }
  }
}

}  // namespace re2
