|
1 /* GRAPHITE2 LICENSING |
|
2 |
|
3 Copyright 2013, SIL International |
|
4 All rights reserved. |
|
5 |
|
6 This library is free software; you can redistribute it and/or modify |
|
7 it under the terms of the GNU Lesser General Public License as published |
|
8 by the Free Software Foundation; either version 2.1 of License, or |
|
9 (at your option) any later version. |
|
10 |
|
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 GNU |
|
14 Lesser General Public License for more details. |
|
15 |
|
16 You should also have received a copy of the GNU Lesser General Public |
|
17 License along with this library in the file named "LICENSE". |
|
18 If not, write to the Free Software Foundation, 51 Franklin Street, |
|
19 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the |
|
20 internet at http://www.fsf.org/licenses/lgpl.html. |
|
21 |
|
22 Alternatively, the contents of this file may be used under the terms of the |
|
23 Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public |
|
24 License, as published by the Free Software Foundation, either version 2 |
|
25 of the License or (at your option) any later version. |
|
26 */ |
|
27 #pragma once |
|
28 |
|
29 namespace graphite2 |
|
30 { |
|
31 |
|
32 class BracketPair |
|
33 { |
|
34 public: |
|
35 BracketPair(uint16 g, Slot *s, uint8 b, BracketPair *p, BracketPair *l) : _open(s), _close(0), _parent(p), _next(0), _prev(l), _gid(g), _mask(0), _before(b) {}; |
|
36 uint16 gid() const { return _gid; } |
|
37 Slot *open() const { return _open; } |
|
38 Slot *close() const { return _close; } |
|
39 uint8 mask() const { return _mask; } |
|
40 int8 before() const { return _before; } |
|
41 BracketPair *parent() const { return _parent; } |
|
42 void close(Slot *s) { _close = s; } |
|
43 BracketPair *next() const { return _next; } |
|
44 BracketPair *prev() const { return _prev; } |
|
45 void next(BracketPair *n) { _next = n; } |
|
46 void orin(uint8 m) { _mask |= m; } |
|
47 private: |
|
48 Slot * _open; // Slot of opening paren |
|
49 Slot * _close; // Slot of closing paren |
|
50 BracketPair * _parent; // pair this pair is in or NULL |
|
51 BracketPair * _next; // next pair along the string |
|
52 BracketPair * _prev; // pair that closed last before we opened |
|
53 uint16 _gid; // gid of closing paren |
|
54 uint8 _mask; // bitmap (2 bits) of directions within the pair |
|
55 int8 _before; // most recent strong type (L, R, OPP, CPP) |
|
56 }; |
|
57 |
|
58 class BracketPairStack |
|
59 { |
|
60 public: |
|
61 BracketPairStack(int s) : _stack(grzeroalloc<BracketPair>(s)), _ip(_stack - 1), _top(0), _last(0), _lastclose(0), _size(s) {} |
|
62 ~BracketPairStack() { free(_stack); } |
|
63 |
|
64 public: |
|
65 BracketPair *scan(uint16 gid); |
|
66 void close(BracketPair *tos, Slot *s); |
|
67 BracketPair *push(uint16 gid, Slot *pos, uint8 before, int prevopen); |
|
68 void orin(uint8 mask); |
|
69 void clear() { _ip = _stack - 1; _top = 0; _last = 0; _lastclose = 0; } |
|
70 int size() const { return _size; } |
|
71 BracketPair *start() const { return _stack; } |
|
72 |
|
73 CLASS_NEW_DELETE |
|
74 |
|
75 private: |
|
76 |
|
77 BracketPair *_stack; // start of storage |
|
78 BracketPair *_ip; // where to add the next pair |
|
79 BracketPair *_top; // current parent |
|
80 BracketPair *_last; // end of next() chain |
|
81 BracketPair *_lastclose; // last pair to close |
|
82 int _size; // capacity |
|
83 }; |
|
84 |
|
85 inline BracketPair *BracketPairStack::scan(uint16 gid) |
|
86 { |
|
87 BracketPair *res = _top; |
|
88 while (res >= _stack) |
|
89 { |
|
90 if (res->gid() == gid) |
|
91 return res; |
|
92 res = res->parent(); |
|
93 } |
|
94 return 0; |
|
95 } |
|
96 |
|
97 inline void BracketPairStack::close(BracketPair *tos, Slot *s) |
|
98 { |
|
99 for ( ; _last && _last != tos && !_last->close(); _last = _last->parent()) |
|
100 { } |
|
101 tos->close(s); |
|
102 _last->next(NULL); |
|
103 _lastclose = tos; |
|
104 _top = tos->parent(); |
|
105 } |
|
106 |
|
107 inline BracketPair *BracketPairStack::push(uint16 gid, Slot *pos, uint8 before, int prevopen) |
|
108 { |
|
109 if (++_ip - _stack < _size && _stack) |
|
110 { |
|
111 ::new (_ip) BracketPair(gid, pos, before, _top, prevopen ? _last : _lastclose); |
|
112 if (_last) _last->next(_ip); |
|
113 _last = _ip; |
|
114 } |
|
115 _top = _ip; |
|
116 return _ip; |
|
117 } |
|
118 |
|
119 inline void BracketPairStack::orin(uint8 mask) |
|
120 { |
|
121 BracketPair *t = _top; |
|
122 for ( ; t; t = t->parent()) |
|
123 t->orin(mask); |
|
124 } |
|
125 |
|
126 } |