void clean_grammar()

- finds illegal constructs in the document model

clean_grammar() finds undefined elements, undefined inclusions or exclusions, and unreferenced elements. If such an element is encountered, an error is reported.

void calc_empty()

- calculate empty status for all nodes

void calc_status()

- calculates Required or Optional status for all nodes

These functions are called from `generate.c'. calc_empty() calculates for each node of every element, whether the node is nullable or not. A node is nullable when the model group it represents, can be zero.

void may_be_empty(node, elem)

- calculates nullable value for node P_Node node; P_Element elem;

Calculates whether node is nullable or not. If it is, the nullable flag of node is set to `Yes', otherwise it is set to `No'.
This function traverses the complete grammar. If an element is encountered that is referenced but not defined, this element is stored uniquely in the group undefined_elements.

void find_undef(node, elem)

- finds undefined element P_Node node; P_Element elem;

void undef_elems()

- reports undefined elements, if any

The function find_undef() checks whether the element denoted by node, if node is of type GI, is defined in the document model. If not, the element-name is added to the group undefined_elements. undef_elems() finds all undefined elements by calls to the previous function for all nodes in the document tree. It also prints an error message for each undefined element.

void excl_incl_defined()

- reports undefined ex/inclusions, if any

This function visits all inclusions and exclusions of all elements to find whether the referenced elements exist. If a non-existing element is found, an error report is given.
Each element that occurs in an inclusion is added to the set of referenced elements, used. This set is used by the following functions.

void unreachable()

- finds all unreachable elements

void reach(node, elem)

- function which does the actual work for unreachable() P_Node node; P_Element elem;

void unreferenced()

- finds all unreferenced elements

unreachable() searches the complete grammar for unreachable elements. If such an element is found, an error is reported. It calls reach() for the content tree of the document element. reach() sets the done flag for each element of which it encounters a generic identifier. It also puts the element number in the set of referenced elements. Reach then calls itself for the element corresponding with the generic identifier. The done flag is used to prevent visiting an element more than once.
After the call to unreachable(), all elements should be in the set of reachable elements. This set is inspected by unreferenced(). If an element is not in the set it is reported.

Bool sons_are_nullable(node)

- checks whether the sons of node are nullable P_Node node;

void clear_nullable(node, elem)

- sets nullable value for node to Undecided P_Node node; P_Element elem;

sons_are_nullable() checks whether node is nullable because of it's children. clear_nullable() sets the value of the nullable flag of node to `Undecided'. It is called for each node of each element by solve_empty(), if changes to the grammar were made. The nullable status must then be calculated again.

void solve_empty()

- solve special case of empty productions

LLgen has problems with productions that produce empty that have repetition occurrence indicators (PLUS and REP). These productions give ambiguity conflicts in LL(1) grammars, but are allowed in the SGML document model. This function solves these conflicts by changing these productions. It first calls change_plus() and thereafter repeat_node().

void change_plus(node, elem)

- changes representation of groups P_Node node; P_Element elem;

void repeat_node(node, elem)

- change representation of REP nodes P_Node node; P_Element elem;

void rep_node(node)

- change representation of node P_Node node;

The function change_plus() converts nodes with a PLUS or REP occurrence indicator to their equivalent in LL(1) format. A node that can be empty and has a PLUS indicator is changed into a node with a REP indicator. A SEQ or AND group with a REP indicator, whose children can all be empty is changed into an OR group with a REP indicator.
The function repeat_node() converts each node which is an OR group with a REP occurrence indicator whose children can all be empty. For each such node rep_node() is called.
rep_node() changes the representation of node into a form which is LL(1). It calls itself recursively.

void convert_plus(node, elem)

- convert PLUS nodes to REP

s P_Node node; P_Element elem;

void convert_plusses_and_set_busy()

- convert PLUS nodes and sets busy flag


The function convert_plus() converts node to a REP node if it is a PLUS node. It also sets the busy flag of elem to FALSE. convert_plusses_and_set_busy() calls convert_plus() for every node in the document model.

void debug_empty(b)

- used for debugging purposes only Bool b;

The function sets a debug flag to the value of `b'. If the value of `b' is TRUE, all debug information listed in this file is printed, if the value is FALSE, no debug information is printed.

empty.c empty.h