Injected rules rank higher if they match against the left scope

This allows overriding “native” rules via injecting.

This commit drops support for using ‘.’ as (injection) scope selector to match everywhere. Instead use ‘*’.
This commit is contained in:
Joachim Mårtensson
2013-04-30 21:22:12 +02:00
committed by Allan Odgaard
parent 715624b952
commit 35227b48ea

View File

@@ -294,6 +294,28 @@ namespace parse
return rank;
}
static size_t collect_injections (rule_ptr const& base, char const* first, char const* last, stack_ptr const& stack, size_t i, bool firstLine, std::set<ranked_match_t>& res, std::map<size_t, regexp::match_t>& match_cache, std::set<size_t>& unique, size_t rank, scope::context_t const& scope)
{
for(stack_ptr node = stack; node; node = node->parent)
{
if(!node->rule->injections)
continue;
iterate(it, *node->rule->injections)
{
if(scope::selector_t(it->first).does_match(scope))
rank = collect_rule(base, first, last, stack->anchor, i, firstLine, it->second, res, match_cache, unique, rank);
}
}
citerate(it, injected_grammars())
{
if(it->first.does_match(scope))
rank = collect_children(base, first, last, stack->anchor, i, firstLine, it->second->children, res, match_cache, unique, rank);
}
return rank;
}
static void collect_rules (rule_ptr const& base, char const* first, char const* last, size_t i, bool firstLine, stack_ptr const& stack, std::set<ranked_match_t>& res, std::map<size_t, regexp::match_t>& match_cache)
{
res.clear();
@@ -306,25 +328,10 @@ namespace parse
}
std::set<size_t> unique;
size_t rank = collect_children(base, first, last, stack->anchor, i, firstLine, stack->rule->children, res, match_cache, unique);
for(stack_ptr node = stack; node; node = node->parent)
{
if(!node->rule->injections)
continue;
iterate(it, *node->rule->injections)
{
if(it->first == "." || scope::selector_t(it->first).does_match(stack->scope))
collect_rule(base, first, last, stack->anchor, i, firstLine, it->second, res, match_cache, unique, rank);
}
}
citerate(it, injected_grammars())
{
if(to_s(it->first) == "." || it->first.does_match(stack->scope))
collect_children(base, first, last, stack->anchor, i, firstLine, it->second->children, res, match_cache, unique, rank);
}
size_t rank = 0;
rank = collect_injections(base, first, last, stack, i, firstLine, res, match_cache, unique, rank, scope::context_t(stack->scope, ""));
rank = collect_children(base, first, last, stack->anchor, i, firstLine, stack->rule->children, res, match_cache, unique, rank);
rank = collect_injections(base, first, last, stack, i, firstLine, res, match_cache, unique, rank, scope::context_t("", stack->scope));
}
static bool has_cycle (size_t rule_id, size_t i, stack_ptr const& stack)