Comparison

tools/erlparse.lua @ 2948:1ac5ef6ce1a0

Merge 0.7->trunk
author Matthew Wild <mwild1@gmail.com>
date Thu, 25 Mar 2010 19:40:38 +0000
parent 2947:ff7f6668b34f
child 5079:2ab99e239d45
comparison
equal deleted inserted replaced
2944:855c0eb80600 2948:1ac5ef6ce1a0
4 -- 4 --
5 -- This project is MIT/X11 licensed. Please see the 5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information. 6 -- COPYING file in the source package for more information.
7 -- 7 --
8 8
9 9 local string_byte, string_char = string.byte, string.char;
10 local t_concat, t_insert = table.concat, table.insert;
11 local type, tonumber, tostring = type, tonumber, tostring;
10 12
11 local file = nil; 13 local file = nil;
12 local last = nil; 14 local last = nil;
15 local line = 1;
13 local function read(expected) 16 local function read(expected)
14 local ch; 17 local ch;
15 if last then 18 if last then
16 ch = last; last = nil; 19 ch = last; last = nil;
17 else ch = file:read(1); end 20 else
18 if expected and ch ~= expected then error("expected: "..expected.."; got: "..(ch or "nil")); end 21 ch = file:read(1);
22 if ch == "\n" then line = line + 1; end
23 end
24 if expected and ch ~= expected then error("expected: "..expected.."; got: "..(ch or "nil").." on line "..line); end
19 return ch; 25 return ch;
20 end 26 end
21 local function pushback(ch) 27 local function pushback(ch)
22 if last then error(); end 28 if last then error(); end
23 last = ch; 29 last = ch;
25 local function peek() 31 local function peek()
26 if not last then last = read(); end 32 if not last then last = read(); end
27 return last; 33 return last;
28 end 34 end
29 35
30 local _A, _a, _Z, _z, _0, _9, __, _at, _space = string.byte("AaZz09@_ ", 1, 9); 36 local _A, _a, _Z, _z, _0, _9, __, _at, _space, _minus = string_byte("AaZz09@_ -", 1, 10);
31 local function isLowerAlpha(ch) 37 local function isLowerAlpha(ch)
32 ch = string.byte(ch) or 0; 38 ch = string_byte(ch) or 0;
33 return (ch >= _a and ch <= _z); 39 return (ch >= _a and ch <= _z);
34 end 40 end
35 local function isNumeric(ch) 41 local function isNumeric(ch)
36 ch = string.byte(ch) or 0; 42 ch = string_byte(ch) or 0;
37 return (ch >= _0 and ch <= _9); 43 return (ch >= _0 and ch <= _9) or ch == _minus;
38 end 44 end
39 local function isAtom(ch) 45 local function isAtom(ch)
40 ch = string.byte(ch) or 0; 46 ch = string_byte(ch) or 0;
41 return (ch >= _A and ch <= _Z) or (ch >= _a and ch <= _z) or (ch >= _0 and ch <= _9) or ch == __ or ch == _at; 47 return (ch >= _A and ch <= _Z) or (ch >= _a and ch <= _z) or (ch >= _0 and ch <= _9) or ch == __ or ch == _at;
42 end 48 end
43 local function isSpace(ch) 49 local function isSpace(ch)
44 ch = string.byte(ch) or "x"; 50 ch = string_byte(ch) or "x";
45 return ch <= _space; 51 return ch <= _space;
46 end 52 end
47 53
48 local escapes = {["\\b"]="\b", ["\\d"]="\d", ["\\e"]="\e", ["\\f"]="\f", ["\\n"]="\n", ["\\r"]="\r", ["\\s"]="\s", ["\\t"]="\t", ["\\v"]="\v", ["\\\""]="\"", ["\\'"]="'", ["\\\\"]="\\"}; 54 local escapes = {["\\b"]="\b", ["\\d"]="\d", ["\\e"]="\e", ["\\f"]="\f", ["\\n"]="\n", ["\\r"]="\r", ["\\s"]="\s", ["\\t"]="\t", ["\\v"]="\v", ["\\\""]="\"", ["\\'"]="'", ["\\\\"]="\\"};
49 local function readString() 55 local function readString()
50 read("\""); -- skip quote 56 read("\""); -- skip quote
51 local slash = nil; 57 local slash = nil;
52 local str = ""; 58 local str = {};
53 while true do 59 while true do
54 local ch = read(); 60 local ch = read();
55 if slash then 61 if slash then
56 slash = slash..ch; 62 slash = slash..ch;
57 if not escapes[slash] then error("Unknown escape sequence: "..slash); end 63 if not escapes[slash] then error("Unknown escape sequence: "..slash); end
58 str = str..escapes[slash]; 64 str[#str+1] = escapes[slash];
59 slash = nil; 65 slash = nil;
60 elseif ch == "\"" then 66 elseif ch == "\"" then
61 break; 67 break;
62 elseif ch == "\\" then 68 elseif ch == "\\" then
63 slash = ch; 69 slash = ch;
64 else 70 else
65 str = str..ch; 71 str[#str+1] = ch;
66 end 72 end
67 end 73 end
68 return str; 74 return t_concat(str);
69 end 75 end
70 local function readAtom1() 76 local function readAtom1()
71 local var = read(); 77 local var = { read() };
72 while isAtom(peek()) do 78 while isAtom(peek()) do
73 var = var..read(); 79 var[#var+1] = read();
74 end 80 end
75 return var; 81 return t_concat(var);
76 end 82 end
77 local function readAtom2() 83 local function readAtom2()
78 local str = read("'"); 84 local str = { read("'") };
79 local slash = nil; 85 local slash = nil;
80 while true do 86 while true do
81 local ch = read(); 87 local ch = read();
82 str = str..ch; 88 str[#str+1] = ch;
83 if ch == "'" and not slash then break; end 89 if ch == "'" and not slash then break; end
84 end 90 end
85 return str; 91 return t_concat(str);
86 end 92 end
87 local function readNumber() 93 local function readNumber()
88 local num = read(); 94 local num = { read() };
89 while isNumeric(peek()) do 95 while isNumeric(peek()) do
90 num = num..read(); 96 num[#num+1] = read();
91 end 97 end
92 return tonumber(num); 98 return tonumber(t_concat(num));
93 end 99 end
94 local readItem = nil; 100 local readItem = nil;
95 local function readTuple() 101 local function readTuple()
96 local t = {}; 102 local t = {};
97 local s = ""; -- string representation 103 local s = {}; -- string representation
98 read(); -- read {, or [, or < 104 read(); -- read {, or [, or <
99 while true do 105 while true do
100 local item = readItem(); 106 local item = readItem();
101 if not item then break; end 107 if not item then break; end
102 if type(item) ~= type(0) or item > 255 then 108 if type(item) ~= "number" or item > 255 then
103 s = nil; 109 s = nil;
104 elseif s then 110 elseif s then
105 s = s..string.char(item); 111 s[#s+1] = string_char(item);
106 end 112 end
107 table.insert(t, item); 113 t_insert(t, item);
108 end 114 end
109 read(); -- read }, or ], or > 115 read(); -- read }, or ], or >
110 if s and s ~= "" then 116 if s and #s > 0 then
111 return s 117 return t_concat(s)
112 else 118 else
113 return t 119 return t
114 end; 120 end;
115 end 121 end
116 local function readBinary() 122 local function readBinary()
117 read("<"); -- read < 123 read("<"); -- read <
124 -- Discard PIDs
125 if isNumeric(peek()) then
126 while peek() ~= ">" do read(); end
127 read(">");
128 return {};
129 end
118 local t = readTuple(); 130 local t = readTuple();
119 read(">") -- read > 131 read(">") -- read >
120 local ch = peek(); 132 local ch = peek();
121 if type(t) == type("") then 133 if type(t) == "string" then
122 -- binary is a list of integers 134 -- binary is a list of integers
123 return t; 135 return t;
124 elseif type(t) == type({}) then 136 elseif type(t) == "table" then
125 if t[1] then 137 if t[1] then
126 -- binary contains string 138 -- binary contains string
127 return t[1]; 139 return t[1];
128 else 140 else
129 -- binary is empty 141 -- binary is empty