a bit more progress on lua bindings
[philodendron.git] / sketches / regex_debug.lua
blobe9cf39a538e21d2a1a041b5d1c6ba3c85258e9a1
2 --dofile("sketches/pp.lua")
4 -- function NFA:dump_dot()
5 -- local str = "digraph untitled {\n"
6 -- local seen = {}
7 -- local queue = {self.start}
8 -- local next_statenum = 2
9 -- seen[self.start] = 1
10 -- while table.getn(queue) > 0 do
11 -- state = table.remove(queue)
12 -- for char,newstates in pairs(state) do
13 -- if newstates.class == NFAState then newstates = {newstates} end
14 --
15 -- for i,newstate in ipairs(newstates) do
16 --
17 -- -- if we haven't seen this state before, queue it up
18 -- if seen[newstate] == nil then
19 -- table.insert(queue, newstate)
20 -- seen[newstate] = next_statenum
21 -- next_statenum = next_statenum + 1
22 -- end
23 --
24 -- str = str .. string.format(' %d -> %d [label="%s"];\n', seen[state], seen[newstate], char)
25 -- end
26 -- end
27 -- end
28 -- str = str .. string.format(' %d [label="Start"]\n', seen[self.start])
29 -- str = str .. string.format(" %d [peripheries=2]\n", seen[self.final])
30 -- str = str .. "}"
31 -- return str
32 -- end
34 require "sketches/pp"
36 function fa.FA:__tostring()
37 -- local oldmt = getmetatable(self)
38 -- setmetatable(self, nil)
39 -- print("BTW my identity is " .. tostring(self))
40 -- setmetatable(self, oldmt)
41 local str = "digraph untitled {\n"
42 states = self:states():to_array()
43 --table.sort(states, function (a, b) return a.statenum < b.statenum end)
44 for i,state in ipairs(states) do
45 local label = ""
46 local peripheries = 1
47 if state == self.start then label = "Begin" end
48 if state == self.final or state.final then
49 if label ~= "" then label = label .. "/" end
50 if state.final then
51 if type(state.final) == "table" then
52 print(label)
53 print(serialize(state.final:to_array()))
54 label = label .. str_join(state.final:to_array(), "NEWLINE")
55 else
56 label = label .. state.final
57 end
58 else
59 label = label .. "Final"
60 end
61 peripheries = 2
62 end
63 if state.decisions then
64 for terminal, stack in pairs(state.decisions) do
65 label = label .. "NEWLINE" .. terminal .. "->"
66 if stack == Ignore then
67 label = label .. "IGNORE"
68 else
69 for stack_member in each(stack) do
70 if type(stack_member) == "table" and stack_member.class == fa.NonTerm then
71 label = label .. stack_member.name
72 elseif type(stack_member) == "table" and stack_member.class == Ignore then
73 label = label .. "IGNORE"
74 else
75 label = label .. serialize(stack_member)
76 end
77 label = label .. ", "
78 end
79 end
80 end
81 end
82 label = label:gsub("[\"\\]", "\\%1")
83 label = label:gsub("NEWLINE", "\\n")
84 str = str .. string.format(' "%s" [label="%s", peripheries=%d];\n', tostring(state), label, peripheries)
85 for char, tostate, attributes in state:transitions() do
86 local print_char
87 if char == fa.e then
88 print_char = "ep"
89 -- elseif char == "(" then
90 -- print_char = "start capture"
91 -- elseif char == ")" then
92 -- print_char = "end capture"
93 elseif type(char) == "string" then
94 print_char = char
95 elseif type(char) == 'table' and char.class == IntSet then
96 if char:isunbounded() then char = char:invert() end
97 print_char = char:toasciistring()
98 elseif type(char) == 'table' and char.class == fa.NonTerm then
99 print_char = char.name
100 elseif type(char) == 'table' and char.class == fa.IntFA then
101 print_char = "A regex!"
102 else
103 print(serialize(char, 3, true))
104 print_char = string.char(char)
106 if attributes and false then
107 for k,v in pairs(attributes) do
108 if k ~= "class" then
109 local s = tostring(v)
110 if type(v) == "table" then
111 s = v.name
113 print_char = print_char .. string.format("NEWLINE%s: %s", k, s)
117 print_char = print_char:gsub("[\"\\]", "\\%1")
118 print_char = print_char:gsub("NEWLINE", "\\n")
119 str = str .. string.format(' "%s" -> "%s" [label="%s"];\n', tostring(state), tostring(tostate), print_char)
122 str = str .. "}"
123 return str
126 fa.IntFA.__tostring = fa.FA.__tostring
127 fa.RTN.__tostring = fa.FA.__tostring