@q file: structures.w@> @q% Copyright Dave Bone 1998 - 2015@> @q% /*@> @q% This Source Code Form is subject to the terms of the Mozilla Public@> @q% License, v. 2.0. If a copy of the MPL was not distributed with this@> @q% file, You can obtain one at http://mozilla.org/MPL/2.0/.@> @q% */@> @** Structure and Rule Recycling Optimization.\fbreak To improve performance due to the birth-run-delete cyle of grammar rules on the parse stack, the following optimization is used: Stable of rule's symbol when created for recycling purposes. 2 concerns must be attended to:\fbreak \ptindent{1) the parse stack needs the Rule\_s\_reuse\_entry ptr of the current rule} \ptindent{2) due to recursion, the recycle table per rule is sequentially searched} Please see {\bf |rules_use_cnt|} grammar for a thorough discussion on how the rulle count is calculated for recycling. \fbreak \fbreak Initially an array per specific grammar rule was generated. It had speed but would have been kludgey to handle overflow on the number of rules for reuse. Here is a note on the array [1] definition. The Sun compiler doesn't like the [] definition being open-ended. So I fake it. Each rule will be specifically defined within its namespace. But, \Yacco2{} is a general library of routines. So my search uses the entry count to protect against a table overrun situation. \fbreak \fbreak Take 2:\fbreak Though this approach is speedy when dealing with left recursion only, it did not have a saftey valve when the count was wrong: eg right recursion or flawed algorithm on determining rule recursion count. So i changed it to a stack/double list combo. The ``in use'' list acts like a stack but its lhs/rhs reduction pair leaves the lhs as the top item placed in the ``in use'' queue before its rhs items are removed from the ``in use'' list. Why? The lhs rule comes from the reduction when the rhs's symbols are still sitting on the parse stack. That is, lhs rule is created first, placed in the ``in use'' list before the rhs's symbols are popped from the parse stack. If the popped symbol is a rule it gets recycled and placed back into the ``for use'' stack for another round of reuse. @+= struct Per_rule_s_reuse_table; struct reuse_rule_list; struct reuse_rule_list{ reuse_rule_list():younger_(0),older_(0),reuse_rule_entry_(0),per_rule_tbl_ptr_(0){}; reuse_rule_list* younger_; reuse_rule_list* older_; Rule_s_reuse_entry* reuse_rule_entry_; Per_rule_s_reuse_table* per_rule_tbl_ptr_; }; struct Rule_s_reuse_entry{ reuse_rule_list its_linked_list_; CAbs_lr1_sym* rule_; // new rule symbol for recycling Rule_s_reuse_entry():rule_(0){}; ~Rule_s_reuse_entry(){ if(rule_ == 0) return; delete rule_; }; }; struct Per_rule_s_reuse_table{ reuse_rule_list* in_use_list_; reuse_rule_list* for_use_list_; Per_rule_s_reuse_table():in_use_list_(0),for_use_list_(0){}; }; struct Fsm_rules_reuse_table{// grammar's stable of rules int no_rules_entries_; Per_rule_s_reuse_table* per_rule_s_table_[1]; };