| Cobra | Inline Programs | accessing pattern sets | ||
|---|---|---|---|---|
| NAMEAccessing Pattern Sets from Inline ProgramsSYNTAXadd_pattern(N, n, m) del_pattern(N, n, m) is_pattern(N) pattern_exists(N) DESCRIPTIONPattern sets are normally defined with query commands (see pe and ps), but they can also be created, and accessed, from within inline Cobra programs. Four predefined functions support this access. (But, see also the builtin function pset for some additional ways to access the matches in a named pattern set.)In th syntax section above, N is the name of the pattern set, which is either specified as a name, a string, or a string variable, and n and m token references: Function add_pattern(N, n, m);adds a pattern to pattern set N, creating that pattern set if it does not yet exist. The first lexical token that is part of the pattern to be added is the token referenced by variable n, and the last is the token references by variable m. Function del_pattern(N, n, m);deletes the first pattern matching the start and end token specified in pattern set N. It is an error if set N does not exist. Bound variables are not checked for this function. Function is_pattern(N)returns non-zero if the pattern with name N exists, and zero otherwise. It has no side-effects (i.e., it will not create the pattern if it does not exist). A synonym of is_pattern(N) is pattern_exists(N). EXAMPLESAdding a pattern to an existing set is simple:
	$ cobra cobra_list.c
	1 core, 1 files, 1192 tokens
	: pe A: while ( .* )
	1 pattern stored in set 'A'
	%{
		a = Begin; # make up an arbitrary new match sequence
		b = Begin.nxt;
		add_pattern(A, a, b);	# add it to set A
		Stop;
	%}
	: dp A		# now has 2 patterns
	1: cobra_list.c:7..7
		7  #include "cobra.h"
	2: cobra_list.c:206..206
		206          while (p)
	2 patterns
	:
An example of a case where we want to refine a search by deleting selected patterns
could be as follows. Here we look for a pattern where a locally defined array variable
(bound to meta variable x) is used as an actual parameter in a function call,
where we use a pattern set constraint to exclude calls to the library function memset.
	pe C1: { .* @type x:@ident \[ .* \] .* @ident <1> ( .* :x .* ) \; .* } @1 (.txt != "memset")
We now want to refine this pattern set by removing local declarations marked as extern.
There are of course more direct ways to do the same, but this can illustrate the principle.
	%{
		p = pset(C1);
		while (p.seq != 0)
		{	v = p.p_bdef;	# def of bound variable x:@ident
			v = v.prv;	# @type
			v = v.prv;	# . @type x:@ident
			if (v.txt == "extern")
			{	ff = p.p_start;
				tt = p.p_end;
				del_pattern(C1, ff, tt);	# omit match
			}
			p = p.nxt;
		}
		Stop;
	%}
Note that the pattern match is deleted from the pattern-set itself, not from the list
returned by the pset command.NOTESIf functions add_pattern or del_pattern are used for a pattern set that was previously copied with a pset command, the copied structure is not automatically updated, and keeps referring to the elements at the time the copy was created. A new pset call will copy the updated structure. A repeated pset that is issued without changes having been made to the pattern set will not create a new version of the sequence, but return the old instance.SEE ALSOfunctions_predefined, pset | ||||
| Inline Programs Manual Tutorial | (Last Updated: 22 June 2024) | |||