1
0
mirror of git://projects.qi-hardware.com/eda-tools.git synced 2024-11-23 06:37:13 +02:00

b2/: meta-variable $ for "previously matched variable"

We need this for iterative processing of FN.
This commit is contained in:
Werner Almesberger 2012-05-22 13:01:39 -03:00
parent 2946b830f1
commit 3d2eca34ff
7 changed files with 52 additions and 17 deletions

View File

@ -1,5 +1,7 @@
FN=DNP { ignore } FN=DNP { ignore }
FN=X(*) { $=$1 }
REF=R[0-9]* { REF=R[0-9]* {
T=R T=R
VAL=(#R) { R=$1 } VAL=(#R) { R=$1 }
@ -23,8 +25,9 @@ variable:
$foo, ... $foo, ...
with curly braces: with curly braces:
${foo}, ... ${foo}, ...
input variable: input variable (in pattern):
$$ $$
the input variable ($) can also be used as LHS for matches and assignments
Caveat: Caveat:

View File

@ -94,6 +94,7 @@ int main(int argc, char **argv)
void (*process)(const char *name) = parse_hierarchy; void (*process)(const char *name) = parse_hierarchy;
int i; int i;
dollar = unique("$");
for (i = 1; i != argc; i++) { for (i = 1; i != argc; i++) {
if (*argv[i] == '-') { if (*argv[i] == '-') {
if (!strcmp(argv[i], "-c")) if (!strcmp(argv[i], "-c"))

View File

@ -17,6 +17,8 @@
#include "subst.h" #include "subst.h"
extern const char *dollar; /* "$" */
extern struct action hierarchy; extern struct action hierarchy;
extern struct subst *substitutions; extern struct subst *substitutions;

View File

@ -25,6 +25,8 @@
#include "y.tab.h" #include "y.tab.h"
const char *dollar;
struct action hierarchy; struct action hierarchy;
struct subst *substitutions = NULL; struct subst *substitutions = NULL;
@ -110,6 +112,7 @@ static const struct field *top_field(void)
%type <stock> stock %type <stock> stock
%type <prov> providers provider %type <prov> providers provider
%type <subst> substitutions block opt_block %type <subst> substitutions block opt_block
%type <s> word_or_dollar
%% %%
@ -589,7 +592,7 @@ block:
{ {
$$ = NULL; $$ = NULL;
} }
| WORD relop PATTERN opt_block block | word_or_dollar relop PATTERN opt_block block
{ {
if ($4) { if ($4) {
if ($2 != rel_eq) if ($2 != rel_eq)
@ -622,6 +625,17 @@ block:
} }
; ;
word_or_dollar:
'$'
{
$$ = dollar;
}
| WORD
{
$$ = $1;
}
;
opt_block: opt_block:
{ {
$$ = NULL; $$ = NULL;

View File

@ -66,6 +66,8 @@ struct value {
* When using "struct param" to store (string) variables not associated to a * When using "struct param" to store (string) variables not associated to a
* field, then u.name contains the variable name, "op" contains the relational * field, then u.name contains the variable name, "op" contains the relational
* operator (default rel_eq), and value.u.s contains the variable's value. * operator (default rel_eq), and value.u.s contains the variable's value.
*
* If the variable is "$", then u.name is set to NULL.
*/ */
struct param { struct param {

View File

@ -20,6 +20,7 @@
#include "util.h" #include "util.h"
#include "vstring.h" #include "vstring.h"
#include "lang.h"
#include "relop.h" #include "relop.h"
#include "subst.h" #include "subst.h"
#include "subex.h" #include "subex.h"
@ -163,46 +164,53 @@ static int do_match_1(const char *var, const regex_t *re,
} }
static int do_match(const char *var, const regex_t *re, static int do_match(const char **var, const regex_t *re,
const struct param *in, const struct param *out, const struct param *in, const struct param *out,
const char **val, regmatch_t *match) const char **val, regmatch_t *match)
{ {
int i; int i;
if (var != fn) if (*var != fn)
return do_match_1(var, re, in, out, val, match); return do_match_1(*var, re, in, out, val, match);
for (i = 0; i != FIELDS; i++) for (i = 0; i != FIELDS; i++)
if (!do_match_1(f[i], re, in, out, val, match)) if (!do_match_1(f[i], re, in, out, val, match)) {
*var = f[i];
return 0; return 0;
}
return -1; return -1;
} }
static const struct subst *recurse_sub(const struct subst *sub, static const struct subst *recurse_sub(const struct subst *sub,
const struct param *in, const char *s, const regmatch_t *match, const struct param *in, const char *matched_var, const char *matched_val,
const char *units, struct param **out) const regmatch_t *match, const char *units, struct param **out)
{ {
const struct subst *jump; const struct subst *jump;
regmatch_t m_tmp[10]; regmatch_t m_tmp[10];
const char *val; const char *var, *val;
char *tmp; char *tmp;
while (sub) { while (sub) {
switch (sub->type) { switch (sub->type) {
case st_match: case st_match:
if (do_match(sub->u.match.src, &sub->u.match.re, var = sub->u.match.src;
if (var == dollar)
var = matched_var;
if (do_match(&var, &sub->u.match.re,
in, *out, &val, m_tmp)) in, *out, &val, m_tmp))
break; break;
jump = recurse_sub(sub->u.match.block, in, val, m_tmp, jump = recurse_sub(sub->u.match.block, in,
sub->u.match.units, out); var, val, m_tmp, sub->u.match.units, out);
if (jump && jump != sub) if (jump && jump != sub)
return jump; return jump;
break; break;
case st_assign: case st_assign:
tmp = compose(sub->u.assign.pat, in, *out, s, match, tmp = compose(sub->u.assign.pat, in, *out, matched_val,
units); match, units);
do_assign(sub->u.assign.dst, out, sub->u.assign.op, var = sub->u.assign.dst;
tmp); if (var == dollar)
var = matched_var;
do_assign(var, out, sub->u.assign.op, tmp);
break; break;
case st_end: case st_end:
return &jump_end; return &jump_end;
@ -237,5 +245,6 @@ int substitute(const struct subst *sub, const struct param *in,
} }
} }
*out = NULL; *out = NULL;
return recurse_sub(sub, in, NULL, NULL, NULL, out) != &jump_ignore; return recurse_sub(sub, in, NULL, NULL, NULL, NULL, out)
!= &jump_ignore;
} }

View File

@ -356,10 +356,14 @@ static void recurse_fin(struct subst *sub, const struct parent *parent)
sub->prev = prev; sub->prev = prev;
switch (sub->type) { switch (sub->type) {
case st_match: case st_match:
if (!parent && sub->u.match.src == dollar)
yyerror("$ without match");
next.sub = sub; next.sub = sub;
recurse_fin(sub->u.match.block, &next); recurse_fin(sub->u.match.block, &next);
break; break;
case st_assign: case st_assign:
if (!parent && sub->u.assign.dst == dollar)
yyerror("$ without match");
check_chunks(sub->u.assign.pat, parent, prev); check_chunks(sub->u.assign.pat, parent, prev);
break; break;
case st_end: case st_end: