lexpos.pas 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. {
  2. Construct the position table, as well as first position sets.
  3. The position table stores symbol positions in regular expressions of
  4. the Lex grammar. It also allows to store the corresponding first
  5. and follow sets. By this means, the position table represents an eps-
  6. free nondeterministic automaton for the regular expressions of the
  7. Lex grammar (cf. Aho/Sethi/Ullman, Compilers : Principles, Techniques
  8. and Tools, 1986, Section 3.9, on constructing NFA's from regular
  9. expressions using position tables).
  10. Copyright (c) 1990-92 Albert Graef <[email protected]>
  11. Copyright (C) 1996 Berend de Boer <[email protected]>
  12. This program is free software; you can redistribute it and/or modify
  13. it under the terms of the GNU General Public License as published by
  14. the Free Software Foundation; either version 2 of the License, or
  15. (at your option) any later version.
  16. This program is distributed in the hope that it will be useful,
  17. but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. GNU General Public License for more details.
  20. You should have received a copy of the GNU General Public License
  21. along with this program; if not, write to the Free Software
  22. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23. $Revision: 1.2 $
  24. $Modtime: 96-08-01 6:30 $
  25. $History: LEXPOS.PAS $
  26. *
  27. * ***************** Version 2 *****************
  28. * User: Berend Date: 96-10-10 Time: 21:16
  29. * Updated in $/Lex and Yacc/tply
  30. * Updated for protected mode, windows and Delphi 1.X and 2.X.
  31. }
  32. unit LexPos;
  33. interface
  34. uses LexBase, LexTable;
  35. procedure addExpr(r : RegExpr; var FIRST : IntSet);
  36. (* Add the positions in r to the position table, and return the set of
  37. first positions of r. *)
  38. implementation
  39. procedure eval(r : RegExpr;
  40. var FIRST, LAST : IntSet;
  41. var nullable : Boolean);
  42. (* Evaluates the expression r, adding the positions in r to the position
  43. table and assigning FIRST, LAST and FOLLOW sets accordingly (cf. Aho/
  44. Sethi/Ullman, Compilers : Principles, Techniques and Tools, Section 3.9).
  45. Returns:
  46. - FIRST: the set of first positions in r
  47. - LAST: the set of last positions in r
  48. - nullable: denotes whether the r is nullable (i.e. is matched by the
  49. empty string). *)
  50. var
  51. c : Char;
  52. str : StrPtr;
  53. cc : CClassPtr;
  54. rule, pos : Integer;
  55. r1, r2 : RegExpr;
  56. FIRST1, LAST1 : IntSet;
  57. nullable1 : Boolean;
  58. i : integer;
  59. begin
  60. if is_epsExpr(r) then
  61. begin
  62. empty(FIRST); empty(LAST);
  63. nullable := true
  64. end
  65. else if is_markExpr(r, rule, pos) then
  66. begin
  67. addMarkPos(rule, pos);
  68. singleton(FIRST, n_pos); singleton(LAST, n_pos);
  69. nullable := true
  70. end
  71. else if is_charExpr(r, c) then
  72. begin
  73. addCharPos(c);
  74. singleton(FIRST, n_pos); singleton(LAST, n_pos);
  75. nullable := false
  76. end
  77. else if is_strExpr(r, str) then
  78. if length(str^)=0 then
  79. (* empty string is treated as empty expression *)
  80. begin
  81. empty(FIRST); empty(LAST);
  82. nullable := true
  83. end
  84. else
  85. begin
  86. addCharPos(str^[1]);
  87. singleton(FIRST, n_pos);
  88. for i := 2 to length(str^) do
  89. begin
  90. addCharPos(str^[i]);
  91. singleton(pos_table^[pred(n_pos)].follow_pos^, n_pos);
  92. end;
  93. singleton(LAST, n_pos);
  94. nullable := false
  95. end
  96. else if is_CClassExpr(r, cc) then
  97. begin
  98. addCClassPos(cc);
  99. singleton(FIRST, n_pos); singleton(LAST, n_pos);
  100. nullable := false
  101. end
  102. else if is_starExpr(r, r1) then
  103. begin
  104. eval(r1, FIRST, LAST, nullable);
  105. for i := 1 to size(LAST) do
  106. setunion(pos_table^[LAST[i]].follow_pos^, FIRST);
  107. nullable := true
  108. end
  109. else if is_plusExpr(r, r1) then
  110. begin
  111. eval(r1, FIRST, LAST, nullable);
  112. for i := 1 to size(LAST) do
  113. setunion(pos_table^[LAST[i]].follow_pos^, FIRST);
  114. end
  115. else if is_optExpr(r, r1) then
  116. begin
  117. eval(r1, FIRST, LAST, nullable);
  118. nullable := true
  119. end
  120. else if is_catExpr(r, r1, r2) then
  121. begin
  122. eval(r1, FIRST, LAST1, nullable);
  123. eval(r2, FIRST1, LAST, nullable1);
  124. for i := 1 to size(LAST1) do
  125. setunion(pos_table^[LAST1[i]].follow_pos^, FIRST1);
  126. if nullable then setunion(FIRST, FIRST1);
  127. if nullable1 then setunion(LAST, LAST1);
  128. nullable := nullable and nullable1
  129. end
  130. else if is_altExpr(r, r1, r2) then
  131. begin
  132. eval(r1, FIRST, LAST, nullable);
  133. eval(r2, FIRST1, LAST1, nullable1);
  134. setunion(FIRST, FIRST1);
  135. setunion(LAST, LAST1);
  136. nullable := nullable or nullable1
  137. end
  138. end(*eval*);
  139. procedure addExpr(r : RegExpr; var FIRST : IntSet);
  140. var LAST : IntSet;
  141. nullable : Boolean;
  142. begin
  143. eval(r, FIRST, LAST, nullable);
  144. end(*addExpr*);
  145. end(*LexPos*).