mirror of
git://projects.qi-hardware.com/eda-tools.git
synced 2024-11-26 22:32:50 +02:00
b2/: meta-variable $ for "previously matched variable"
We need this for iterative processing of FN.
This commit is contained in:
parent
2946b830f1
commit
3d2eca34ff
5
b2/SUBST
5
b2/SUBST
@ -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:
|
||||||
|
|
||||||
|
@ -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"))
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
16
b2/lang.y
16
b2/lang.y
@ -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;
|
||||||
|
@ -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 {
|
||||||
|
39
b2/subex.c
39
b2/subex.c
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user