Comparison

tools/erlparse.lua @ 482:b86082df0bc0

ejabberd db dump importer for Prosody
author Waqas Hussain <waqas20@gmail.com>
date Sat, 29 Nov 2008 23:59:27 +0500
child 489:237cddb1a785
comparison
equal deleted inserted replaced
478:3abf90751a8f 482:b86082df0bc0
1
2 local file = nil;
3 local last = nil;
4 local function read(expected)
5 local ch;
6 if last then
7 ch = last; last = nil;
8 else ch = file:read(1); end
9 if expected and ch ~= expected then error("expected: "..expected.."; got: "..(ch or "nil")); end
10 return ch;
11 end
12 local function pushback(ch)
13 if last then error(); end
14 last = ch;
15 end
16 local function peek()
17 if not last then last = read(); end
18 return last;
19 end
20
21 local _A, _a, _Z, _z, _0, _9, __, _space = string.byte("AaZz09_ ", 1, 8);
22 local function isAlpha(ch)
23 ch = string.byte(ch) or 0;
24 return (ch >= _A and ch <= _Z) or (ch >= _a and ch <= _z);
25 end
26 local function isNumeric(ch)
27 ch = string.byte(ch) or 0;
28 return (ch >= _0 and ch <= _9);
29 end
30 local function isVar(ch)
31 ch = string.byte(ch) or 0;
32 return (ch >= _A and ch <= _Z) or (ch >= _a and ch <= _z) or (ch >= _0 and ch <= _9) or ch == __;
33 end
34 local function isSpace(ch)
35 ch = string.byte(ch) or "x";
36 return ch <= _space;
37 end
38
39 local function readString()
40 read("\""); -- skip quote
41 local slash = nil;
42 local str = "";
43 while true do
44 local ch = read();
45 if ch == "\"" and not slash then break; end
46 str = str..ch;
47 end
48 str = str:gsub("\\.", {["\\b"]="\b", ["\\d"]="\d", ["\\e"]="\e", ["\\f"]="\f", ["\\n"]="\n", ["\\r"]="\r", ["\\s"]="\s", ["\\t"]="\t", ["\\v"]="\v", ["\\\""]="\"", ["\\'"]="'", ["\\\\"]="\\"});
49 return str;
50 end
51 local function readSpecialString()
52 read("<"); read("<"); -- read <<
53 local str = "";
54 if peek() == "\"" then
55 local str = readString();
56 elseif peek() ~= ">" then
57 error();
58 end
59 read(">"); read(">"); -- read >>
60 return str;
61 end
62 local function readVar()
63 local var = read();
64 while isVar(peek()) do
65 var = var..read();
66 end
67 return var;
68 end
69 local function readNumber()
70 local num = read();
71 while isNumeric(peek()) do
72 num = num..read();
73 end
74 return tonumber(num);
75 end
76 local readItem = nil;
77 local function readTuple()
78 local t = {};
79 read(); -- read { or [
80 while true do
81 local item = readItem();
82 if not item then break; end
83 table.insert(t, item);
84 end
85 read(); -- read } or ]
86 return t;
87 end
88 readItem = function()
89 local ch = peek();
90 if ch == nil then return nil end
91 if ch == "{" or ch == "[" then
92 return readTuple();
93 elseif isAlpha(ch) then
94 return readVar();
95 elseif isNumeric(ch) then
96 return readNumber();
97 elseif ch == "\"" then
98 return readString();
99 elseif ch == "<" then
100 return readSpecialString();
101 elseif isSpace(ch) or ch == "," then
102 read();
103 return readItem();
104 else
105 --print("Unknown char: "..ch);
106 return nil;
107 end
108 end
109 local function readChunk()
110 local x = readItem();
111 if x then read("."); end
112 return x;
113 end
114 local function readFile(filename)
115 file = io.open(filename);
116 if not file then error("File not found: "..filename); os.exit(0); end
117 return function()
118 local x = readChunk();
119 if not x and peek() then error("Invalid char: "..peek()); end
120 return x;
121 end;
122 end
123
124 module "erlparse"
125
126 function parseFile(file)
127 return readFile(file);
128 end
129
130 return _M;