root/base/test/expectations/parser.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_TEST_EXPECTATIONS_PARSER_H_
#define BASE_TEST_EXPECTATIONS_PARSER_H_

#include <string>

#include "base/basictypes.h"
#include "base/strings/string_piece.h"
#include "base/test/expectations/expectation.h"

namespace test_expectations {

// This is the internal parser for test expectations. It parses an input
// string and reports information to its Delegate as it's processing the
// input.
//
// The input format is documented here:
// https://docs.google.com/a/chromium.org/document/d/1edhMJ5doY_dzfbKNCzeJJ-8XxPrexTbNL2Y_jVvLB8Q/view
//
// Basic format:
// "http://bug/1234 [ OS-Version ] Test.Name = Result"
//
// The parser is implemented as a state machine, with each state returning a
// function pointer to the next state.
class Parser {
 public:
  // The parser will call these methods on its delegate during a Parse()
  // operation.
  class Delegate {
   public:
    // When a well-formed and valid Expectation has been parsed from the input,
    // it is reported to the delegate via this method.
    virtual void EmitExpectation(const Expectation& expectation) = 0;

    // Called when the input string is not well-formed. Parsing will stop after
    // this method is called.
    virtual void OnSyntaxError(const std::string& message) = 0;

    // Called when an Expectation has been parsed because it is well-formed but
    // contains invalid data (i.e. the modifiers or result are not valid
    // keywords). This Expectation will not be reported via EmitExpectation.
    virtual void OnDataError(const std::string& message) = 0;
  };

  // Creates a new parser for |input| that will send data to |delegate|.
  Parser(Delegate* delegate, const std::string& input);
  ~Parser();

  // Runs the parser of the input string.
  void Parse();

 private:
  // This bit of hackery is used to implement a function pointer type that
  // returns a pointer to a function of the same signature. Since a definition
  // like that is inherently recursive, it's impossible to do:
  //     type StateFunc(*StateFunc)(StateData*);
  // However, this approach works without the need to use void*. Inspired by
  // <http://www.gotw.ca/gotw/057.htm>.
  struct StateFunc;
  typedef StateFunc(Parser::*StateFuncPtr)();
  struct StateFunc {
    StateFunc(StateFuncPtr pf) : pf_(pf) {}
    operator StateFuncPtr() {
      return pf_;
    }
    StateFuncPtr pf_;
  };

  // Tests whether there is at least one more character at pos_ before end_.
  bool HasNext();

  // The parser state functions. On entry, the parser state is at the beginning
  // of the token. Each returns a function pointer to the next state function,
  // or NULL to end parsing. On return, the parser is at the beginning of the
  // next token.
  StateFunc Start();
  StateFunc ParseComment();
  StateFunc ParseBugURL();
  StateFunc BeginModifiers();
  StateFunc InModifiers();
  StateFunc SaveModifier();
  StateFunc EndModifiers();
  StateFunc ParseTestName();
  StateFunc SaveTestName();
  StateFunc ParseExpectation();
  StateFunc ParseExpectationType();
  StateFunc SaveExpectationType();
  StateFunc End();

  // A state function that collects character data from the current position
  // to the next whitespace character. Returns the |success| function when at
  // the end of the string, with the data stored in |extracted_string_|.
  StateFunc ExtractString(StateFunc success);

  // Function that skips over horizontal whitespace characters and then returns
  // the |next| state.
  StateFunc SkipWhitespace(StateFunc next);

  // Does the same as SkipWhitespace but includes newlines.
  StateFunc SkipWhitespaceAndNewLines(StateFunc next);

  // State function that reports the given syntax error |message| to the
  // delegate and then returns NULL, ending the parse loop.
  StateFunc SyntaxError(const std::string& message);

  // Function that reports the data |error| to the delegate without stopping
  // parsing.
  void DataError(const std::string& error);

  // Parser delegate.
  Delegate* delegate_;

  // The input string.
  std::string input_;

  // Current location in the |input_|.
  const char* pos_;

  // Pointer to the end of the |input_|.
  const char* end_;

  // Current line number, as updated by SkipWhitespace().
  int line_number_;

  // The character data extracted from |input_| as a result of the
  // ExtractString() state.
  base::StringPiece extracted_string_;

  // The Expectation object that is currently being processed by the parser.
  // Reset in Start().
  Expectation current_;

  // If DataError() has been called during the course of parsing |current_|.
  // If true, then |current_| will not be emitted to the Delegate.
  bool data_error_;
};

}  // namespace test_expectations

#endif  // BASE_TEST_EXPECTATIONS_PARSER_H_

/* [<][>][^][v][top][bottom][index][help] */