Compiled Rule Code


This page describes the compiled form of the different kinds of grammar rules. All rules start with a line number, typically zero when lines don't make sense. This enables the debugger to open and highlight the appropriate rule (and sometimes a line within the rule) during breakpoints or single-stepping.
 

Set Variable

Each line of a SetVar rule compiles to an evaluation of whatever goes into that variable, either a load from some named variable, or else a call to an evaluation rule like a table or conditional value. These are compiled (and executed) in the order they are in the grammar rule window.
 

Conditional Value

Each line of a Conditional Value rule compiles to an evaluation of that condition, which is tested and jumps to the next condition line if false, followed by the evaluation of the return value when the test is true. The return value is stored in a special "if res" variable for use by the calling rule. Values can be made up from literal constants (numbers or strings) and variables, combined with built-in arithmetic and other operators.
 

Syntax Line

At the front of a compiled syntax rule with multiple lines is a test of the selector variable to choose which line will be activated. Then for each line the code begins with any selected initialization (regardless of where it occurs in the source window line), then the remaining items in the order they occur in that source line. These items can be other rules (which get called to do their thing), or tree variables (which similarly get called to let the appropriate lexical rule(s) operate), or other variables which simply generate their text values to the output. The lines are compiled in reverse order, but that has no effect on execution, since only one line is activated on any given call.
 

Dot Connector

Tree node connection rules provide a general format for linking node shapes to syntax lines, and the subtrees to the items on each line. Like syntax lines, the connection groups are compiled in reverse order, with a selector test to choose one of them, except the special SetVar connection at the front (if present) is compiled at the front where it executes before choosing a connection group. If a tree list variable is one of the groups, then a reference to the current node is also stored in that variable, so it can be generated out of sequence, wherever the grammar places that variable in a syntax line.

The right side of each connection group is a list of the variables available to the selected syntax line, although it may not actually use all of them. Code is compiled for each subtree connection, to store a reference to it in the variable(s) it is linked to. Then the syntax line rule is called to arrange them as generated text.

The Thing connection rule also contains code to drive the pronoun generator, so that if the current noun # is associated with any of the defined pronouns, that pronoun is generated instead of everything else. This happens in the "Pron Gen" rule, which is built from the pronoun selector.
 

Lookup Table

Lookup Tables do not compile into separate rules, but use built-in table lookup operators to directly access the table value.
 

Lexical Rule

The source window lexical rule specification makes up only part of the compiled rule code. Some of the parameters can be variables not initialized in this category; these values are stored into the variables, wherever they are. The local category variables are just initialized with the values given them in the lexical rule, or else initialized as null. This prevents nested tree structures from interfering with each other's variables. Variables that are initialized in an L&N Connection table from this concept number are also given values here.

The node shape also selects an appropriate connection rule, if any, to call, and if there are variable connection rules that might be active, all of them are called (they simply do nothing and return if their variables are null).

Lexical rules do some of their operations the first time through a Thing or Proposition modified list (so to analyze what subtrees are there), other operations only the second time (when text is to be generated), and some on both passes.

There are special compiled "lexical" rules for the driver nodes, 0.3 Thing, 0.4 Proposition, and 0.8 Root. The root is always the first "node" compiled, before it starts on the selected tree node, so this rule also initializes a copy of all variables to null, except the selected node is as highlighted in the tree window. Thing and Proposition rules initialize a local pass# variable so that the subtrees can be scanned and processed differently during the analysis and generation passes.
 

Running

When you choose the "Translate" menu item, BibleTrans first compiles all the rules needed for this subtree, then activates lexical rule 0.8 (root), giving it the selected tree node. After initializing all the variables, the lexical rule for the selected node is called. If it is a Proposition or higher, that rule will initialize its category variables, then scan the subtrees setting up variables as specified in the linkage table(s), then go back and choose the syntax line selected for that verb or relation, which generates the output text. Subordinate propositions, as well as embedded Things, are treated in exactly the same way, except they are called in the order specified in the higher-level syntax line. This happens recursively until the whole tree has been translated. Note that role slots not connected to syntax variables, or variables not appearing on the syntax line, will not be visited during the generation pass and will not produce any text.

We have an extensive debugging facility for locating and fixing grammar errors...