Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(148)

Side by Side Diff: chrome/tools/profile_reset/jtl_parser.cc

Issue 24998003: Compiler for the JSON Traversal Language. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments, added some unittests. Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 // Note: will fail in case the first line contains an unmatched double-quote
17 // outside of comments.
18 const char kSingleLineWithMaybeCommentsRE[] =
19 // Non-greedily match and capture sequences of 1.) string literals inside
20 // correctly matched double-quotes, or 2.) any other character.
21 "^((?:\"[^\"\\n]*\"|[^\"\\n])*?)"
22 // Greedily match and throw away the potential comment.
23 "(?://.*)?"
24 // Match and throw away EOL, or match end-of-string.
25 "(?:\n|$)";
26
27 // RegEx to match either a double-quote-enclosed string literal or a whitespace.
28 // Applied repeatedly and without overlapping, can be used to remove whitespace
29 // outside of string literals.
30 const char kRemoveWhitespaceRE[] = "(\"[^\"]*\")|\\s";
31
32 // The substitution pattern to use together with the above when replacing.
battre 2013/10/01 12:18:26 Please add: As white spaces are not captured, they
engedy 2013/10/01 15:09:33 Done.
33 const char kRemoveWhitespaceRewrite[] = "\\1";
34
35 // Separator to terminate a sentence.
36 const char kEndOfSentenceSeparator[] = ";";
37
38 // Separator to continue a sentence with another operation.
39 const char kContinueSentenceSeparator[] = "/";
40
41 // The 'true' Boolean keyword.
42 const char kTrueKeyword[] = "true";
43
44 // The 'false' Boolean keyword.
45 const char kFalseKeyword[] = "false";
46
47 // RegEx that matches and captures one argument, which is either a double-quote
48 // enclosed string, or a Boolean value. Will throw away a trailing comma.
49 const char kSingleArgumentRE[] = "(?:(?:\"([^\"]*)\"|(true|false))(?:,|$))";
50
51 // RegEx-es that, when concatenated, will match a single operation, and capture
52 // the: operation name, the optional arguments, and the separator that follows.
53 const char kOperationNameRE[] = "([[:word:]]+)";
54 const char kMaybeArgumentListRE[] =
55 "(?:\\(" // Opening parenthesis.
56 "((?:\"[^\"]*\"|[^\")])*)" // Capture: anything inside, quote-aware.
57 "\\))?"; // Closing parenthesis + everything optional.
58 const char kOperationSeparatorRE[] = "(;|/)";
59
60 } // namespace
61
62 struct JtlParser::ParsingState {
63 explicit ParsingState(const std::string& compacted_source)
64 : single_operation_regex(std::string(kOperationNameRE) +
65 kMaybeArgumentListRE +
66 kOperationSeparatorRE),
67 single_argument_regex(kSingleArgumentRE),
68 remaining_compacted_source(compacted_source),
69 last_line_number(0) {}
70
71 RE2 single_operation_regex;
72 RE2 single_argument_regex;
73 re2::StringPiece remaining_compacted_source;
74 re2::StringPiece last_context;
75 size_t last_line_number;
76 };
77
78 JtlParser::JtlParser(const std::string& compacted_source_code,
79 const std::vector<size_t>& newline_indices)
80 : compacted_source_(compacted_source_code),
81 newline_indices_(newline_indices) {
82 state_.reset(new ParsingState(compacted_source_code));
83 }
84
85 JtlParser::~JtlParser() {}
86
87 // static
88 bool JtlParser::RemoveCommentsAndAllWhitespace(
89 const std::string& verbose_text,
90 std::string* compacted_text,
91 std::vector<size_t>* newline_indices,
92 size_t* error_line_number) {
93 DCHECK(compacted_text);
94 DCHECK(newline_indices);
95 std::string line;
96 RE2 single_line_regex(kSingleLineWithMaybeCommentsRE);
97 RE2 remove_whitespace_regex(kRemoveWhitespaceRE);
98 re2::StringPiece verbose_text_piece(verbose_text);
99 compacted_text->clear();
100 newline_indices->clear();
101 while (!verbose_text_piece.empty()) {
102 if (!RE2::Consume(&verbose_text_piece, single_line_regex, &line)) {
103 if (error_line_number)
104 *error_line_number = newline_indices->size();
105 return false;
106 }
107 RE2::GlobalReplace(
108 &line, remove_whitespace_regex, kRemoveWhitespaceRewrite);
109 *compacted_text += line;
110 newline_indices->push_back(compacted_text->size());
111 }
112 return true;
113 }
114
115 bool JtlParser::HasFinished() {
116 return state_->remaining_compacted_source.empty();
117 }
118
119 bool JtlParser::ParseNextOperation(std::string* name,
120 base::ListValue* argument_list,
121 bool* ends_sentence) {
122 DCHECK(name);
123 DCHECK(argument_list);
124 DCHECK(ends_sentence);
125
126 state_->last_context = state_->remaining_compacted_source;
127 state_->last_line_number = GetOriginalLineNumber(
128 compacted_source_.size() - state_->remaining_compacted_source.length());
129
130 std::string arguments, separator;
131 if (!RE2::Consume(&state_->remaining_compacted_source,
132 state_->single_operation_regex,
133 name,
134 &arguments,
135 &separator))
136 return false;
137
138 *ends_sentence = (separator == kEndOfSentenceSeparator);
139 state_->last_context.remove_suffix(state_->remaining_compacted_source.size());
140
141 re2::StringPiece arguments_piece(arguments);
142 std::string string_value, boolean_value;
143 while (!arguments_piece.empty()) {
144 if (!RE2::Consume(&arguments_piece,
145 state_->single_argument_regex,
146 &string_value,
147 &boolean_value))
148 return false;
149
150 if (!boolean_value.empty())
battre 2013/10/01 12:18:26 Please add {} for multiline arguments.
engedy 2013/10/01 15:09:33 Done.
151 argument_list->Append(
152 new base::FundamentalValue(boolean_value == kTrueKeyword));
153 else // |string_value| might be empty for an empty string
154 argument_list->Append(new StringValue(string_value));
155 }
156 return true;
157 }
158
159 size_t JtlParser::GetOriginalLineNumber(size_t compacted_index) const {
160 return static_cast<size_t>(std::upper_bound(newline_indices_.begin(),
161 newline_indices_.end(),
162 compacted_index) -
163 newline_indices_.begin());
164 }
165
166 size_t JtlParser::last_line_number() const { return state_->last_line_number; }
167
168 std::string JtlParser::last_context() const {
169 return state_->last_context.ToString();
170 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698