Fix handling of precedence for repeat rules

This commit is contained in:
Max Brunsfeld 2015-11-01 21:00:44 -08:00
parent d6ee28abd0
commit d7cb48aae7
6 changed files with 1039 additions and 919 deletions

View file

@ -259,6 +259,27 @@ describe("LexItemSet::transitions()", [&]() {
})));
});
it("handles repeats with precedence", [&]() {
LexItemSet item_set({
LexItem(Symbol(1), prec(-1, repeat1(character({ 'a' }))))
});
AssertThat(
item_set.transitions(),
Equals(LexItemSet::TransitionMap({
{
CharacterSet().include('a'),
{
LexItemSet({
LexItem(Symbol(1), prec(-1, repeat1(character({ 'a' })))),
LexItem(Symbol(1), prec(-1, blank())),
}),
PrecedenceRange(-1)
}
}
})));
});
it("handles choices between overlapping character sets", [&]() {
LexItemSet item_set({
LexItem(Symbol(1), choice({

View file

@ -14,7 +14,8 @@ extern const Grammar c = Grammar({
{ "preproc_define", seq({
str("#define"),
sym("identifier"),
token(repeat(choice({ str("\\\n"), pattern(".") }))) }) },
optional(token(prec(-1, repeat1(choice({ str("\\\n"), pattern(".") }))))),
str("\n") }) },
{ "function_definition", seq({
optional(sym("declaration_specifiers")),

File diff suppressed because it is too large Load diff

View file

@ -594,7 +594,7 @@ static TSTree *ts_lex(TSLexer *lexer, TSStateId lex_state) {
(lookahead == '\n') ||
(lookahead == 'g')))
ADVANCE(29);
ACCEPT_TOKEN(sym_comment);
ACCEPT_TOKEN(sym_regex);
case 28:
if (!((lookahead == 0) ||
(lookahead == '\n')))

View file

@ -89,7 +89,8 @@ class LexTableBuilder {
rules::Metadata::build(
separator_rule,
{
{ rules::START_TOKEN, 1 }, { rules::PRECEDENCE, -1 },
{ rules::START_TOKEN, 1 },
{ rules::PRECEDENCE, -99999 },
}),
rule,
})));

View file

@ -109,13 +109,17 @@ class LexItemTransitions : public rules::RuleFn<void> {
LexItemSet::TransitionMap content_transitions;
LexItemTransitions(&content_transitions, this).apply(rule->content);
for (const auto &pair : content_transitions) {
PrecedenceRange precedence(pair.second.second);
if (precedence.empty && !precedence_stack->empty())
precedence.add(precedence_stack->back());
merge_transition(transitions, pair.first, pair.second.first,
pair.second.second);
precedence);
merge_transition(
transitions, pair.first,
transform_item_set(pair.second.first, [&rule](rule_ptr item_rule) {
return rules::Seq::build({ item_rule, rule->copy() });
}), pair.second.second);
}), precedence);
}
}