2 -- Copyright (C) 2008 Matthew Wild
3 -- Copyright (C) 2008 Waqas Hussain
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
13 local function read(expected)
\r
16 ch = last; last = nil;
\r
17 else ch = file:read(1); end
\r
18 if expected and ch ~= expected then error("expected: "..expected.."; got: "..(ch or "nil")); end
\r
21 local function pushback(ch)
\r
22 if last then error(); end
\r
25 local function peek()
\r
26 if not last then last = read(); end
\r
30 local _A, _a, _Z, _z, _0, _9, __, _space = string.byte("AaZz09_ ", 1, 8);
\r
31 local function isAlpha(ch)
\r
32 ch = string.byte(ch) or 0;
\r
33 return (ch >= _A and ch <= _Z) or (ch >= _a and ch <= _z);
\r
35 local function isNumeric(ch)
\r
36 ch = string.byte(ch) or 0;
\r
37 return (ch >= _0 and ch <= _9);
\r
39 local function isVar(ch)
\r
40 ch = string.byte(ch) or 0;
\r
41 return (ch >= _A and ch <= _Z) or (ch >= _a and ch <= _z) or (ch >= _0 and ch <= _9) or ch == __;
\r
43 local function isSpace(ch)
\r
44 ch = string.byte(ch) or "x";
\r
45 return ch <= _space;
\r
48 local function readString()
\r
49 read("\""); -- skip quote
\r
54 if ch == "\"" and not slash then break; end
\r
57 str = str:gsub("\\.", {["\\b"]="\b", ["\\d"]="\d", ["\\e"]="\e", ["\\f"]="\f", ["\\n"]="\n", ["\\r"]="\r", ["\\s"]="\s", ["\\t"]="\t", ["\\v"]="\v", ["\\\""]="\"", ["\\'"]="'", ["\\\\"]="\\"});
\r
60 local function readSpecialString()
\r
61 read("<"); read("<"); -- read <<
\r
63 if peek() == "\"" then
\r
65 elseif peek() ~= ">" then
\r
68 read(">"); read(">"); -- read >>
\r
71 local function readVar()
\r
73 while isVar(peek()) do
\r
78 local function readNumber()
\r
80 while isNumeric(peek()) do
\r
83 return tonumber(num);
\r
85 local readItem = nil;
\r
86 local function readTuple()
\r
88 read(); -- read { or [
\r
90 local item = readItem();
\r
91 if not item then break; end
\r
92 table.insert(t, item);
\r
94 read(); -- read } or ]
\r
97 readItem = function()
\r
99 if ch == nil then return nil end
\r
100 if ch == "{" or ch == "[" then
\r
101 return readTuple();
\r
102 elseif isAlpha(ch) then
\r
104 elseif isNumeric(ch) then
\r
105 return readNumber();
\r
106 elseif ch == "\"" then
\r
107 return readString();
\r
108 elseif ch == "<" then
\r
109 return readSpecialString();
\r
110 elseif isSpace(ch) or ch == "," or ch == "|" then
\r
114 --print("Unknown char: "..ch);
\r
118 local function readChunk()
\r
119 local x = readItem();
\r
120 if x then read("."); end
\r
123 local function readFile(filename)
\r
124 file = io.open(filename);
\r
125 if not file then error("File not found: "..filename); os.exit(0); end
\r
127 local x = readChunk();
\r
128 if not x and peek() then error("Invalid char: "..peek()); end
\r
135 function parseFile(file)
\r
136 return readFile(file);
\r