1 --[[--------------------------------------------------------------------
3 Gazelle: a system for building fast, reusable parsers
7 Implementations of useful data structures that we use often.
8 Most of these are just useful interfaces around Lua's tables.
10 Copyright (c) 2007 Joshua Haberman. See LICENSE for details.
12 --------------------------------------------------------------------]]--
17 Queue
= {name
="Queue"}
18 function Queue
:new(init
)
19 local obj
= newobject(self
)
22 if init
then obj
:enqueue(init
) end
26 function Queue
:enqueue(val
)
27 self
.last
= self
.last
+ 1
31 function Queue
:dequeue()
32 if self
:isempty() then error("Tried to dequeue an empty queue") end
33 local val
= self
[self
.first
]
34 self
[self
.first
] = nil
35 self
.first
= self
.first
+ 1
39 function Queue
:isempty()
40 return self
.first
> self
.last
46 Stack
= {name
="Stack"}
47 function Stack
:new(init
)
48 local obj
= newobject(self
)
53 function Stack
:push(val
)
54 table.insert(self
.stack
, val
)
58 return table.remove(self
.stack
)
62 return self
.stack
[#self
.stack
]
65 function Stack
:isempty()
66 return #self
.stack
== 0
70 local new_stack
= newobject(Stack
)
71 new_stack
.stack
= table_shallow_copy(self
.stack
)
75 function Stack
:contains(elem
)
76 for e
in each(self
.stack
) do
84 function Stack
:to_array()
86 for i
, val
in ipairs(self
.stack
) do
87 table.insert(arr
, val
)
96 function Set
:new(init
)
97 local obj
= newobject(self
)
100 obj
:add_collection(init
)
105 function Set
:contains(x
)
106 return self
.elements
[x
] ~= nil
110 self
.elements
[x
] = true
113 function Set
:remove(x
)
114 self
.elements
[x
] = nil
117 function Set
:add_collection(arr
)
118 for elem
in each(arr
) do
124 return pairs(self
.elements
)
127 function Set
:to_array()
129 for elem
in self
:each() do
130 table.insert(arr
, elem
)
135 function Set
:isempty()
136 return self
:count() == 0
140 local new_set
= newobject(Set
)
141 new_set
.elements
= table_shallow_copy(self
.elements
)
147 for elem
in self
:each() do
153 function Set
:hash_key()
154 local arr
= self
:to_array()
156 arr
[i
] = tostring(arr
[i
])
161 str
= "" for elem
in each(arr
) do str
= str
.. elem
end
167 OrderedSet
= {name
="OrderedSet"}
168 function OrderedSet
:new(init
)
169 local obj
= newobject(self
)
170 obj
.element_offsets
= {}
173 for element
in each(init
) do
180 function OrderedSet
:add(elem
)
181 if not self
.element_offsets
[elem
] then
182 table.insert(self
.elements
, elem
)
183 self
.element_offsets
[elem
] = #self
.elements
187 function OrderedSet
:count()
188 return #self
.elements
191 function OrderedSet
:offset_of(elem
)
192 return self
.element_offsets
[elem
]
195 function OrderedSet
:element_at(pos
)
196 return self
.elements
[pos
]
199 function OrderedSet
:sort(sort_func
)
200 table.sort(self
.elements
, sort_func
)
201 self
.element_offsets
= {}
202 for i
, element
in ipairs(self
.elements
) do
203 self
.element_offsets
[element
] = i
207 function OrderedSet
:each()
211 if self
.elements
[i
] then
212 return self
.elements
[i
]
220 OrderedMap
= {name
="OrderedMap"}
221 function OrderedMap
:new()
222 local obj
= newobject(self
)
228 function OrderedMap
:add(key
, value
)
229 if not self
.key_offsets
[key
] then
230 table.insert(self
.elements
, {key
, value
})
231 self
.key_offsets
[key
] = #self
.elements
235 function OrderedMap
:get(key
)
236 return self
.elements
[self
.key_offsets
[key]]
[2]
239 function OrderedMap
:offset_of_key(elem
)
240 return self
.key_offsets
[elem
]
243 function OrderedMap
:count()
244 return #self
.elements
247 function OrderedMap
:each()
251 if self
.elements
[i
] then
252 return unpack(self
.elements
[i
])
260 -- The Range is *inclusive* at both ends.
261 Range
= {name
="Range"}
262 function Range
:new(low
, high
)
265 local obj
= newobject(self
)
271 function Range
.union(a
, b
)
272 if math
.max(a
.low
, b
.low
) <= (math
.min(a
.high
, b
.high
)+1) then
273 return Range
:new(math
.min(a
.low
, b
.low
), math
.max(a
.high
, b
.high
))
279 function Range
:contains(int
)
280 return (self
.low
<= int
) and (self
.high
>= int
)
283 function Range
:tostring(display_val_func
)
284 if self
.low
== self
.high
then
285 return display_val_func(self
.low
)
287 return display_val_func(self
.low
) .. "-" .. display_val_func(self
.high
)
294 -- None of the ranges may overlap.
295 IntSet
= {name
="IntSet"}
296 function IntSet
:new()
297 local obj
= newobject(self
)
303 function IntSet
:add(new_range
)
305 for range
in each(self
.list
) do
306 local union
= new_range
:union(range
)
310 table.insert(newlist
, range
)
314 table.insert(newlist
, new_range
)
318 function IntSet
:get_non_negated()
326 -- This is O(n^2) right now, and can probably
327 -- be made O(n lg n) with a little thought, but n's
328 -- are so small right now that I won't worry.
329 function IntSet
:add_intset(intset
)
330 for range
in each(intset
.list
) do
335 function IntSet
:contains(int
)
336 local obj
= self
:get_non_negated()
337 for range
in each(obj
.list
) do
338 if range
:contains(int
) then return true end
343 function IntSet
:sampleint()
344 local obj
= self
:get_non_negated()
346 if #obj
.list
== 0 then
349 return obj
.list
[1].low
353 function IntSet
:invert()
354 local new_intset
= IntSet
:new()
355 new_intset
.negated
= not self
.negated
357 table.sort(self
.list
, function (a
, b
) return a
.low
< b
.low
end)
360 for range
in each(self
.list
) do
361 if offset
<= range
.low
-1 then
362 new_intset
:add(Range
:new(offset
, range
.low
-1))
364 offset
= range
.high
+1
367 if offset
~= math
.huge
then
368 new_intset
:add(Range
:new(offset
, math
.huge
))
374 function IntSet
:each_range()
375 return each(self
:get_non_negated().list
)
378 function IntSet
:isunbounded()
379 for range
in each(self
.list
) do
380 if range
.high
== math
.huge
then
387 function IntSet
:tostring(display_val_func
)
389 if self
.negated
then str
= "^" end
391 table.sort(self
.list
, function (a
, b
) return a
.low
< b
.low
end)
393 for range
in each(self
.list
) do
400 str
= str
.. range
:tostring(display_val_func
)
406 function IntSet
:toasciistring()
407 local convert_func
= function (x
)
408 if x
== math
.huge
then
411 return string.format("\\%03o", x
)
413 return string.char(x
)
416 return self
:tostring(convert_func
)
419 function IntSet
:tointstring()
420 return self
:tostring(function (x
) return tostring(x
) end)
424 ShallowTable
= {name
="ShallowTable"}
425 function ShallowTable
:new(val
)
426 if val
== nil then return nil end
428 if not self
.cache
then
430 --setmetatable(self.cache, {__mode = "v"}) -- make values weak
435 for key
in pairs(val
) do table.insert(keys
, key
) end
437 for key
in each(keys
) do
438 if type(val
[key
]) == "table" and val
[key
].class
== fa
.NonTerm
then
439 str
= str
.. "|" .. key
.. ":NONTERM" .. tostring(val
[key
].name
)
441 str
= str
.. "|" .. key
.. ":" .. tostring(val
[key
])
445 if not self
.cache
[str
] then
446 self
.cache
[str
] = newobject(self
)
447 for k
,v
in pairs(val
) do
448 self
.cache
[str
][k
] = v
452 return self
.cache
[str
]