1 //////////////////////////////////////////////////////////////////////////////
4 // ADLib, Prop and their related set of tools and documentation are in the
5 // public domain. The author(s) of this software reserve no copyrights on
6 // the source code and any code generated using the tools. You are encouraged
7 // to use ADLib and Prop to develop software, in both academic and commercial
8 // settings, and are free to incorporate any part of ADLib and Prop into
11 // Although you are under no obligation to do so, we strongly recommend that
12 // you give away all software developed using our tools.
14 // We also ask that credit be given to us when ADLib and/or Prop are used in
15 // your programs, and that this notice be preserved intact in all the source
18 // This software is still under development and we welcome any suggestions
19 // and help from the users.
23 //////////////////////////////////////////////////////////////////////////////
25 #include <AD/automata/follow.h>
27 //////////////////////////////////////////////////////////////////////////////
29 //////////////////////////////////////////////////////////////////////////////
30 FollowSet::FollowSet(const Grammar
& g
, Mem
& m
) : FirstSet(g
,m
)
31 { // int min = G.min_terminal();
32 int max
= G
.max_non_terminal();
33 int set_size
= G
.max_terminal() + 1;
35 ///////////////////////////////////////////////////////////////////////////
36 // Allocate memory for the follow set
37 ///////////////////////////////////////////////////////////////////////////
38 follow_set
= (BitSet
**)m
.c_alloc(sizeof(BitSet
*) * (max
+ 1));
39 { for (int i
= G
.min_non_terminal(); i
<= G
.max_non_terminal(); i
++) {
40 follow_set
[i
] = new (m
, set_size
) BitSet
;
44 ///////////////////////////////////////////////////////////////////////////
45 // Compute the follow set.
46 // Iterate until fixed point is reached
47 ///////////////////////////////////////////////////////////////////////////
51 ////////////////////////////////////////////////////////////////////////
52 // For each production A -> xyz.
53 // For each non-terminal X in A -> a X b
54 // (1) new follow(X) = follow(X) union first(b)
55 // (2) new follow(X) = follow(X) union follow(A) if nullable(b)
56 ////////////////////////////////////////////////////////////////////////
57 for (int i
= g
.size() - 1; i
>= 0; i
--) {
59 register Production P
= g
[i
];
60 Symbol A
= P
[0]; // A -> a X b
61 for (P
++; (X
= *P
++) != Grammar::END_PRODUCTION
; ) {
62 if (g
.isNonTerminal(X
) &&
63 first(*follow_set
[X
],P
,changed
) &&
64 X
!= A
&& // a slight optimization
65 follow_set
[X
]->Union_if_changed(*follow_set
[A
]))
72 //////////////////////////////////////////////////////////////////////////////
73 // Destructor. Do nothing since memory is handled by the memory pool
74 //////////////////////////////////////////////////////////////////////////////
75 FollowSet::~FollowSet() {}