Software /
code /
prosody
File
tools/erlparse.lua @ 1431:9fe9ba693f4a
util.stanza: Serializer optimizations, and nicer output for empty elements
author | Waqas Hussain <waqas20@gmail.com> |
---|---|
date | Sat, 27 Jun 2009 08:38:52 +0500 |
parent | 896:2c0b9e3c11c3 |
child | 1523:841d61be198f |
line wrap: on
line source
-- Prosody IM v0.4 -- Copyright (C) 2008-2009 Matthew Wild -- Copyright (C) 2008-2009 Waqas Hussain -- -- This project is MIT/X11 licensed. Please see the -- COPYING file in the source package for more information. -- local file = nil; local last = nil; local function read(expected) local ch; if last then ch = last; last = nil; else ch = file:read(1); end if expected and ch ~= expected then error("expected: "..expected.."; got: "..(ch or "nil")); end return ch; end local function pushback(ch) if last then error(); end last = ch; end local function peek() if not last then last = read(); end return last; end local _A, _a, _Z, _z, _0, _9, __, _space = string.byte("AaZz09_ ", 1, 8); local function isAlpha(ch) ch = string.byte(ch) or 0; return (ch >= _A and ch <= _Z) or (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) 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 == __; end local function isSpace(ch) ch = string.byte(ch) or "x"; return ch <= _space; end local function readString() read("\""); -- skip quote local slash = nil; local str = ""; while true do local ch = read(); if ch == "\"" and not slash then break; end str = str..ch; end 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 var = read(); while isVar(peek()) do var = var..read(); end return var; end local function readNumber() local num = read(); while isNumeric(peek()) do num = num..read(); end return tonumber(num); end local readItem = nil; local function readTuple() local t = {}; read(); -- read { or [ while true do local item = readItem(); if not item then break; end table.insert(t, item); end read(); -- read } or ] return t; 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 isNumeric(ch) then return readNumber(); elseif ch == "\"" then return readString(); elseif ch == "<" then return readSpecialString(); elseif isSpace(ch) or ch == "," or ch == "|" then read(); return readItem(); else --print("Unknown char: "..ch); return nil; end end local function readChunk() local x = readItem(); if x then read("."); end return x; end local function readFile(filename) file = io.open(filename); if not file then error("File not found: "..filename); os.exit(0); end return function() local x = readChunk(); if not x and peek() then error("Invalid char: "..peek()); end return x; end; end module "erlparse" function parseFile(file) return readFile(file); end return _M;