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

Unified 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, 3 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 side-by-side diff with in-line comments
Download patch
Index: chrome/tools/profile_reset/jtl_compiler.cc
diff --git a/chrome/tools/profile_reset/jtl_compiler.cc b/chrome/tools/profile_reset/jtl_compiler.cc
new file mode 100644
index 0000000000000000000000000000000000000000..5f6e624d88410bd7ce822e4a0e822d2017cae502
--- /dev/null
+++ b/chrome/tools/profile_reset/jtl_compiler.cc
@@ -0,0 +1,182 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/tools/profile_reset/jtl_compiler.h"
+
+#include <algorithm>
+#include <map>
+#include <string>
+
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string_util.h"
+#include "chrome/browser/profile_resetter/jtl_foundation.h"
+#include "chrome/tools/profile_reset/jtl_parser.h"
+
+namespace jtl = jtl_foundation;
+
+namespace {
+
+// Serializes symbols into byte-code in a streaming manner.
+class ByteCodeWriter {
+ public:
+ explicit ByteCodeWriter(std::string* output) : output_(output) {}
+ ~ByteCodeWriter() {}
+
+ void WriteUint8(uint8 value) { output_->push_back(static_cast<char>(value)); }
+ void WriteOpCode(uint8 op_code) { WriteUint8(op_code); }
+ void WriteHash(const std::string& hash) {
+ CHECK(hash.size() == jtl::kHashSizeInBytes);
+ *output_ += hash;
+ }
+ void WriteBool(bool value) { WriteUint8(value ? 1u : 0u); }
+
+ private:
+ std::string* output_;
+
+ DISALLOW_COPY_AND_ASSIGN(ByteCodeWriter);
+};
+
+// Encapsulates meta-data about all instructions, and is capable of transcoding
+// each instruction from a parsed text-based format to byte-code.
+class InstructionSet {
+ public:
+ InstructionSet() {
+ // Define new instructions in this list.
+ Add(Instruction("node", jtl::NAVIGATE, Arguments(Hash)));
+ Add(Instruction("any", jtl::NAVIGATE_ANY, Arguments()));
+ Add(Instruction("back", jtl::NAVIGATE_BACK, Arguments()));
+ Add(Instruction("store_bool", jtl::STORE_BOOL, Arguments(Hash, Bool)));
+ Add(Instruction("compare_stored_bool",
+ jtl::COMPARE_STORED_BOOL,
+ Arguments(Hash, Bool, Bool)));
+ Add(Instruction("store_hash", jtl::STORE_HASH, Arguments(Hash, Hash)));
+ Add(Instruction("compare_stored_hash",
+ jtl::COMPARE_STORED_HASH,
+ Arguments(Hash, Hash, Hash)));
+ Add(Instruction("compare_bool", jtl::COMPARE_NODE_BOOL, Arguments(Bool)));
+ Add(Instruction("compare_hash", jtl::COMPARE_NODE_HASH, Arguments(Hash)));
+ Add(Instruction("break", jtl::STOP_EXECUTING_SENTENCE, Arguments()));
+ }
+
+ bool TranscodeInstruction(const std::string& name,
+ const ListValue& arguments,
+ bool end_of_sentence,
+ const jtl::Hasher& hasher,
+ ByteCodeWriter* target) const {
+ if (instruction_map_.count(name) == 0)
+ return false;
+ const Instruction& instruction(instruction_map_.at(name));
+ if (instruction.argument_types.size() != arguments.GetSize())
+ return false;
+ target->WriteOpCode(instruction.op_code);
+ for (size_t i = 0; i < arguments.GetSize(); ++i) {
+ switch (instruction.argument_types[i]) {
+ case Bool: {
+ bool value;
+ if (!arguments.GetBoolean(i, &value))
+ return false;
+ target->WriteBool(value);
+ break;
+ }
+ case Hash: {
+ std::string value;
+ if (!arguments.GetString(i, &value))
+ return false;
+ target->WriteHash(hasher.GetHash(value));
+ break;
+ }
+ default:
+ NOTREACHED();
+ return false;
+ }
+ }
+ if (end_of_sentence)
+ target->WriteOpCode(jtl::END_OF_SENTENCE);
+ return true;
+ }
+
+ private:
+ // The possible types of an operation's argument.
+ enum ArgumentType {
+ None,
+ Bool,
+ Hash
+ };
+
+ // Encapsulates meta-data about one instruction.
+ struct Instruction {
+ Instruction() : op_code(jtl::END_OF_SENTENCE) {}
+ Instruction(const char* name,
+ jtl_foundation::OpCodes op_code,
+ const std::vector<ArgumentType>& argument_types)
+ : name(name), op_code(op_code), argument_types(argument_types) {}
+
+ std::string name;
+ jtl::OpCodes op_code;
+ std::vector<ArgumentType> argument_types;
+ };
+
+ static std::vector<ArgumentType> Arguments(ArgumentType arg1_type = None,
+ ArgumentType arg2_type = None,
+ ArgumentType arg3_type = None) {
+ std::vector<ArgumentType> result;
+ if (arg1_type != None)
+ result.push_back(arg1_type);
+ if (arg2_type != None)
+ result.push_back(arg2_type);
+ if (arg3_type != None)
+ result.push_back(arg3_type);
+ return result;
+ }
+
+ void Add(const Instruction& instruction) {
+ instruction_map_[instruction.name] = instruction;
+ }
+
+ std::map<std::string, Instruction> instruction_map_;
+
+ DISALLOW_COPY_AND_ASSIGN(InstructionSet);
+};
+
+} // namespace
+
+bool JtlCompiler::Compile(const std::string& source_code,
+ const std::string& hash_seed,
+ std::string* output_bytecode,
+ CompileError* error_details) {
+ DCHECK(output_bytecode);
+ InstructionSet instruction_set;
+ ByteCodeWriter bytecode_writer(output_bytecode);
+ jtl::Hasher hasher(hash_seed);
+ scoped_ptr<JtlParser> parser(JtlParser::Create(source_code));
+ while (parser->HasNextOperation()) {
+ std::string operation_name;
+ ListValue arguments;
+ bool end_of_sentence;
battre 2013/09/27 15:00:01 nit: initialize to false
engedy 2013/10/01 10:48:10 Done.
+ if (!parser->ParseNextOperation(
+ &operation_name, &arguments, &end_of_sentence)) {
+ if (error_details) {
+ error_details->context = parser->last_context();
+ error_details->line_number = parser->last_line_number();
+ error_details->error_code = CompileError::PARSING_ERROR;
+ }
+ return false;
+ }
+ if (!instruction_set.TranscodeInstruction(operation_name,
+ arguments,
+ end_of_sentence,
+ hasher,
+ &bytecode_writer)) {
+ if (error_details) {
+ error_details->context = parser->last_context();
+ error_details->line_number = parser->last_line_number();
+ error_details->error_code = CompileError::UNKNOWN_OPERATION;
+ }
+ return false;
+ }
+ }
+
+ return true;
+}

Powered by Google App Engine
This is Rietveld 408576698