BP2 Reference Manual 8.	Procedures 9.	Csound argument mapping Title Page Index Contents

8. Procedures

Formal grammars may be seen as declarative descriptions of string languages. A frequently raised question addresses the possibility of encapsulating procedural knowledge into declarative knowledge. In a formal grammar this may be accomplished by "flags" (see "Programmed grammars", QuickStart §11) or by other procedures, see for instance "Destroying structures" §4.5.

Here we deal with procedures that may be inserted in subgrammar rules. Every procedure name starts with an underline character. Current procedures are

_destru _goto _failed _repeat _stop

that control derivations, and

_print _printOn _printOff _stepOn _stepOff _traceOn _traceOff

that modify the trace output, not the derivation itself.

Note that the names of procedures are not case-sensitive. Thus, for example, "_traceOn" may be equivalently written "_Traceon", "_TRACEON", etc.

If a procedure appears in the left argument of a rule it is executed before the rule is applied. If it appears in the right argument it is executed once the rule has been applied. Trace procedures, _destru and _stop may appear on either side, but _goto, _failed and _repeat must only appear in the right argument of a rule.

Procedures in the left argument should be placed after weights and flags, and before any variables or terminal symbols. Procedures in the right argument should be placed after variables or terminal symbols.

8.1 Production procedures

_destru works exactly as described in §4.5, but it will only be performed if the rule in which it appears is a candidate rule.

_goto is an unconditional jump to another subgrammar or another specific rule in a subgrammar. Its syntax is

_goto(igram,irul)

where igram is the index of the destination grammar and irul the index of the destination rule. In case irul = 0, BP2 will jump to subgrammar igram and look for any candidate rule. If (igram,irul) does not point at a candidate rule, BP2 will either execute a _failed conditional jump (see infra) or search a candidate rule in subgrammar igram. If none is found it will jump to subgrammar igram+1, etc. as usual.

When compiling the grammar BP2 will check that there is a rule indexed irul in subgrammar igram. If there is no such rule an error will be reported.

_failed is a conditional jump to another subgrammar or another specific rule in a subgrammar. Its syntax is

_failed(igram,irul)

in which igram and irul have the same meanings as in _goto. The jump will be performed if the rule was selected by a preceding _goto or _failed and it was not a candidate rule.

_repeat is a loop. Its simplest syntax is

_repeat(n)

where n is an integer value indicating that the current rule should be tried n times. Alternate syntaxes are

_repeat(Kx) and _repeat(Kx = n)

where Kx is a parameter that may be assigned a fixed value (Kx = n) and/or controlled in real time by an external MIDI device (see QuickStart §6). Remember that fixed value assignment must be done only once in the entire grammar.

Both _repeat and _goto may appear in the same rule, e.g.:

X --> a b _repeat(12) _goto(4,8)

In this case, _goto(4,8) will be performed once the rule has been applied 12 times or it is no longer candidate.

See example "-gr.tryrepeat" for important remarks.

8.2 Trace procedures

_stop makes a pause. The "Resume/stop" window is displayed.

_print displays the work string in the "Trace" window.

_printOn and _printOff set the "Display computation" mode on and off respectively. Similarly, _traceOn and _traceOff set the "Trace computation" mode on and off respectively, while _stepOn and _stepOff do the same with the "Step computation" mode.

8.3 Renumbering and remapping conditional jumps

If the grammar has been successfully compiled once, grammar and rule indexes have been inserted in the leftmost part of each rule. This part serves as an identification header. If you need to displace a rule, cut and paste it along with its identification header without changing its arguments . When recompiling the grammar, BP2 will renumber rules and subgrammars, and eventually modify identification headers and arguments in _goto and _failed procedures. Consider for example grammar "-gr.tryGOTO":

-ho.abc
-se.tryGOTO
[This grammar generates a string containing...]
[... not more than six 'c' and an equal...]
[... number of 'a' and 'b'.]

ORD
GRAM#1[1] S --> X S _repeat(K1=12) _goto(1,2)
GRAM#1[2] S --> lambda _goto(2,0)
----------
RND
_print
GRAM#2[1] <5-1> X --> C
GRAM#2[2] <1> X --> C _goto(3,1)
----------
RND
GRAM#3[1] X --> A _failed(4,0) _goto(3,2)
GRAM#3[2] X --> B _failed(3,3) _goto(3,1)
GRAM#3[3] _print ? --> ? B _goto(4,0) _print _stop
----------
SUB
GRAM#4[1] A --> a
GRAM#4[2] B --> b
GRAM#4[3] C --> c

Suppose that rule [3] of subgrammar #3 is displaced as follows:

----------
RND
GRAM#3[3] _print ? --> ? B _goto(4,0) _print _stop
GRAM#3[1] X --> A _failed(4,0) _goto(3,2)
GRAM#3[2] X --> B _failed(3,3) _goto(3,1)
----------

After recompiling subgrammar #3 will be:

----------
RND
GRAM#3[1] _print ? --> ? B _goto(4,0) _print _stop
GRAM#3[2] X --> A _failed(4,0) _goto(3,3)
GRAM#3[3] X --> B _failed(3,1) _goto(3,2)
----------

Let us now study "-gr.tryGOTO". The first subgrammar is an "ORD" grammar therefore rules are tried in order. Rule [1] will be applied 12 times, then rule [2] will be applied so that 'S' will be erased. (Since it is controlled by K1 the number of repetitions may be later modified by a MIDI device.) The workstring will then be displayed because there is a "_print" on top of subgrammar #2. Then rule [1] or [2] of subgrammar #2 will be applied, with a strong preference for [1] which has an initial weight <5>. Whenever rule [2] is applied BP2 will jump to rule [1] of subgrammar #3. If the rule is not candidate, the "_failed" procedure will force it to jump to subgrammar 4. Otherwise, rules [1] and [2] will be applied alternately. If rule [2] of subgrammar #3 is no longer candidate, rule [3] will be applied once (producing an extra 'b'), then "_goto(4,0)" will force a jump to subgrammar #4. The rest needs no explanation. It is easy to check that the numbers of 'a' and 'b' will eventually be equal.

Indeed, this is an extreme case in which there is so much procedural control that the grammar appears almost like a program (in any procedural language). Nevertheless, it demonstrates BP2's ability to combine procedural with declarative knowledge.


BP2 Reference Manual 8.	Procedures 9.	Csound argument mapping Title Page Index Contents