diff options
Diffstat (limited to '')
-rw-r--r-- | LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/llex_mk4.lua | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/llex_mk4.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/llex_mk4.lua new file mode 100644 index 0000000..42559a3 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/llex_mk4.lua | |||
@@ -0,0 +1,285 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | llex.lua | ||
4 | Lua 5 lexical analyzer in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * a line-oriented version of mk3 | ||
18 | -- | ||
19 | -- local lex_init = require("llex.lua") | ||
20 | -- local llex = lex_init(z, source) | ||
21 | -- llex:chunkid() | ||
22 | -- * returns formatted name of chunk id | ||
23 | -- llex:errorline(s, line) | ||
24 | -- * throws an error with a formatted message | ||
25 | -- llex:lex() | ||
26 | -- * returns next lexical element (token, seminfo) | ||
27 | -- llex.ln | ||
28 | -- * line number | ||
29 | ----------------------------------------------------------------------]] | ||
30 | |||
31 | return | ||
32 | function(zio, source) | ||
33 | -------------------------------------------------------------------- | ||
34 | -- initialize variables | ||
35 | -- * I is the upvalue, i is the local version for space/efficiency | ||
36 | -------------------------------------------------------------------- | ||
37 | local string = string | ||
38 | local find, sub = string.find, string.sub | ||
39 | local EOF = "<eof>" | ||
40 | local luaX = { ln = 0 } | ||
41 | local I, z | ||
42 | -------------------------------------------------------------------- | ||
43 | -- initialize keyword list | ||
44 | -------------------------------------------------------------------- | ||
45 | local kw = {} | ||
46 | for v in string.gfind([[ | ||
47 | and break do else elseif end false for function if in | ||
48 | local nil not or repeat return then true until while]], "%S+") do | ||
49 | kw[v] = true | ||
50 | end | ||
51 | -------------------------------------------------------------------- | ||
52 | -- returns a chunk name or id | ||
53 | -------------------------------------------------------------------- | ||
54 | function luaX:chunkid() | ||
55 | if find(source, "^[=@]") then | ||
56 | return sub(source, 2) -- remove first char | ||
57 | end | ||
58 | return "[string]" | ||
59 | end | ||
60 | -------------------------------------------------------------------- | ||
61 | -- formats error message and throws error | ||
62 | -- * a simplified version, does not report what token was responsible | ||
63 | -------------------------------------------------------------------- | ||
64 | function luaX:errorline(s, line) | ||
65 | error(string.format("%s:%d: %s", self:chunkid(), line or self.ln, s)) | ||
66 | end | ||
67 | -------------------------------------------------------------------- | ||
68 | -- move on to next line | ||
69 | -------------------------------------------------------------------- | ||
70 | local function nextln() | ||
71 | local luaX = luaX | ||
72 | luaX.ln = luaX.ln + 1 | ||
73 | z = zio:getln() | ||
74 | I = 1 | ||
75 | end | ||
76 | ---------------------------------------------------------------------- | ||
77 | -- reads a long string or long comment | ||
78 | ---------------------------------------------------------------------- | ||
79 | local function read_long(i, is_str) | ||
80 | local luaX = luaX | ||
81 | local string = string | ||
82 | local buff = "" | ||
83 | local cont = 1 | ||
84 | if sub(z, i, i) == "\n" then | ||
85 | nextln(); i = 1 | ||
86 | end | ||
87 | while true do | ||
88 | local p, q, r = find(z, "([\n%[%]])", i) -- (long range) | ||
89 | if not p then | ||
90 | luaX:errorline(is_str and "unfinished long string" or | ||
91 | "unfinished long comment") | ||
92 | end | ||
93 | buff = buff..string.sub(z, i, p - 1) -- add a portion | ||
94 | i = p + 1 | ||
95 | if sub(z, i, i) == r then -- only [[ or ]] | ||
96 | i = i + 1 | ||
97 | if r == "[" then | ||
98 | cont = cont + 1 | ||
99 | else-- r == "]" then | ||
100 | if cont == 1 then break end -- last ]] found | ||
101 | cont = cont - 1 | ||
102 | end | ||
103 | buff = buff..r..r | ||
104 | else -- [ or ] or \n | ||
105 | buff = buff..r | ||
106 | if r == "\n" then | ||
107 | nextln(); i = 1 | ||
108 | end | ||
109 | end | ||
110 | end--while | ||
111 | I = i | ||
112 | return buff | ||
113 | end | ||
114 | ---------------------------------------------------------------------- | ||
115 | -- reads a string | ||
116 | ---------------------------------------------------------------------- | ||
117 | local function read_string(i, del) | ||
118 | local luaX = luaX | ||
119 | local string = string | ||
120 | local buff = "" | ||
121 | while true do | ||
122 | local p, q, r = find(z, "([\n\\\"\'])", i) -- (long range) | ||
123 | if p then | ||
124 | if r == "\n" then | ||
125 | luaX:errorline("unfinished string") | ||
126 | end | ||
127 | buff = buff..sub(z, i, p - 1) -- normal portions | ||
128 | i = p | ||
129 | if r == "\\" then -- handle escapes | ||
130 | i = i + 1 | ||
131 | r = sub(z, i, i) | ||
132 | if r == "" then break end -- (error) | ||
133 | p = find("\nabfnrtv", r, 1, 1) | ||
134 | ------------------------------------------------------ | ||
135 | if p then -- special escapes | ||
136 | r = sub("\n\a\b\f\n\r\t\v", p, p) | ||
137 | if p == 1 then | ||
138 | nextln(); i = 1 | ||
139 | else | ||
140 | i = i + 1 | ||
141 | end | ||
142 | ------------------------------------------------------ | ||
143 | elseif find(r, "%D") then -- other non-digits | ||
144 | i = i + 1 | ||
145 | ------------------------------------------------------ | ||
146 | else -- \xxx sequence | ||
147 | local p, q, s = find(z, "^(%d%d?%d?)", i) | ||
148 | i = q + 1 | ||
149 | if s + 1 > 256 then -- UCHAR_MAX | ||
150 | luaX:errorline("escape sequence too large") | ||
151 | end | ||
152 | r = string.char(s) | ||
153 | ------------------------------------------------------ | ||
154 | end--if p | ||
155 | else | ||
156 | i = i + 1 | ||
157 | if r == del then | ||
158 | I = i | ||
159 | return buff -- ending delimiter | ||
160 | end | ||
161 | end--if r | ||
162 | buff = buff..r | ||
163 | else | ||
164 | break -- (error) | ||
165 | end--if p | ||
166 | end--while | ||
167 | luaX:errorline("unfinished string") | ||
168 | end | ||
169 | ---------------------------------------------------------------------- | ||
170 | -- main lexer function | ||
171 | ---------------------------------------------------------------------- | ||
172 | function luaX:lex() | ||
173 | local string = string | ||
174 | local find, len = find, string.len | ||
175 | while true do--outer | ||
176 | local i = I | ||
177 | -- inner loop allows break to be used to nicely section tests | ||
178 | while true do--inner | ||
179 | ---------------------------------------------------------------- | ||
180 | local p, _, r = find(z, "^([_%a][_%w]*)", i) | ||
181 | if p then | ||
182 | I = i + len(r) | ||
183 | if kw[r] then return r end -- keyword | ||
184 | return "<name>", r -- identifier | ||
185 | end | ||
186 | ---------------------------------------------------------------- | ||
187 | local p, q, r = find(z, "^(%.?)%d", i) | ||
188 | if p then -- numeral | ||
189 | if r == "." then i = i + 1 end | ||
190 | local _, n, r, s = find(z, "^%d*(%.?%.?)%d*([eE]?)", i) | ||
191 | q = n | ||
192 | i = q + 1 | ||
193 | if len(r) == 2 then | ||
194 | self:errorline("ambiguous syntax (dots follows digits)") | ||
195 | end | ||
196 | if len(s) == 1 then -- optional exponent | ||
197 | local _, n = find(z, "^[%+%-]?%d*", i) -- optional sign | ||
198 | q = n | ||
199 | i = q + 1 | ||
200 | end | ||
201 | r = tonumber(sub(z, p, q)) | ||
202 | I = i | ||
203 | if not r then self:errorline("malformed number") end | ||
204 | return "<number>", r | ||
205 | end | ||
206 | ---------------------------------------------------------------- | ||
207 | local p, q, r = find(z, "^(%s)[ \t]*", i) | ||
208 | if p then | ||
209 | if r == "\n" then -- newline | ||
210 | nextln() | ||
211 | else | ||
212 | I = q + 1 -- whitespace | ||
213 | end | ||
214 | break -- (continue) | ||
215 | end | ||
216 | ---------------------------------------------------------------- | ||
217 | local p, _, r = find(z, "^(%p)", i) -- symbols/punctuation | ||
218 | if p then | ||
219 | local q = find("-[\"\'.=<>~", r, 1, 1) | ||
220 | if q then -- further processing for more complex symbols | ||
221 | ---------------------------------------------------- | ||
222 | if q <= 2 then | ||
223 | if q == 1 then -- minus | ||
224 | if find(z, "^%-%-", i) then | ||
225 | i = i + 2 | ||
226 | if find(z, "^%[%[", i) then -- long comment | ||
227 | read_long(i + 2) | ||
228 | else -- short comment | ||
229 | if find(z, "\n", i) then | ||
230 | nextln() | ||
231 | else | ||
232 | I = len(z) + 1 | ||
233 | end | ||
234 | end | ||
235 | break -- (continue) | ||
236 | end | ||
237 | -- (fall through for "-") | ||
238 | elseif q == 2 then -- [ or long string | ||
239 | if find(z, "^%[%[", i) then | ||
240 | return "<string>", read_long(i + 2, true) | ||
241 | end | ||
242 | -- (fall through for "[") | ||
243 | end | ||
244 | ---------------------------------------------------- | ||
245 | elseif q <= 5 then | ||
246 | if q < 5 then -- strings | ||
247 | return "<string>", read_string(i + 1, r) | ||
248 | end | ||
249 | local _, _, s = find(z, "^(%.%.?%.?)", i) -- dots | ||
250 | r = s | ||
251 | -- (fall through) | ||
252 | ---------------------------------------------------- | ||
253 | else -- relational/logic | ||
254 | local _, _, s = find(z, "^(%p=?)", i) | ||
255 | r = s | ||
256 | -- (fall through) | ||
257 | end | ||
258 | end | ||
259 | I = i + len(r); return r -- for other symbols, fall through | ||
260 | end | ||
261 | ---------------------------------------------------------------- | ||
262 | local r = sub(z, i, i) | ||
263 | if r ~= "" then | ||
264 | if find(r, "%c") then -- invalid control char | ||
265 | self:errorline("invalid control char("..string.byte(r)..")") | ||
266 | end | ||
267 | I = i + 1; return r -- other single-char tokens | ||
268 | end | ||
269 | return EOF -- end of stream | ||
270 | ---------------------------------------------------------------- | ||
271 | end--while inner | ||
272 | end--while outer | ||
273 | end | ||
274 | -------------------------------------------------------------------- | ||
275 | -- initial processing (shbang handling) | ||
276 | -------------------------------------------------------------------- | ||
277 | nextln() | ||
278 | local p, q, r = find(z, "^#[^\n]*(\n?)") | ||
279 | if p then -- skip first line | ||
280 | I = q + 1 | ||
281 | if r == "\n" then nextln() end | ||
282 | end | ||
283 | return luaX | ||
284 | -------------------------------------------------------------------- | ||
285 | end | ||