diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2014-08-11 22:01:59 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2014-08-11 22:01:59 -0700 |
commit | 17c43f985b8c707e997fe65a20ce31430f51bb36 (patch) | |
tree | e607df7e43896557804c3600f263c72748f60639 | |
parent | 7876104ee7e73c190b67e90a87fe5a44f40c4af6 (diff) | |
download | txr-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-- | ChangeLog | 18 | ||||
-rw-r--r-- | match.c | 37 | ||||
-rw-r--r-- | parser.y | 21 |
3 files changed, 36 insertions, 40 deletions
@@ -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, @@ -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)))) { @@ -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"); } |