src
prepare.cc
Go to the documentation of this file.
1 #include "src/util/c99_stdint.h"
2 #include <string.h>
3 #include <map>
4 
5 #include "src/codegen/bitmap.h"
6 #include "src/codegen/go.h"
7 #include "src/globals.h"
8 #include "src/ir/adfa/action.h"
9 #include "src/ir/adfa/adfa.h"
11 #include "src/ir/rule_rank.h"
12 #include "src/util/allocate.h"
13 
14 namespace re2c {
15 
16 void DFA::split(State *s)
17 {
18  State *move = new State;
19  addState(move, s);
20  move->action.set_move ();
21  move->rule = s->rule;
22  move->fill = s->fill;
23  move->go = s->go;
24  s->rule = NULL;
25  s->go.nSpans = 1;
26  s->go.span = allocate<Span> (1);
27  s->go.span[0].ub = ubChar;
28  s->go.span[0].to = move;
29 }
30 
31 static uint32_t merge(Span *x0, State *fg, State *bg)
32 {
33  Span *x = x0, *f = fg->go.span, *b = bg->go.span;
34  uint32_t nf = fg->go.nSpans, nb = bg->go.nSpans;
35  State *prev = NULL, *to;
36  // NB: we assume both spans are for same range
37 
38  for (;;)
39  {
40  if (f->ub == b->ub)
41  {
42  to = f->to == b->to ? bg : f->to;
43 
44  if (to == prev)
45  {
46  --x;
47  }
48  else
49  {
50  x->to = prev = to;
51  }
52 
53  x->ub = f->ub;
54  ++x;
55  ++f;
56  --nf;
57  ++b;
58  --nb;
59 
60  if (nf == 0 && nb == 0)
61  {
62  return static_cast<uint32_t> (x - x0);
63  }
64  }
65 
66  while (f->ub < b->ub)
67  {
68  to = f->to == b->to ? bg : f->to;
69 
70  if (to == prev)
71  {
72  --x;
73  }
74  else
75  {
76  x->to = prev = to;
77  }
78 
79  x->ub = f->ub;
80  ++x;
81  ++f;
82  --nf;
83  }
84 
85  while (b->ub < f->ub)
86  {
87  to = b->to == f->to ? bg : f->to;
88 
89  if (to == prev)
90  {
91  --x;
92  }
93  else
94  {
95  x->to = prev = to;
96  }
97 
98  x->ub = b->ub;
99  ++x;
100  ++b;
101  --nb;
102  }
103  }
104 }
105 
106 void DFA::findBaseState()
107 {
108  Span *span = allocate<Span> (ubChar - lbChar);
109 
110  for (State *s = head; s; s = s->next)
111  {
112  if (s->fill == 0)
113  {
114  for (uint32_t i = 0; i < s->go.nSpans; ++i)
115  {
116  State *to = s->go.span[i].to;
117 
118  if (to->isBase)
119  {
120  to = to->go.span[0].to;
121  uint32_t nSpans = merge(span, s, to);
122 
123  if (nSpans < s->go.nSpans)
124  {
125  operator delete (s->go.span);
126  s->go.nSpans = nSpans;
127  s->go.span = allocate<Span> (nSpans);
128  memcpy(s->go.span, span, nSpans*sizeof(Span));
129  }
130 
131  break;
132  }
133  }
134  }
135  }
136 
137  operator delete (span);
138 }
139 
141 {
142  bUsedYYBitmap = false;
143 
144  // create rule states
145  std::map<rule_rank_t, State *> rules;
146  for (State * s = head; s; s = s->next)
147  {
148  if (s->rule)
149  {
150  if (rules.find (s->rule->rank) == rules.end ())
151  {
152  State *n = new State;
153  n->action.set_rule (s->rule);
154  rules[s->rule->rank] = n;
155  addState(n, s);
156  }
157  for (uint32_t i = 0; i < s->go.nSpans; ++i)
158  {
159  if (!s->go.span[i].to)
160  {
161  s->go.span[i].to = rules[s->rule->rank];
162  }
163  }
164  }
165  }
166 
167  // create default state (if needed)
168  State * default_state = NULL;
169  for (State * s = head; s; s = s->next)
170  {
171  for (uint32_t i = 0; i < s->go.nSpans; ++i)
172  {
173  if (!s->go.span[i].to)
174  {
175  if (!default_state)
176  {
177  default_state = new State;
178  addState(default_state, s);
179  }
180  s->go.span[i].to = default_state;
181  }
182  }
183  }
184 
185  // find backup states and create accept state (if needed)
186  if (default_state)
187  {
188  for (State * s = head; s; s = s->next)
189  {
190  if (s->rule)
191  {
192  for (uint32_t i = 0; i < s->go.nSpans; ++i)
193  {
194  if (!s->go.span[i].to->rule && s->go.span[i].to->action.type != Action::RULE)
195  {
196  const uint32_t accept = static_cast<uint32_t> (accepts.find_or_add (rules[s->rule->rank]));
197  s->action.set_save (accept);
198  }
199  }
200  }
201  }
202  default_state->action.set_accept (&accepts);
203  }
204 
205  // split ``base'' states into two parts
206  for (State * s = head; s; s = s->next)
207  {
208  s->isBase = false;
209 
210  if (s->fill != 0)
211  {
212  for (uint32_t i = 0; i < s->go.nSpans; ++i)
213  {
214  if (s->go.span[i].to == s)
215  {
216  s->isBase = true;
217  split(s);
218 
219  if (opts->bFlag)
220  {
221  BitMap::find(&s->next->go, s);
222  }
223 
224  s = s->next;
225  break;
226  }
227  }
228  }
229  }
230 
231  // find ``base'' state, if possible
232  findBaseState();
233 
234  for (State * s = head; s; s = s->next)
235  {
236  s->go.init (s);
237  }
238 }
239 
241 {
242  // calculate 'YYMAXFILL'
243  max_fill = 0;
244  for (State * s = head; s; s = s->next)
245  {
246  if (max_fill < s->fill)
247  {
248  max_fill = s->fill;
249  }
250  }
251 
252  // determine if 'YYMARKER' or 'YYBACKUP'/'YYRESTORE' pair is used
253  need_backup = accepts.size () > 0;
254 
255  // determine if 'YYCTXMARKER' or 'YYBACKUPCTX'/'YYRESTORECTX' pair is used
256  for (State * s = head; s; s = s->next)
257  {
258  if (s->isPreCtxt)
259  {
260  need_backupctx = true;
261  }
262  }
263 
264  // determine if 'yyaccept' variable is used
265  need_accept = accepts.size () > 1;
266 }
267 
268 } // namespace re2c
bool bFlag
Definition: opt.h:118
size_t max_fill
Definition: adfa.h:69
void set_rule(const RuleOp *const rule)
Definition: action.h:82
uint32_t nSpans
Definition: go.h:174
void set_save(uint32_t save)
Definition: action.h:65
void calc_stats()
Definition: prepare.cc:240
uint32_t ub
Definition: go.h:21
static uint32_t merge(Span *x0, State *fg, State *bg)
Definition: prepare.cc:31
State * to
Definition: go.h:22
bool bUsedYYBitmap
Definition: main.cc:16
uint32_t lbChar
Definition: adfa.h:63
Action action
Definition: adfa.h:33
bool need_backup
Definition: adfa.h:70
bool need_backupctx
Definition: adfa.h:71
uint32_t ubChar
Definition: adfa.h:64
void set_accept(const accept_t *accepts)
Definition: action.h:76
State * head
Definition: adfa.h:66
Opt opts
Definition: opt.cc:7
void prepare()
Definition: prepare.cc:140
static const BitMap * find(const Go *, const State *)
Definition: bitmap.cc:30
size_t size() const
Definition: uniq_vector.h:21
Go go
Definition: adfa.h:32
Span * span
Definition: go.h:175
size_t find_or_add(const value_t &v)
Definition: uniq_vector.h:29
Definition: bitmap.cc:10
Definition: go.h:19
bool need_accept
Definition: adfa.h:72
State * next
Definition: adfa.h:27