Son aktivite 1747970795

capitalex's Avatar capitalex bu gisti düzenledi 1747970795. Düzenlemeye git

1 file changed, 230 insertions

nova-parser.lua(dosya oluşturuldu)

@@ -0,0 +1,230 @@
1 + local pprint = require "pprint"
2 + local None = {}
3 + local whitespace = {
4 + [' '] = true,
5 + ['\n'] = true,
6 + ['\r'] = true,
7 + ['\t'] = true,
8 + }
9 + local yield, wrap = coroutine.yield, coroutine.wrap
10 +
11 + local function gen(t)
12 + return wrap(function()
13 + for i, v in ipairs(t) do
14 + yield(i, v)
15 + end
16 + end)
17 + end
18 + local function iter(f)
19 + return function(arg)
20 + return wrap(function () f(arg) end)
21 + end
22 + end
23 +
24 + local function chars(string)
25 + local cs = {}
26 + for char in string:gmatch(".") do
27 + table.insert(cs, char)
28 + end
29 + return cs
30 + end
31 +
32 + local function copy(t)
33 + local t_copy = {}
34 + for k, v in pairs(t) do
35 + t_copy[k] = v
36 + end
37 + return t_copy
38 + end
39 +
40 + local function append(a, b)
41 + local appended = {}
42 + for _, v in ipairs(a) do
43 + table.insert(appended, v)
44 + end
45 + for _, v in ipairs(b) do
46 + table.insert(appended, v)
47 + end
48 + return appended
49 + end
50 +
51 + local function clear(t)
52 + for k, v in pairs(t) do
53 + t[k] = nil
54 + end
55 + end
56 +
57 + local function insert(t, what)
58 + table.insert(t, what)
59 + return t
60 + end
61 +
62 + local parser_container = iter(function(string)
63 + local left = {}
64 + local right = {}
65 + local target = left
66 + local characters = gen(insert(chars(string), None))
67 + local delimiter = None
68 +
69 + for _, character in characters do
70 + if not whitespace[character] then
71 + delimiter = character
72 + break
73 + end
74 +
75 + end
76 + if delimiter == None then
77 + return None
78 + end
79 +
80 + for _, character in characters do
81 + if character == delimiter or character == None then
82 + if target == left then
83 + target = right
84 + else
85 + target = left
86 + yield(copy(left), copy(right))
87 + clear(left) clear(right)
88 + end
89 + else
90 + table.insert(target, character)
91 + end
92 + end
93 + end)
94 +
95 + local parse_labels = iter(function(rules)
96 + local left = {}
97 + local right = {}
98 + local pair = {{}, {}}
99 + local target = left
100 + local delimiter = None
101 + for condition, result in rules do
102 + for _, side in ipairs({condition, result}) do
103 + local characters = gen(insert(side, None))
104 + local state = "find delimiter"
105 + for _, character in characters do
106 + if character == None then
107 + local label = table.concat(pair[1]):match "^%s*(.-)%s*$"
108 + local pattern = table.concat(pair[2]):match "^%s*(.-)%s*$"
109 + if not (#label == 0 and #pattern == 0) then
110 + table.insert(target, {label, pattern})
111 + end
112 + clear(pair[1]) clear(pair[2])
113 + break
114 + elseif state == "find delimiter" then
115 + if not whitespace[character] then
116 + delimiter = character
117 + state = "parse label"
118 + end
119 + elseif state == "parse label" then
120 + if character == delimiter then
121 + state = "parse pattern"
122 + else
123 + table.insert(pair[1], character)
124 + end
125 + elseif state == "parse pattern" then
126 + if character == delimiter or character == None then
127 + state = "parse label"
128 + local label = table.concat(pair[1]):match "^%s*(.-)%s*$"
129 + local pattern = table.concat(pair[2]):match "^%s*(.-)%s*$"
130 + if not (#label == 0 and #pattern == 0) then
131 + table.insert(target, {label, pattern})
132 + end
133 + clear(pair[1]) clear(pair[2])
134 + else
135 + table.insert(pair[2], character)
136 + end
137 + end
138 + end
139 + if target == left then
140 + target = right
141 + else
142 + target = left
143 + end
144 + end
145 + yield(copy(left), copy(right))
146 + clear(left) clear(right)
147 + end
148 + end)
149 +
150 + local parse_patterns = iter(function(rules)
151 + for conditions, results in rules do
152 + local left = {}
153 + local right = {}
154 + local preserves = {}
155 + for _, condition in ipairs(conditions) do
156 + local label, pattern = condition[1], condition[2]
157 + local preserve = false
158 + if pattern:match("%?$") then
159 + pattern = pattern:sub(1, -2)
160 + preserve = true
161 + end
162 + if pattern:match("^[\"'](.*)[\"']$") then
163 + for i, character in ipairs(chars(pattern:match("^[\"'](.*)[\"\']$"))) do
164 + table.insert(left, {label, {tostring(string.byte(character))}})
165 + if preserves then
166 + table.insert(right, {label, {tostring(string.byte(character))}})
167 + end
168 + end
169 + elseif pattern:match("^%((.*)%)$") then
170 + for token in pattern:match("^%((.*)%)$"):gmatch("%S+") do
171 + table.insert(left, {label, {token}})
172 + if preserve then
173 + table.insert(right, {label, {token}})
174 + end
175 + end
176 + elseif pattern:find("^%.") then
177 + -- TODO
178 + else
179 + local words = {}
180 + for word in pattern:gmatch("%S+") do
181 + table.insert(words, word)
182 + end
183 + table.insert(left, {label, words})
184 + if preserve then
185 + table.insert(preserves, {label, words})
186 + end
187 + end
188 + end
189 +
190 + for _, result in ipairs(results) do
191 + local label, pattern = result[1], result[2]
192 +
193 + if pattern:match("^[\"'](.*)[\"']$") then
194 + for i, character in ipairs(chars(pattern:match("^[\"'](.*)[\"\']$"))) do
195 + table.insert(right, {label, {tostring(string.byte(character))}})
196 + end
197 + elseif pattern:match("^%((.*)%)$") then
198 + for token in pattern:match("^%((.*)%)$"):gmatch("%S+") do
199 + table.insert(right, {label, {token}})
200 + end
201 + elseif pattern:find("^%.") then
202 + -- TODO
203 + else
204 + local words = {}
205 + for word in pattern:gmatch("%S+") do
206 + table.insert(words, word)
207 + end
208 + table.insert(right, {label, words})
209 + end
210 + end
211 +
212 + yield(copy(left), append(right, preserves))
213 + clear(left) clear(right) clear(preserves)
214 + end
215 + end)
216 +
217 + local file = io.open("main.nv", "r")
218 + for left, right in parse_patterns(parse_labels(parser_container(file:read("*a")))) do
219 + io.write("|")
220 + local left_pattern = {}
221 + for _, pattern in ipairs(left) do
222 + table.insert(left_pattern, ":" .. pattern[1] .. ": " .. table.concat(pattern[2], " "))
223 + end
224 + io.write(table.concat(left_pattern, " "))
225 + io.write("|\n")
226 + for _, pattern in ipairs(right) do
227 + print("", ":" .. pattern[1] .. ": " .. table.concat(pattern[2], " "))
228 + end
229 + io.write("\n")
230 + end
Daha yeni Daha eski