Home | History | Annotate | Download | only in expectations
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef BASE_TEST_EXPECTATIONS_PARSER_H_
      6 #define BASE_TEST_EXPECTATIONS_PARSER_H_
      7 
      8 #include <string>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/strings/string_piece.h"
     12 #include "base/test/expectations/expectation.h"
     13 
     14 namespace test_expectations {
     15 
     16 // This is the internal parser for test expectations. It parses an input
     17 // string and reports information to its Delegate as it's processing the
     18 // input.
     19 //
     20 // The input format is documented here:
     21 // https://docs.google.com/a/chromium.org/document/d/1edhMJ5doY_dzfbKNCzeJJ-8XxPrexTbNL2Y_jVvLB8Q/view
     22 //
     23 // Basic format:
     24 // "http://bug/1234 [ OS-Version ] Test.Name = Result"
     25 //
     26 // The parser is implemented as a state machine, with each state returning a
     27 // function pointer to the next state.
     28 class Parser {
     29  public:
     30   // The parser will call these methods on its delegate during a Parse()
     31   // operation.
     32   class Delegate {
     33    public:
     34     // When a well-formed and valid Expectation has been parsed from the input,
     35     // it is reported to the delegate via this method.
     36     virtual void EmitExpectation(const Expectation& expectation) = 0;
     37 
     38     // Called when the input string is not well-formed. Parsing will stop after
     39     // this method is called.
     40     virtual void OnSyntaxError(const std::string& message) = 0;
     41 
     42     // Called when an Expectation has been parsed because it is well-formed but
     43     // contains invalid data (i.e. the modifiers or result are not valid
     44     // keywords). This Expectation will not be reported via EmitExpectation.
     45     virtual void OnDataError(const std::string& message) = 0;
     46   };
     47 
     48   // Creates a new parser for |input| that will send data to |delegate|.
     49   Parser(Delegate* delegate, const std::string& input);
     50   ~Parser();
     51 
     52   // Runs the parser of the input string.
     53   void Parse();
     54 
     55  private:
     56   // This bit of hackery is used to implement a function pointer type that
     57   // returns a pointer to a function of the same signature. Since a definition
     58   // like that is inherently recursive, it's impossible to do:
     59   //     type StateFunc(*StateFunc)(StateData*);
     60   // However, this approach works without the need to use void*. Inspired by
     61   // <http://www.gotw.ca/gotw/057.htm>.
     62   struct StateFunc;
     63   typedef StateFunc(Parser::*StateFuncPtr)();
     64   struct StateFunc {
     65     StateFunc(StateFuncPtr pf) : pf_(pf) {}
     66     operator StateFuncPtr() {
     67       return pf_;
     68     }
     69     StateFuncPtr pf_;
     70   };
     71 
     72   // Tests whether there is at least one more character at pos_ before end_.
     73   bool HasNext();
     74 
     75   // The parser state functions. On entry, the parser state is at the beginning
     76   // of the token. Each returns a function pointer to the next state function,
     77   // or NULL to end parsing. On return, the parser is at the beginning of the
     78   // next token.
     79   StateFunc Start();
     80   StateFunc ParseComment();
     81   StateFunc ParseBugURL();
     82   StateFunc BeginModifiers();
     83   StateFunc InModifiers();
     84   StateFunc SaveModifier();
     85   StateFunc EndModifiers();
     86   StateFunc ParseTestName();
     87   StateFunc SaveTestName();
     88   StateFunc ParseExpectation();
     89   StateFunc ParseExpectationType();
     90   StateFunc SaveExpectationType();
     91   StateFunc End();
     92 
     93   // A state function that collects character data from the current position
     94   // to the next whitespace character. Returns the |success| function when at
     95   // the end of the string, with the data stored in |extracted_string_|.
     96   StateFunc ExtractString(StateFunc success);
     97 
     98   // Function that skips over horizontal whitespace characters and then returns
     99   // the |next| state.
    100   StateFunc SkipWhitespace(StateFunc next);
    101 
    102   // Does the same as SkipWhitespace but includes newlines.
    103   StateFunc SkipWhitespaceAndNewLines(StateFunc next);
    104 
    105   // State function that reports the given syntax error |message| to the
    106   // delegate and then returns NULL, ending the parse loop.
    107   StateFunc SyntaxError(const std::string& message);
    108 
    109   // Function that reports the data |error| to the delegate without stopping
    110   // parsing.
    111   void DataError(const std::string& error);
    112 
    113   // Parser delegate.
    114   Delegate* delegate_;
    115 
    116   // The input string.
    117   std::string input_;
    118 
    119   // Current location in the |input_|.
    120   const char* pos_;
    121 
    122   // Pointer to the end of the |input_|.
    123   const char* end_;
    124 
    125   // Current line number, as updated by SkipWhitespace().
    126   int line_number_;
    127 
    128   // The character data extracted from |input_| as a result of the
    129   // ExtractString() state.
    130   base::StringPiece extracted_string_;
    131 
    132   // The Expectation object that is currently being processed by the parser.
    133   // Reset in Start().
    134   Expectation current_;
    135 
    136   // If DataError() has been called during the course of parsing |current_|.
    137   // If true, then |current_| will not be emitted to the Delegate.
    138   bool data_error_;
    139 };
    140 
    141 }  // namespace test_expectations
    142 
    143 #endif  // BASE_TEST_EXPECTATIONS_PARSER_H_
    144