Software /
code /
prosody
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; |