yacclr0.pas 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. {
  2. LR(0) set construction. For an explanation of this algorithm, see
  3. Aho/Sethi/Ullman, "Compilers : Principles, Techniques and Tools,"
  4. 1986, Section 4.7.
  5. Copyright (c) 1990-92 Albert Graef <[email protected]>
  6. Copyright (C) 1996 Berend de Boer <[email protected]>
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. $Revision: 1.2 $
  19. $Modtime: 96-07-31 14:09 $
  20. $History: YACCLR0.PAS $
  21. *
  22. * ***************** Version 2 *****************
  23. * User: Berend Date: 96-10-10 Time: 21:16
  24. * Updated in $/Lex and Yacc/tply
  25. * Updated for protected mode, windows and Delphi 1.X and 2.X.
  26. }
  27. unit YaccLR0;
  28. interface
  29. procedure LR0Set;
  30. (* constructs the LR(0) state set, shift and goto transitions and
  31. corresponding kernel items *)
  32. implementation
  33. uses YaccBase, YaccTabl;
  34. (* This implementation is based on the algorithm given in Aho/Sethi/Ullman,
  35. 1986, Section 4.7. *)
  36. procedure get_syms ( var item_set : ItemSet; var sym_set : IntSet );
  37. (* get the symbols for which there are transitions in item_set *)
  38. var i : Integer;
  39. begin
  40. with item_set do
  41. begin
  42. empty(sym_set);
  43. for i := 1 to n_items do
  44. with item[i], rule_table^[rule_no]^ do
  45. if pos_no<=rhs_len then
  46. include(sym_set, rhs_sym[pos_no]);
  47. end;
  48. end(*get_syms*);
  49. function make_state ( var item_set : ItemSet; sym : Integer ) : Integer;
  50. (* construct a new state for the transitions in item_set on symbol sym;
  51. returns: the new state number *)
  52. var i : Integer;
  53. begin
  54. with item_set do
  55. begin
  56. (* add the new state: *)
  57. new_state;
  58. for i := 1 to n_items do
  59. with item[i], rule_table^[rule_no]^ do
  60. if (pos_no<=rhs_len) and (rhs_sym[pos_no]=sym) then
  61. add_item(rule_no, pos_no+1);
  62. make_state := add_state;
  63. end;
  64. end(*make_state*);
  65. procedure add_next_links;
  66. (* add links to successor items for kernel items in the active state *)
  67. var k, i : Integer;
  68. begin
  69. with state_table^[act_state] do
  70. for k := trans_lo to trans_hi do
  71. with trans_table^[k] do
  72. for i := item_lo to item_hi do
  73. with item_table^[i], rule_table^[rule_no]^ do
  74. if (pos_no<=rhs_len) and (rhs_sym[pos_no]=sym) then
  75. next := find_item(next_state, rule_no, pos_no+1 );
  76. end(*add_next_links*);
  77. procedure LR0Set;
  78. var act_items : ItemSet;
  79. act_syms : IntSet;
  80. i : Integer;
  81. begin
  82. (* initialize state 0: *)
  83. new_state;
  84. add_item(1, 1); (* augmented start production *)
  85. act_state := add_state;
  86. (* build the state table: *)
  87. repeat
  88. (* compute the closure of the current state: *)
  89. get_item_set(act_state, act_items);
  90. closure(act_items);
  91. (* sort items: *)
  92. sort_item_set(act_items);
  93. (* determine symbols used in shift and goto transitions: *)
  94. get_syms(act_items, act_syms);
  95. (* add transitions: *)
  96. start_trans;
  97. for i := 1 to size(act_syms) do
  98. if act_syms[i]=0 then
  99. (* accept action *)
  100. add_trans(0, 0)
  101. else
  102. (* shift/goto action *)
  103. add_trans(act_syms[i], make_state(act_items, act_syms[i]));
  104. end_trans;
  105. (* add next links to kernel items: *)
  106. add_next_links;
  107. (* switch to next state: *)
  108. inc(act_state);
  109. until act_state=n_states;
  110. end(*LR0Set*);
  111. end(*YaccLR0*).