| // 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_ |