csv.lua

1
local lpeg = require "lpeg"
2
local setmetatable, tonumber = 
3
	setmetatable, tonumber;
4
local s_char = string.char;
5
 
6
module("csv");
7
 
8
local delim = lpeg.P",";
9
 
10
local char_escape = lpeg.R"az" + lpeg.S"\\\r\n" + delim;
11
local numeric_escape = (lpeg.R"09"^1)^-3;
12
local escape = (lpeg.P"\\" * (char_escape + numeric_escape));
13
 
14
local quoted_value = lpeg.P"\"" * ((1-lpeg.P"\"")^0) * lpeg.P"\"";
15
local value = quoted_value + (escape + (1-delim))^0;
16
 
17
local escape_map = setmetatable({
18
	t = "\t", b = "\b", f = "\f";
19
	n = "\n", r = "\r", v = "\v"; },
20
		{ __index = function (_, n)
21
			if tonumber(n) then
22
				print"n"
23
				return s_char(tonumber(n));
24
			else
25
				return n;
26
			end
27
		end
28
	});
29
 
30
function read_record(line, value_callback)
31
	local fieldpos = 0;
32
	local callback = function (v)
33
			return value_callback(v:gsub("\\(.)", escape_map));
34
		end;
35
	repeat
36
		fieldpos = lpeg.match(value / callback, line, fieldpos+1);
37
	until fieldpos >= #line;
38
end
39
 
40
return _M;