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

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: 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_compiler.h"
6
7 #include <algorithm>
8 #include <map>
9 #include <string>
10
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/strings/string_util.h"
14 #include "chrome/browser/profile_resetter/jtl_foundation.h"
15 #include "chrome/tools/profile_reset/jtl_parser.h"
16
17 namespace jtl = jtl_foundation;
18
19 namespace {
20
21 // Serializes symbols into byte-code in a streaming manner.
22 class ByteCodeWriter {
23 public:
24 explicit ByteCodeWriter(std::string* output) : output_(output) {}
25 ~ByteCodeWriter() {}
26
27 void WriteUint8(uint8 value) { output_->push_back(static_cast<char>(value)); }
28 void WriteOpCode(uint8 op_code) { WriteUint8(op_code); }
29 void WriteHash(const std::string& hash) {
30 CHECK(hash.size() == jtl::kHashSizeInBytes);
31 *output_ += hash;
32 }
33 void WriteBool(bool value) { WriteUint8(value ? 1u : 0u); }
34
35 private:
36 std::string* output_;
37
38 DISALLOW_COPY_AND_ASSIGN(ByteCodeWriter);
39 };
40
41 // Encapsulates meta-data about all instructions, and is capable of transcoding
42 // each instruction from a parsed text-based format to byte-code.
43 class InstructionSet {
44 public:
45 InstructionSet() {
46 // Define new instructions in this list.
47 Add(Instruction("node", jtl::NAVIGATE, Arguments(Hash)));
48 Add(Instruction("any", jtl::NAVIGATE_ANY, Arguments()));
49 Add(Instruction("back", jtl::NAVIGATE_BACK, Arguments()));
50 Add(Instruction("store_bool", jtl::STORE_BOOL, Arguments(Hash, Bool)));
51 Add(Instruction("compare_stored_bool",
52 jtl::COMPARE_STORED_BOOL,
53 Arguments(Hash, Bool, Bool)));
54 Add(Instruction("store_hash", jtl::STORE_HASH, Arguments(Hash, Hash)));
55 Add(Instruction("compare_stored_hash",
56 jtl::COMPARE_STORED_HASH,
57 Arguments(Hash, Hash, Hash)));
58 Add(Instruction("compare_bool", jtl::COMPARE_NODE_BOOL, Arguments(Bool)));
59 Add(Instruction("compare_hash", jtl::COMPARE_NODE_HASH, Arguments(Hash)));
60 Add(Instruction("break", jtl::STOP_EXECUTING_SENTENCE, Arguments()));
61 }
62
63 bool TranscodeInstruction(const std::string& name,
64 const ListValue& arguments,
65 bool end_of_sentence,
66 const jtl::Hasher& hasher,
67 ByteCodeWriter* target) const {
68 if (instruction_map_.count(name) == 0)
69 return false;
70 const Instruction& instruction(instruction_map_.at(name));
71 if (instruction.argument_types.size() != arguments.GetSize())
72 return false;
73 target->WriteOpCode(instruction.op_code);
74 for (size_t i = 0; i < arguments.GetSize(); ++i) {
75 switch (instruction.argument_types[i]) {
76 case Bool: {
77 bool value;
78 if (!arguments.GetBoolean(i, &value))
79 return false;
80 target->WriteBool(value);
81 break;
82 }
83 case Hash: {
84 std::string value;
85 if (!arguments.GetString(i, &value))
86 return false;
87 target->WriteHash(hasher.GetHash(value));
88 break;
89 }
90 default:
91 NOTREACHED();
92 return false;
93 }
94 }
95 if (end_of_sentence)
96 target->WriteOpCode(jtl::END_OF_SENTENCE);
97 return true;
98 }
99
100 private:
101 // The possible types of an operation's argument.
102 enum ArgumentType {
103 None,
104 Bool,
105 Hash
106 };
107
108 // Encapsulates meta-data about one instruction.
109 struct Instruction {
110 Instruction() : op_code(jtl::END_OF_SENTENCE) {}
111 Instruction(const char* name,
112 jtl_foundation::OpCodes op_code,
113 const std::vector<ArgumentType>& argument_types)
114 : name(name), op_code(op_code), argument_types(argument_types) {}
115
116 std::string name;
117 jtl::OpCodes op_code;
118 std::vector<ArgumentType> argument_types;
119 };
120
121 static std::vector<ArgumentType> Arguments(ArgumentType arg1_type = None,
122 ArgumentType arg2_type = None,
123 ArgumentType arg3_type = None) {
124 std::vector<ArgumentType> result;
125 if (arg1_type != None)
126 result.push_back(arg1_type);
127 if (arg2_type != None)
128 result.push_back(arg2_type);
129 if (arg3_type != None)
130 result.push_back(arg3_type);
131 return result;
132 }
133
134 void Add(const Instruction& instruction) {
135 instruction_map_[instruction.name] = instruction;
136 }
137
138 std::map<std::string, Instruction> instruction_map_;
139
140 DISALLOW_COPY_AND_ASSIGN(InstructionSet);
141 };
142
143 } // namespace
144
145 bool JtlCompiler::Compile(const std::string& source_code,
146 const std::string& hash_seed,
147 std::string* output_bytecode,
148 CompileError* error_details) {
149 DCHECK(output_bytecode);
150 InstructionSet instruction_set;
151 ByteCodeWriter bytecode_writer(output_bytecode);
152 jtl::Hasher hasher(hash_seed);
153 scoped_ptr<JtlParser> parser(JtlParser::Create(source_code));
154 while (parser->HasNextOperation()) {
155 std::string operation_name;
156 ListValue arguments;
157 bool end_of_sentence;
battre 2013/09/27 15:00:01 nit: initialize to false
engedy 2013/10/01 10:48:10 Done.
158 if (!parser->ParseNextOperation(
159 &operation_name, &arguments, &end_of_sentence)) {
160 if (error_details) {
161 error_details->context = parser->last_context();
162 error_details->line_number = parser->last_line_number();
163 error_details->error_code = CompileError::PARSING_ERROR;
164 }
165 return false;
166 }
167 if (!instruction_set.TranscodeInstruction(operation_name,
168 arguments,
169 end_of_sentence,
170 hasher,
171 &bytecode_writer)) {
172 if (error_details) {
173 error_details->context = parser->last_context();
174 error_details->line_number = parser->last_line_number();
175 error_details->error_code = CompileError::UNKNOWN_OPERATION;
176 }
177 return false;
178 }
179 }
180
181 return true;
182 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698