summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-08-11 22:01:59 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-08-11 22:01:59 -0700
commit17c43f985b8c707e997fe65a20ce31430f51bb36 (patch)
treee607df7e43896557804c3600f263c72748f60639
parent7876104ee7e73c190b67e90a87fe5a44f40c4af6 (diff)
downloadtxr-17c43f985b8c707e997fe65a20ce31430f51bb36.tar.gz
txr-17c43f985b8c707e997fe65a20ce31430f51bb36.tar.bz2
txr-17c43f985b8c707e997fe65a20ce31430f51bb36.zip
First cut at restructuring how variable matching works in the pattern
language. The goal is to remove the strict behavior of using only one element of context after a variable. variable form at parse time: we unravel that first. * parser.y (grammar): Simplifying the phrase structure rule for the var element. All the variants that have a trailing elem are removed. The abstract syntax changes; the modifier moves to the third position in the list. * match.c (h_var): Matching change: the element which follows a variable is now pulled from the specline rather than the variable syntax, which is how it should have been done in the first place. The modifiers are pulled from a different spot in the variable syntax.
-rw-r--r--ChangeLog18
-rw-r--r--match.c37
-rw-r--r--parser.y21
3 files changed, 36 insertions, 40 deletions
diff --git a/ChangeLog b/ChangeLog
index dfdb84fe..d9a06d9a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2014-08-11 Kaz Kylheku <kaz@kylheku.com>
+
+ First cut at restructuring how variable matching works in the pattern
+ language. The goal is to remove the strict behavior of using only one
+ element of context after a variable.
+ variable form at parse time: we unravel that first.
+
+ * parser.y (grammar): Simplifying the phrase structure
+ rule for the var element. All the variants that have
+ a trailing elem are removed. The abstract syntax
+ changes; the modifier moves to the third position in the
+ list.
+
+ * match.c (h_var): Matching change: the element which follows
+ a variable is now pulled from the specline rather than the variable
+ syntax, which is how it should have been done in the first place. The
+ modifiers are pulled from a different spot in the variable syntax.
+
2014-08-09 Kaz Kylheku <kaz@kylheku.com>
* filter.c (filter_init): Expose the trie-lookup-begin,
diff --git a/match.c b/match.c
index 71692d1e..0ffc1220 100644
--- a/match.c
+++ b/match.c
@@ -484,16 +484,16 @@ static val search_form(match_line_ctx *c, val needle_form, val from_end)
static val h_var(match_line_ctx *c)
{
- val elem = first(c->specline);
+ val elem = pop(&c->specline);
val sym = second(elem);
- val pat = third(elem);
- val modifiers = fourth(elem);
+ val pat = first(c->specline);
+ val modifiers = third(elem);
val modifier = first(modifiers);
val pair = if2(sym, assoc(sym, c->bindings)); /* exists? */
if (sym == t)
sem_error(elem, lit("t is not a bindable symbol"), nao);
-
+
if (gt(length_list(modifiers), one)) {
sem_error(elem, lit("multiple modifiers on variable ~s"),
sym, nao);
@@ -504,10 +504,11 @@ static val h_var(match_line_ctx *c)
it with its value, and treat it as a string match.
The spec looks like ((var <sym> <pat>) ...)
and it must be transformed into
- (<sym-substituted> <pat> ...) */
- if (pat) {
- c->specline = rlcp(cons(cdr(pair), cons(pat, rest(c->specline))), c->specline);
- } else if (fixnump(modifier)) {
+ (<sym-substituted> <pat> ...).
+ But if the variable is a fix sized field match,
+ then we treat that specially: it has to match
+ that much text. */
+ if (fixnump(modifier)) {
val past = plus(c->pos, modifier);
if (length_str_lt(c->dataline, past) || lt(past, c->pos))
@@ -525,9 +526,9 @@ static val h_var(match_line_ctx *c)
LOG_MATCH("fixed field", past);
c->pos = past;
- c->specline = cdr(c->specline);
+ c->specline = rest(c->specline);
} else {
- c->specline = rlcp(cons(cdr(pair), rest(c->specline)), c->specline);
+ c->specline = rlcp(cons(cdr(pair), c->specline), c->specline);
}
return repeat_spec_k;
} else if (consp(modifier)) { /* var bound over text matched by form */
@@ -599,9 +600,8 @@ static val h_var(match_line_ctx *c)
/* Unbound var followed by var: the following one must either
be bound, or must specify a regex. */
val second_sym = second(pat);
- val next_pat = third(pat);
- val next_modifiers = fourth(pat);
- val next_modifier = first(fourth(pat));
+ val next_modifiers = third(pat);
+ val next_modifier = first(next_modifiers);
val pair = if2(second_sym, assoc(second_sym, c->bindings)); /* exists? */
if (gt(length_list(next_modifiers), one)) {
@@ -634,21 +634,14 @@ static val h_var(match_line_ctx *c)
c->pos = fpos;
LOG_MATCH("double var regex (second var)", plus(fpos, flen));
c->pos = plus(fpos, flen);
- if (next_pat) {
- c->specline = rlcp(cons(next_pat, rest(c->specline)), c->specline);
- return repeat_spec_k;
- }
+ return next_spec_k;
} else if (!pair) {
sem_error(elem, lit("consecutive unbound variables"), nao);
} else {
/* Re-generate a new spec with an edited version of
the element we just processed, and repeat. */
val new_elem = list(var_s, sym, cdr(pair), modifier, nao);
-
- if (next_pat)
- c->specline = cons(new_elem, cons(next_pat, rest(c->specline)));
- else
- c->specline = cons(new_elem, rest(c->specline));
+ c->specline = cons(elem, cons(new_elem, rest(c->specline)));
return repeat_spec_k;
}
} else if (consp(pat) && (consp(first(pat)) || stringp(first(pat)))) {
diff --git a/parser.y b/parser.y
index 37e066cc..b8fdbbd9 100644
--- a/parser.y
+++ b/parser.y
@@ -644,25 +644,10 @@ rep_parts_opt : SINGLE o_elems_opt
* that generates an empty phrase causes reduce/reduce conflicts.
*/
var : SYMTOK { $$ = list(var_s, symhlpr($1, nil), nao); }
- | SYMTOK elem { $$ = list(var_s, symhlpr($1, nil),
- $2, nao); }
| '{' SYMTOK '}' { $$ = list(var_s, symhlpr($2, nil), nao); }
- | '{' SYMTOK '}' elem { $$ = list(var_s, symhlpr($2, nil),
- $4, nao); }
- | '{' SYMTOK modifiers '}' { $$ = list(var_s, symhlpr($2, nil),
- nil, $3, nao); }
- | '{' SYMTOK modifiers '}' elem
- { $$ = list(var_s, symhlpr($2, nil),
- $5, $3, nao); }
- | var_op SYMTOK { $$ = list(var_s, symhlpr($2, nil),
- nil, $1, nao); }
- | var_op SYMTOK elem { $$ = list(var_s, symhlpr($2, nil),
- $3, $1, nao); }
- | var_op '{' SYMTOK '}' { $$ = list(var_s, symhlpr($3, nil),
- nil, $1, nao); }
- | var_op '{' SYMTOK '}' elem
- { $$ = list(var_s, symhlpr($3, nil),
- $5, $1, nao); }
+ | '{' SYMTOK modifiers '}' { $$ = list(var_s, symhlpr($2, nil), $3, nao); }
+ | var_op SYMTOK { $$ = list(var_s, symhlpr($2, nil), $1, nao); }
+ | var_op '{' SYMTOK '}' { $$ = list(var_s, symhlpr($3, nil), $1, nao); }
| var_op '{' SYMTOK regex '}' { $$ = nil;
yyerr("longest match "
"not useable with regex"); }