Added tagged definitions: foo:: blah
This commit is contained in:
parent
24ed834317
commit
206e1fa68f
@ -72,7 +72,11 @@ static void push_matchstring(lua_State *L, match_t *m)
|
||||
|
||||
static void set_capture_fields(lua_State *L, match_t *m, int *n, const char *start)
|
||||
{
|
||||
if (m->pat->type == BP_CAPTURE) {
|
||||
if (m->pat->type == BP_TAGGED) {
|
||||
lua_pushlstring(L, m->pat->args.capture.name, m->pat->args.capture.namelen);
|
||||
lua_setfield(L, -2, "__tag");
|
||||
set_capture_fields(L, m->children[0], n, start);
|
||||
} else if (m->pat->type == BP_CAPTURE) {
|
||||
if (m->pat->args.capture.namelen > 0) {
|
||||
lua_pushlstring(L, m->pat->args.capture.name, m->pat->args.capture.namelen);
|
||||
push_match(L, m->children[0], start);
|
||||
|
3
json.c
3
json.c
@ -30,6 +30,9 @@ static int _json_match(const char *text, match_t *m, int comma, bool verbose)
|
||||
}
|
||||
printf("\",\"range\":[%ld,%ld]", m->start - text, m->end - text);
|
||||
|
||||
if (m->pat->type == BP_TAGGED)
|
||||
printf(",\"tag\":\"%.*s\"", (int)m->pat->args.capture.namelen, m->pat->args.capture.name);
|
||||
|
||||
if (m->children && (verbose || m->pat->type != BP_REF)) {
|
||||
printf(",\"children\":[");
|
||||
for (int i = 0; m->children && m->children[i]; i++)
|
||||
|
4
match.c
4
match.c
@ -256,7 +256,7 @@ static pat_t *get_prerequisite(match_ctx_t *ctx, pat_t *pat)
|
||||
if (p->args.repetitions.min == 0)
|
||||
return p;
|
||||
p = p->args.repetitions.repeat_pat; break;
|
||||
case BP_CAPTURE:
|
||||
case BP_CAPTURE: case BP_TAGGED:
|
||||
p = p->args.capture.capture_pat; break;
|
||||
case BP_CHAIN: {
|
||||
pat_t *f = p->args.multiple.first;
|
||||
@ -538,7 +538,7 @@ static match_t *match(match_ctx_t *ctx, const char *str, pat_t *pat)
|
||||
match_t *after = match(ctx, str, pat->args.pat);
|
||||
return after ? new_match(pat, str, str, MATCHES(after)) : NULL;
|
||||
}
|
||||
case BP_CAPTURE: {
|
||||
case BP_CAPTURE: case BP_TAGGED: {
|
||||
match_t *p = match(ctx, str, pat->args.pat);
|
||||
return p ? new_match(pat, str, p->end, MATCHES(p)) : NULL;
|
||||
}
|
||||
|
10
pattern.c
10
pattern.c
@ -210,6 +210,7 @@ static pat_t *_bp_definition(const char *start, const char *end)
|
||||
const char *str = after_name(start, end);
|
||||
size_t namelen = (size_t)(str - start);
|
||||
if (!matchchar(&str, ':', false, end)) return NULL;
|
||||
bool is_tagged = matchchar(&str, ':', false, end);
|
||||
pat_t *def = bp_pattern_nl(str, end, false);
|
||||
if (!def) parse_err(str, end, "Could not parse this definition.");
|
||||
str = def->end;
|
||||
@ -217,6 +218,13 @@ static pat_t *_bp_definition(const char *start, const char *end)
|
||||
pat_t *ret = new_pat(BP_DEFINITIONS, start, str, 0, -1);
|
||||
ret->args.def.name = start;
|
||||
ret->args.def.namelen = namelen;
|
||||
if (is_tagged) { // `id:: foo` means define a rule named `id` that gives captures an `id` tag
|
||||
pat_t *capture = new_pat(BP_TAGGED, def->start, def->end, def->min_matchlen, def->max_matchlen);
|
||||
capture->args.capture.capture_pat = def;
|
||||
capture->args.capture.name = start;
|
||||
capture->args.capture.namelen = namelen;
|
||||
def = capture;
|
||||
}
|
||||
ret->args.def.meaning = def;
|
||||
ret->args.def.next_def = _bp_definition(after_spaces(str, true, end), end);
|
||||
if (ret->args.def.next_def)
|
||||
@ -679,7 +687,7 @@ void delete_pat(pat_t **at_pat, bool recursive)
|
||||
case BP_REPLACE:
|
||||
delete_pat(&pat->args.replace.pat, true);
|
||||
break;
|
||||
case BP_CAPTURE:
|
||||
case BP_CAPTURE: case BP_TAGGED:
|
||||
delete_pat(&pat->args.capture.capture_pat, true);
|
||||
break;
|
||||
case BP_NOT: case BP_AFTER: case BP_BEFORE:
|
||||
|
Loading…
Reference in New Issue
Block a user