aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergei Golovan <devnull@localhost>2009-07-23 01:38:13 +0100
committerSergei Golovan <devnull@localhost>2009-07-23 01:38:13 +0100
commit194696adb0e98713037fd84c52da9e8d9238527d (patch)
tree176707a45c58a798890a34f36569d9e1894e4632
parentbd85a60673c565914473205ba7d32676b78e4ad3 (diff)
downloadprosody-194696adb0e98713037fd84c52da9e8d9238527d.tar.gz
prosody-194696adb0e98713037fd84c52da9e8d9238527d.zip
ejabberd2prosody, erlparse: Add support for parsing non-ASCII strings and binaries, and atoms enclosed in single quotes
-rw-r--r--tools/erlparse.lua79
1 files changed, 55 insertions, 24 deletions
diff --git a/tools/erlparse.lua b/tools/erlparse.lua
index 0bd4b3b8..f2d410a3 100644
--- a/tools/erlparse.lua
+++ b/tools/erlparse.lua
@@ -27,18 +27,18 @@ local function peek()
return last;
end
-local _A, _a, _Z, _z, _0, _9, __, _space = string.byte("AaZz09_ ", 1, 8);
-local function isAlpha(ch)
+local _A, _a, _Z, _z, _0, _9, __, _at, _space = string.byte("AaZz09@_ ", 1, 9);
+local function isLowerAlpha(ch)
ch = string.byte(ch) or 0;
- return (ch >= _A and ch <= _Z) or (ch >= _a and ch <= _z);
+ return (ch >= _a and ch <= _z);
end
local function isNumeric(ch)
ch = string.byte(ch) or 0;
return (ch >= _0 and ch <= _9);
end
-local function isVar(ch)
+local function isAtom(ch)
ch = string.byte(ch) or 0;
- return (ch >= _A and ch <= _Z) or (ch >= _a and ch <= _z) or (ch >= _0 and ch <= _9) or ch == __;
+ return (ch >= _A and ch <= _Z) or (ch >= _a and ch <= _z) or (ch >= _0 and ch <= _9) or ch == __ or ch == _at;
end
local function isSpace(ch)
ch = string.byte(ch) or "x";
@@ -57,24 +57,23 @@ local function readString()
str = str:gsub("\\.", {["\\b"]="\b", ["\\d"]="\d", ["\\e"]="\e", ["\\f"]="\f", ["\\n"]="\n", ["\\r"]="\r", ["\\s"]="\s", ["\\t"]="\t", ["\\v"]="\v", ["\\\""]="\"", ["\\'"]="'", ["\\\\"]="\\"});
return str;
end
-local function readSpecialString()
- read("<"); read("<"); -- read <<
- local str = "";
- if peek() == "\"" then
- str = readString();
- elseif peek() ~= ">" then
- error();
- end
- read(">"); read(">"); -- read >>
- return str;
-end
-local function readVar()
+local function readAtom1()
local var = read();
- while isVar(peek()) do
+ while isAtom(peek()) do
var = var..read();
end
return var;
end
+local function readAtom2()
+ local str = read("'");
+ local slash = nil;
+ while true do
+ local ch = read();
+ str = str..ch;
+ if ch == "'" and not slash then break; end
+ end
+ return str;
+end
local function readNumber()
local num = read();
while isNumeric(peek()) do
@@ -85,28 +84,60 @@ end
local readItem = nil;
local function readTuple()
local t = {};
- read(); -- read { or [
+ local s = ""; -- string representation
+ read(); -- read {, or [, or <
while true do
local item = readItem();
if not item then break; end
+ if type(item) ~= type(0) or item > 255 then
+ s = nil;
+ elseif s then
+ s = s..string.char(item);
+ end
table.insert(t, item);
end
- read(); -- read } or ]
- return t;
+ read(); -- read }, or ], or >
+ if s and s ~= "" then
+ return s
+ else
+ return t
+ end;
+end
+local function readBinary()
+ read("<"); -- read <
+ local t = readTuple();
+ read(">") -- read >
+ local ch = peek();
+ if type(t) == type("") then
+ -- binary is a list of integers
+ return t;
+ elseif type(t) == type({}) then
+ if t[1] then
+ -- binary contains string
+ return t[1];
+ else
+ -- binary is empty
+ return "";
+ end;
+ else
+ error();
+ end
end
readItem = function()
local ch = peek();
if ch == nil then return nil end
if ch == "{" or ch == "[" then
return readTuple();
- elseif isAlpha(ch) then
- return readVar();
+ elseif isLowerAlpha(ch) then
+ return readAtom1();
+ elseif ch == "'" then
+ return readAtom2();
elseif isNumeric(ch) then
return readNumber();
elseif ch == "\"" then
return readString();
elseif ch == "<" then
- return readSpecialString();
+ return readBinary();
elseif isSpace(ch) or ch == "," or ch == "|" then
read();
return readItem();