144 lines
4.8 KiB
C++
144 lines
4.8 KiB
C++
// 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_
|