The parser and scanner append symbols to the "active" table. The active symbol table and associated binary are defined by:
DDS_TABLE *dds_symbol; DDS_BIN *dds_compile;The symbol table for DDS prime types is shared by binaries. The initial table entry is identified by "dds_prime_block". Nested within it are prime types and error recovery symbols. The prime symbol table and special entries are defined by:
DDS_TABLE dds_prime_table; DDS_BLOCK *dds_prime_block; DDS_BLOCK *dds_error_block; DDS_TYPE *dds_error_type; DDS_OBJECT *dds_error_object; DDS_MEMBER *dds_error_member; DDS_EXPR *dds_error_expr; DDS_EXPR *dds_error_thread;"dds_prime" is an array of DDS_PRIME structs (attributes). The attributes include pointers into dds_prime_table. "dds_prime_tag" STACK provides shared API symbol tags. Each binary stream also has a private "symbol" table. The initial table entry is identified by "block_old". Nested within it are implicit symbols from the old format. "block_new" is nested within block_old, which provides the default symbols and outer scope for the new format. The block_old and block_new scopes are never closed. "dds_block" identifies the current/active compiler scope. "sym_tag" STACK provides private API symbol tags. The BIN struct for each binary stream contains:
DDS_TABLE symbol; DDS_BLOCK *block_old; DDS_BLOCK *block_new; DDS_STACK sym_tag;This is the logical flow when looking for named "objects" while compiling formats:
If the object is defined within the current scope, use it ! else the scanner calls ddsYYdepend and attempts to create it. If DDS_YACC_CREATE is set (write create mode), If "fmt:-:-.name" is defined, call ddsYYparser recursively, which should create a "name" object within the current scope. If "name" object is created, use it ! else if object "name" is defined within the block_old scope, use it ! else if "fmt:-.name is defined, re-open the block_old scope and call ddsYYparser. This "should" create the "name" object. If "name" object is created, use it ! The block_old scope is closed before continuing. else fail ! else (read existing mode), If "fmt:-.name is defined, call ddsYYparser recursively, which should create a "name" object within the current scope. If "name" object is created, use it ! else if "fmt:-:-.name" is defined, call ddsYYparser recursively, which should create a "name" object within the current scope. If "name" object is created, use it ! else fail !
:.......: : : : | | | | +------ --------------> BLOCK <--------+------<------+ | | | hash/name | | | outer hash <---- chain | | +----------<-------- older | | newer ---------->---------+ | +---------<------------ block/flag | | type <--------- type | | first -->---+ | | last ------ ----->--+ | | | | | : : : : | +-->------------------> OBJECT <-------+ | | | | hash/name | | | | local hash <---- chain | | | | 0 <-------- older | | | | newer -->---+ | | +--- -----------<------------ block/flag | | | | | type <--------- type | | | | +--<--+ ptr | | | | | stack <-------- reloc | | | | | value <-------- track | | | : : : : : | +-->- ---------------> MEMBER <-------+ | | | | | hash/name | | | | | local hash <---- chain | | | | +----------<-------- older | | | | newer -->---+ | | +--- -----------<------------ block/flag | | | | | type <--------- type | | | | | offset | | | | | adjust | | | | +--<--+ value <-------- value_b | | | : : : : : | +-->- ---------------> TYPE <---------+ | | | | | hash/name | | | | | 0 <---- chain | | | | +----------<-------- older | | | | newer -->---+ | | +--- -----------<------------ block/flag | | | | | type <--------- type | | | | | ptype | | | | | align | | | | | prec/count | | | | | stroke | | | | +--<--+ c/a/trail | | | : : : : : | +-->- ---------------> EXPR <---------+ | | | | | hash/name | | | | | local hash <---- chain | | | | +----------<-------- older | | | | newer -->---+ | | +--- -----------<------------ block/flag | | | | | type <------- type | | | | | ptr | | | | | stack <-------- reloc | | | | | opcode | | | | | expr <--------- next | | | | | value <-------- args... | | | : :.....: : : :