Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 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 #include "chrome/tools/profile_reset/jtl_parser.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "base/strings/string_util.h" | |
| 9 #include "base/values.h" | |
| 10 #include "third_party/re2/re2/re2.h" | |
| 11 | |
| 12 namespace { | |
| 13 | |
| 14 // RegEx that matches the first line of a text. Will throw away any potential | |
| 15 // double-slash introduced comments and the potential trailing EOL character. | |
| 16 // Gracefully handles slashes inside quotes, and even mismatched quotes. See | |
| 17 // unit tests for details. | |
| 18 const char kSingleLineWithMaybeCommentsRE[] = | |
| 19 "((?:\"[^\"]*\"|.)*?)(?://.*)?(?:\n|$)"; | |
|
battre
2013/09/27 15:00:01
How about splitting this into something like
"
engedy
2013/10/01 10:48:10
Done.
| |
| 20 | |
| 21 // Separator to terminate a sentence. | |
| 22 const char kEndOfSentenceSeparator[] = ";"; | |
| 23 | |
| 24 // Separator to continue a sentence with another operation. | |
| 25 const char kContinueSentenceSeparator[] = "/"; | |
| 26 | |
| 27 // The 'true' Boolean keyword. | |
| 28 const char kTrueKeyword[] = "true"; | |
| 29 | |
| 30 // The 'false' Boolean keyword. | |
| 31 const char kFalseKeyword[] = "false"; | |
| 32 | |
| 33 // RegEx that matches and captures one argument, which is either a double-quote | |
| 34 // enclosed string, or a Boolean value. Will throw away a trailing comma. | |
| 35 const char kSingleArgumentRE[] = "(?:(?:(?:\"([^\"]*)\")|(true|false))(?:,|$))"; | |
| 36 | |
| 37 // RegEx-es that, when concatenated, will match a single operation, and capture | |
| 38 // the: operation name, the optional arguments, and the separator that follows. | |
| 39 const char kOperationNameRE[] = "([[:word:]]+)"; | |
| 40 const char kMaybeArgumentListRE[] = "(?:\\(((?:\"[^\"]*\"|[^\")])*)\\))?"; | |
| 41 const char kOperationSeparatorRE[] = "(;|/)"; | |
| 42 | |
| 43 } // namespace | |
| 44 | |
| 45 struct JtlParser::ParsingState { | |
| 46 explicit ParsingState(const std::string& compacted_source) | |
| 47 : single_operation_regex(std::string(kOperationNameRE) + | |
| 48 kMaybeArgumentListRE + | |
| 49 kOperationSeparatorRE), | |
| 50 single_argument_regex(kSingleArgumentRE), | |
| 51 remaining_compacted_source(compacted_source), | |
| 52 last_line_number(0) {} | |
| 53 | |
| 54 RE2 single_operation_regex; | |
| 55 RE2 single_argument_regex; | |
| 56 re2::StringPiece remaining_compacted_source; | |
| 57 re2::StringPiece last_context; | |
| 58 size_t last_line_number; | |
| 59 }; | |
| 60 | |
| 61 JtlParser::JtlParser(const std::string& compacted_source, | |
| 62 const std::vector<size_t>& newline_indices) | |
| 63 : compacted_source_(compacted_source), | |
| 64 newline_indices_(newline_indices), | |
| 65 state_(new ParsingState(compacted_source)) {} | |
| 66 | |
| 67 JtlParser::~JtlParser() {} | |
| 68 | |
| 69 JtlParser* JtlParser::Create(const std::string& source_code) { | |
| 70 std::string compacted_source; | |
| 71 std::vector<size_t> newline_indices; | |
| 72 RemoveCommentsAndAllWhitespace( | |
| 73 source_code, &compacted_source, &newline_indices); | |
| 74 return new JtlParser(compacted_source, newline_indices); | |
| 75 } | |
| 76 | |
| 77 void JtlParser::RemoveCommentsAndAllWhitespace( | |
| 78 const std::string& verbose_text, | |
| 79 std::string* compacted_text, | |
| 80 std::vector<size_t>* newline_indices) { | |
| 81 DCHECK(compacted_text); | |
| 82 DCHECK(newline_indices); | |
| 83 std::string line_without_comments; | |
| 84 RE2 single_line_regex(kSingleLineWithMaybeCommentsRE); | |
| 85 re2::StringPiece verbose_text_piece(verbose_text); | |
| 86 while (!verbose_text_piece.empty() && | |
| 87 RE2::Consume( | |
| 88 &verbose_text_piece, single_line_regex, &line_without_comments)) { | |
| 89 std::string compacted_line; | |
| 90 RemoveChars(line_without_comments, kWhitespaceASCII, &compacted_line); | |
| 91 *compacted_text += compacted_line; | |
| 92 newline_indices->push_back(compacted_text->size()); | |
| 93 } | |
| 94 DCHECK(verbose_text_piece.empty()); | |
| 95 } | |
| 96 | |
| 97 bool JtlParser::HasNextOperation() { | |
| 98 return !state_->remaining_compacted_source.empty(); | |
| 99 } | |
| 100 | |
| 101 bool JtlParser::ParseNextOperation(std::string* name, | |
| 102 base::ListValue* argument_list, | |
| 103 bool* ends_sentence) { | |
| 104 DCHECK(name); | |
| 105 DCHECK(argument_list); | |
| 106 DCHECK(ends_sentence); | |
| 107 | |
| 108 state_->last_context = state_->remaining_compacted_source; | |
| 109 state_->last_line_number = GetOriginalLineNumber( | |
| 110 compacted_source_.size() - state_->remaining_compacted_source.length()); | |
| 111 | |
| 112 std::string arguments, separator; | |
| 113 if (!RE2::Consume(&state_->remaining_compacted_source, | |
| 114 state_->single_operation_regex, | |
| 115 name, | |
| 116 &arguments, | |
| 117 &separator)) | |
| 118 return false; | |
| 119 | |
| 120 *ends_sentence = (separator == kEndOfSentenceSeparator); | |
| 121 state_->last_context.remove_suffix(state_->remaining_compacted_source.size()); | |
| 122 | |
| 123 re2::StringPiece arguments_piece(arguments); | |
| 124 std::string string_value, boolean_value; | |
| 125 while (!arguments_piece.empty()) { | |
| 126 if (!RE2::Consume(&arguments_piece, | |
| 127 state_->single_argument_regex, | |
| 128 &string_value, | |
| 129 &boolean_value)) | |
| 130 return false; | |
| 131 | |
| 132 if (!boolean_value.empty()) | |
| 133 argument_list->Append( | |
| 134 new base::FundamentalValue(boolean_value == kTrueKeyword)); | |
| 135 else // |string_value| might be empty for an empty string | |
| 136 argument_list->Append(new StringValue(string_value)); | |
| 137 } | |
| 138 return true; | |
| 139 } | |
| 140 | |
| 141 size_t JtlParser::GetOriginalLineNumber(size_t compacted_index) const { | |
| 142 return static_cast<size_t>(std::upper_bound(newline_indices_.begin(), | |
| 143 newline_indices_.end(), | |
| 144 compacted_index) - | |
| 145 newline_indices_.begin()); | |
| 146 } | |
| 147 | |
| 148 size_t JtlParser::last_line_number() const { return state_->last_line_number; } | |
| 149 | |
| 150 std::string JtlParser::last_context() const { | |
| 151 return state_->last_context.ToString(); | |
| 152 } | |
| OLD | NEW |