Add a debug regex command to dump regex instructions

This commit is contained in:
Maxime Coste 2018-04-27 08:34:49 +10:00
parent f10eb9faa3
commit 8438b33175
5 changed files with 45 additions and 23 deletions

View File

@ -1143,7 +1143,7 @@ const CommandDesc debug_cmd = {
[](const Context& context, CompletionFlags flags,
const String& prefix, ByteCount cursor_pos) -> Completions {
auto c = {"info", "buffers", "options", "memory", "shared-strings",
"profile-hash-maps", "faces", "mappings"};
"profile-hash-maps", "faces", "mappings", "regex"};
return { 0_byte, cursor_pos, complete(prefix, cursor_pos, c) };
}),
[](const ParametersParser& parser, Context& context, const ShellContext&)
@ -1216,6 +1216,14 @@ const CommandDesc debug_cmd = {
keymaps.get_mapping(key, m).docstring));
}
}
else if (parser[0] == "regex")
{
if (parser.positional_count() != 2)
throw runtime_error("expected a regex");
write_to_debug_buffer(format(" * {}:\n{}",
parser[1], dump_regex(compile_regex(parser[1], RegexCompileFlags::None))));
}
else
throw runtime_error(format("no such debug command: '{}'", parser[0]));
}

View File

@ -992,60 +992,63 @@ private:
ParsedRegex& m_parsed_regex;
};
void dump_regex(const CompiledRegex& program)
String dump_regex(const CompiledRegex& program)
{
String res;
int count = 0;
for (auto& inst : program.instructions)
{
printf(" %03d ", count++);
char buf[10];
sprintf(buf, " %03d ", count++);
res += buf;
switch (inst.op)
{
case CompiledRegex::Literal:
printf("literal %lc\n", inst.param);
res += format("literal {}\n", inst.param);
break;
case CompiledRegex::Literal_IgnoreCase:
printf("literal (ignore case) %lc\n", inst.param);
res += format("literal (ignore case) {}\n", inst.param);
break;
case CompiledRegex::AnyChar:
printf("any char\n");
res += "any char\n";
break;
case CompiledRegex::Jump:
printf("jump %u\n", inst.param);
res += format("jump {}\n", inst.param);
break;
case CompiledRegex::Split_PrioritizeParent:
case CompiledRegex::Split_PrioritizeChild:
{
printf("split (prioritize %s) %u\n",
inst.op == CompiledRegex::Split_PrioritizeParent ? "parent" : "child",
inst.param);
res += format("split (prioritize {}) {}\n",
inst.op == CompiledRegex::Split_PrioritizeParent ? "parent" : "child",
inst.param);
break;
}
case CompiledRegex::Save:
printf("save %d\n", inst.param);
res += format("save {}\n", inst.param);
break;
case CompiledRegex::Class:
printf("class %d\n", inst.param);
res += format("class {}\n", inst.param);
break;
case CompiledRegex::CharacterType:
printf("character type %d\n", inst.param);
res += format("character type {}\n", inst.param);
break;
case CompiledRegex::LineStart:
printf("line start\n");
res += "line start\n";
break;
case CompiledRegex::LineEnd:
printf("line end\n");
res += "line end\n";
break;
case CompiledRegex::WordBoundary:
printf("word boundary\n");
res += "word boundary\n";
break;
case CompiledRegex::NotWordBoundary:
printf("not word boundary\n");
res += "not word boundary\n";
break;
case CompiledRegex::SubjectBegin:
printf("subject begin\n");
res += "subject begin\n";
break;
case CompiledRegex::SubjectEnd:
printf("subject end\n");
res += "subject end\n";
break;
case CompiledRegex::LookAhead:
case CompiledRegex::NegativeLookAhead:
@ -1078,16 +1081,17 @@ void dump_regex(const CompiledRegex& program)
String str;
for (auto it = program.lookarounds.begin() + inst.param; *it != -1; ++it)
utf8::dump(std::back_inserter(str), *it);
printf("%s (%s)\n", name, str.c_str());
res += format("{} ({})\n", name, str);
break;
}
case CompiledRegex::FindNextStart:
printf("find next start\n");
res += "find next start\n";
break;
case CompiledRegex::Match:
printf("match\n");
res += "match\n";
}
}
return res;
}
CompiledRegex compile_regex(StringView re, RegexCompileFlags flags)
@ -1134,7 +1138,7 @@ struct TestVM : CompiledRegex, ThreadedRegexVM<const char*, dir>
: CompiledRegex{compile_regex(re, dir == MatchDirection::Forward ?
RegexCompileFlags::None : RegexCompileFlags::Backward)},
VMType{(const CompiledRegex&)*this}
{ if (dump) dump_regex(*this); }
{ if (dump) printf(dump_regex(*this).c_str()); }
bool exec(StringView re, RegexExecFlags flags = RegexExecFlags::AnyMatch)
{

View File

@ -112,6 +112,8 @@ struct CompiledRegex : RefCountable, UseMemoryDomain<MemoryDomain::Regex>
std::unique_ptr<StartDesc> backward_start_desc;
};
String dump_regex(const CompiledRegex& program);
enum class RegexCompileFlags
{
None = 0,

View File

@ -125,6 +125,13 @@ InplaceString<15> to_string(int val)
return res;
}
InplaceString<15> to_string(unsigned val)
{
InplaceString<15> res;
res.m_length = sprintf(res.m_data, "%u", val);
return res;
}
InplaceString<23> to_string(long int val)
{
InplaceString<23> res;

View File

@ -72,6 +72,7 @@ struct Hex { size_t val; };
constexpr Hex hex(size_t val) { return {val}; }
InplaceString<15> to_string(int val);
InplaceString<15> to_string(unsigned val);
InplaceString<23> to_string(long int val);
InplaceString<23> to_string(size_t val);
InplaceString<23> to_string(long long int val);