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

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: 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..21104e9bb87b2bf788bcfac03c04a679d1025a9a
--- /dev/null
+++ b/chrome/tools/profile_reset/jtl_compiler.cc
@@ -0,0 +1,193 @@
+// 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 <map>
+
+#include "base/logging.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_EQ(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 each instruction 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()));
+ }
+
+ JtlCompiler::CompileError::ErrorCode TranscodeInstruction(
+ const std::string& name,
+ const ListValue& arguments,
+ bool ends_sentence,
+ const jtl::Hasher& hasher,
+ ByteCodeWriter* target) const {
+ if (instruction_map_.count(name) == 0)
+ return JtlCompiler::CompileError::INVALID_OPERATION_NAME;
+ const Instruction& instruction(instruction_map_.at(name));
+ if (instruction.argument_types.size() != arguments.GetSize())
+ return JtlCompiler::CompileError::INVALID_ARGUMENT_COUNT;
+ target->WriteOpCode(instruction.op_code);
+ for (size_t i = 0; i < arguments.GetSize(); ++i) {
+ switch (instruction.argument_types[i]) {
+ case Bool: {
+ bool value = false;
+ if (!arguments.GetBoolean(i, &value))
+ return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE;
+ target->WriteBool(value);
+ break;
+ }
+ case Hash: {
+ std::string value;
+ if (!arguments.GetString(i, &value))
+ return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE;
+ target->WriteHash(hasher.GetHash(value));
+ break;
+ }
+ default:
+ NOTREACHED();
+ return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE;
+ }
+ }
+ if (ends_sentence)
+ target->WriteOpCode(jtl::END_OF_SENTENCE);
+ return JtlCompiler::CompileError::ERROR_NONE;
+ }
+
+ 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);
+
+ std::string compacted_source_code;
+ std::vector<size_t> newline_indices;
+ size_t mismatched_quotes_line;
+ if (!JtlParser::RemoveCommentsAndAllWhitespace(source_code,
+ &compacted_source_code,
+ &newline_indices,
+ &mismatched_quotes_line)) {
+ if (error_details) {
+ error_details->context = ""; // No meaningful intra-line context here.
+ error_details->line_number = mismatched_quotes_line;
+ error_details->error_code = CompileError::MISMATCHED_DOUBLE_QUOTES;
+ }
+ return false;
+ }
+
+ JtlParser parser(compacted_source_code, newline_indices);
+ while (!parser.HasFinished()) {
+ std::string operation_name;
+ ListValue arguments;
+ bool ends_sentence = false;
+ if (!parser.ParseNextOperation(
+ &operation_name, &arguments, &ends_sentence)) {
+ if (error_details) {
+ error_details->context = parser.GetLastContext();
+ error_details->line_number = parser.GetLastLineNumber();
+ error_details->error_code = CompileError::PARSING_ERROR;
+ }
+ return false;
+ }
+ CompileError::ErrorCode error_code = instruction_set.TranscodeInstruction(
+ operation_name, arguments, ends_sentence, hasher, &bytecode_writer);
+ if (error_code != CompileError::ERROR_NONE) {
+ if (error_details) {
+ error_details->context = parser.GetLastContext();
+ error_details->line_number = parser.GetLastLineNumber();
+ error_details->error_code = error_code;
+ }
+ return false;
+ }
+ }
+
+ return true;
+}
« 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