diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2011-09-28 08:19:58 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2011-09-28 08:19:58 -0700 |
commit | 88a0ca81d753a6393b06fdabb984aeff48dcaa3b (patch) | |
tree | 1f901fe70fd43c3abe633c88866042463b308b1f /parser.y | |
parent | ea7e91958c74d51ce05245243715dda42715e6ab (diff) | |
download | txr-88a0ca81d753a6393b06fdabb984aeff48dcaa3b.tar.gz txr-88a0ca81d753a6393b06fdabb984aeff48dcaa3b.tar.bz2 txr-88a0ca81d753a6393b06fdabb984aeff48dcaa3b.zip |
* match.c (match_line): Logic restructured to allow for
regex variables which also have nested variables.
Previously this code was assuming that the cases were
mutually exclusive, and the parser happened to work that way.
Also, added support for a "double var" match which occurs
when an unbound variable is followed by a regex variable.
This case should be allowed because it makes sense.
It's similar to a variable followed by a regex, except
that the regex is also a variable binding.
* parser.y (o_elems_transform): New function.
(o_elems_opt, o_elems_opt2, quasilit): Transform o_elems with new
function. This is needed because subst_vars doesn't
deal with the nested var syntax for consecutive variables.
(var): New syntax case '{' IDENT exprs '}' elem. This
allows consecutive variables to be nested in all cases.
Diffstat (limited to 'parser.y')
-rw-r--r-- | parser.y | 34 |
1 files changed, 31 insertions, 3 deletions
@@ -42,6 +42,7 @@ int yylex(void); void yyerror(const char *); val repeat_rep_helper(val sym, val main, val parts); +val o_elems_transform(val output_form); val define_transform(val define_form); val lit_char_helper(val litchars); @@ -357,11 +358,12 @@ out_clauses_opt : out_clauses { $$ = $1; } o_line : o_elems_opt '\n' { $$ = $1; } ; -o_elems_opt : o_elems { $$ = cons(num(lineno - 1), $1); } +o_elems_opt : o_elems { $$ = cons(num(lineno - 1), + o_elems_transform($1)); } | { $$ = nil; } ; -o_elems_opt2 : o_elems { $$ = $1; } +o_elems_opt2 : o_elems { $$ = o_elems_transform($1); } | { $$ = null_list; } ; @@ -405,6 +407,8 @@ var : IDENT { $$ = list(var_s, intern(string_own($1), nil), $4, nao); } | '{' IDENT exprs '}' { $$ = list(var_s, intern(string_own($2), nil), nil, $3, nao); } + | '{' IDENT exprs '}' elem { $$ = list(var_s, intern(string_own($2), nil), + $5, $3, nao); } | var_op IDENT { $$ = list(var_s, intern(string_own($2), nil), nil, $1, nao); } | var_op IDENT elem { $$ = list(var_s, intern(string_own($2), nil), @@ -544,7 +548,7 @@ chrlit : '\'' '\'' { $$ = nil; ; quasilit : '`' '`' { $$ = null_string; } - | '`' quasi_items '`' { $$ = cons(quasi_s, $2); } + | '`' quasi_items '`' { $$ = cons(quasi_s, o_elems_transform($2)); } | '`' error { $$ = nil; yybadtoken(yychar, lit("string literal")); } ; @@ -595,6 +599,30 @@ val repeat_rep_helper(val sym, val main, val parts) last_parts, empty_parts, nao); } +val o_elems_transform(val o_elems) +{ + list_collect_decl(o_elems_out, ptail); + val iter; + + for (iter = o_elems; iter; iter = cdr(iter)) { + val elem = car(iter); + + while (consp(elem) && first(elem) == var_s) { + val sym = second(elem); + val pat = third(elem); + val modifiers = fourth(elem); + + list_collect(ptail, list(first(elem), sym, nil, modifiers, nao)); + elem = pat; + } + + if (elem) + list_collect(ptail, elem); + } + + return o_elems_out; +} + val define_transform(val define_form) { val sym = first(define_form); |