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

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

Issue 24998003: Compiler for the JSON Traversal Language. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed linker errors on Win. 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
« no previous file with comments | « chrome/tools/profile_reset/jtl_compiler.h ('k') | chrome/tools/profile_reset/jtl_compiler.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_compiler.h"
6
7 #include <map>
8
9 #include "base/logging.h"
10 #include "chrome/browser/profile_resetter/jtl_foundation.h"
11 #include "chrome/tools/profile_reset/jtl_parser.h"
12
13 namespace jtl = jtl_foundation;
14
15 namespace {
16
17 // Serializes symbols into byte-code in a streaming manner.
18 class ByteCodeWriter {
19 public:
20 explicit ByteCodeWriter(std::string* output) : output_(output) {}
21 ~ByteCodeWriter() {}
22
23 void WriteUint8(uint8 value) { output_->push_back(static_cast<char>(value)); }
24 void WriteOpCode(uint8 op_code) { WriteUint8(op_code); }
25 void WriteHash(const std::string& hash) {
26 CHECK_EQ(hash.size(), jtl::kHashSizeInBytes);
27 *output_ += hash;
28 }
29 void WriteBool(bool value) { WriteUint8(value ? 1u : 0u); }
30
31 private:
32 std::string* output_;
33
34 DISALLOW_COPY_AND_ASSIGN(ByteCodeWriter);
35 };
36
37 // Encapsulates meta-data about all instructions, and is capable of transcoding
38 // each instruction from a parsed text-based format to byte-code.
39 class InstructionSet {
40 public:
41 InstructionSet() {
42 // Define each instruction in this list.
43 Add(Instruction("node", jtl::NAVIGATE, Arguments(Hash)));
44 Add(Instruction("any", jtl::NAVIGATE_ANY, Arguments()));
45 Add(Instruction("back", jtl::NAVIGATE_BACK, Arguments()));
46 Add(Instruction("store_bool", jtl::STORE_BOOL, Arguments(Hash, Bool)));
47 Add(Instruction("compare_stored_bool",
48 jtl::COMPARE_STORED_BOOL,
49 Arguments(Hash, Bool, Bool)));
50 Add(Instruction("store_hash", jtl::STORE_HASH, Arguments(Hash, Hash)));
51 Add(Instruction("compare_stored_hash",
52 jtl::COMPARE_STORED_HASH,
53 Arguments(Hash, Hash, Hash)));
54 Add(Instruction("compare_bool", jtl::COMPARE_NODE_BOOL, Arguments(Bool)));
55 Add(Instruction("compare_hash", jtl::COMPARE_NODE_HASH, Arguments(Hash)));
56 Add(Instruction("break", jtl::STOP_EXECUTING_SENTENCE, Arguments()));
57 }
58
59 JtlCompiler::CompileError::ErrorCode TranscodeInstruction(
60 const std::string& name,
61 const ListValue& arguments,
62 bool ends_sentence,
63 const jtl::Hasher& hasher,
64 ByteCodeWriter* target) const {
65 if (instruction_map_.count(name) == 0)
66 return JtlCompiler::CompileError::INVALID_OPERATION_NAME;
67 const Instruction& instruction(instruction_map_.at(name));
68 if (instruction.argument_types.size() != arguments.GetSize())
69 return JtlCompiler::CompileError::INVALID_ARGUMENT_COUNT;
70 target->WriteOpCode(instruction.op_code);
71 for (size_t i = 0; i < arguments.GetSize(); ++i) {
72 switch (instruction.argument_types[i]) {
73 case Bool: {
74 bool value = false;
75 if (!arguments.GetBoolean(i, &value))
76 return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE;
77 target->WriteBool(value);
78 break;
79 }
80 case Hash: {
81 std::string value;
82 if (!arguments.GetString(i, &value))
83 return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE;
84 target->WriteHash(hasher.GetHash(value));
85 break;
86 }
87 default:
88 NOTREACHED();
89 return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE;
90 }
91 }
92 if (ends_sentence)
93 target->WriteOpCode(jtl::END_OF_SENTENCE);
94 return JtlCompiler::CompileError::ERROR_NONE;
95 }
96
97 private:
98 // The possible types of an operation's argument.
99 enum ArgumentType {
100 None,
101 Bool,
102 Hash
103 };
104
105 // Encapsulates meta-data about one instruction.
106 struct Instruction {
107 Instruction() : op_code(jtl::END_OF_SENTENCE) {}
108 Instruction(const char* name,
109 jtl_foundation::OpCodes op_code,
110 const std::vector<ArgumentType>& argument_types)
111 : name(name), op_code(op_code), argument_types(argument_types) {}
112
113 std::string name;
114 jtl::OpCodes op_code;
115 std::vector<ArgumentType> argument_types;
116 };
117
118 static std::vector<ArgumentType> Arguments(ArgumentType arg1_type = None,
119 ArgumentType arg2_type = None,
120 ArgumentType arg3_type = None) {
121 std::vector<ArgumentType> result;
122 if (arg1_type != None)
123 result.push_back(arg1_type);
124 if (arg2_type != None)
125 result.push_back(arg2_type);
126 if (arg3_type != None)
127 result.push_back(arg3_type);
128 return result;
129 }
130
131 void Add(const Instruction& instruction) {
132 instruction_map_[instruction.name] = instruction;
133 }
134
135 std::map<std::string, Instruction> instruction_map_;
136
137 DISALLOW_COPY_AND_ASSIGN(InstructionSet);
138 };
139
140 } // namespace
141
142 bool JtlCompiler::Compile(const std::string& source_code,
143 const std::string& hash_seed,
144 std::string* output_bytecode,
145 CompileError* error_details) {
146 DCHECK(output_bytecode);
147 InstructionSet instruction_set;
148 ByteCodeWriter bytecode_writer(output_bytecode);
149 jtl::Hasher hasher(hash_seed);
150
151 std::string compacted_source_code;
152 std::vector<size_t> newline_indices;
153 size_t mismatched_quotes_line;
154 if (!JtlParser::RemoveCommentsAndAllWhitespace(source_code,
155 &compacted_source_code,
156 &newline_indices,
157 &mismatched_quotes_line)) {
158 if (error_details) {
159 error_details->context = ""; // No meaningful intra-line context here.
160 error_details->line_number = mismatched_quotes_line;
161 error_details->error_code = CompileError::MISMATCHED_DOUBLE_QUOTES;
162 }
163 return false;
164 }
165
166 JtlParser parser(compacted_source_code, newline_indices);
167 while (!parser.HasFinished()) {
168 std::string operation_name;
169 ListValue arguments;
170 bool ends_sentence = false;
171 if (!parser.ParseNextOperation(
172 &operation_name, &arguments, &ends_sentence)) {
173 if (error_details) {
174 error_details->context = parser.GetLastContext();
175 error_details->line_number = parser.GetLastLineNumber();
176 error_details->error_code = CompileError::PARSING_ERROR;
177 }
178 return false;
179 }
180 CompileError::ErrorCode error_code = instruction_set.TranscodeInstruction(
181 operation_name, arguments, ends_sentence, hasher, &bytecode_writer);
182 if (error_code != CompileError::ERROR_NONE) {
183 if (error_details) {
184 error_details->context = parser.GetLastContext();
185 error_details->line_number = parser.GetLastLineNumber();
186 error_details->error_code = error_code;
187 }
188 return false;
189 }
190 }
191
192 return true;
193 }
OLDNEW
« no previous file with comments | « chrome/tools/profile_reset/jtl_compiler.h ('k') | chrome/tools/profile_reset/jtl_compiler.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698