diff options
Diffstat (limited to '')
-rw-r--r-- | LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/llex_mk2.lua | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/llex_mk2.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/llex_mk2.lua new file mode 100644 index 0000000..955f229 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/llex_mk2.lua | |||
@@ -0,0 +1,309 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | llex.lua | ||
4 | Lua 5 lexical analyzer in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-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 | -- * parser to implement luaX_syntaxerror, call errorline with 2 parms | ||
18 | ----------------------------------------------------------------------]] | ||
19 | |||
20 | --[[-------------------------------------------------------------------- | ||
21 | -- local lex_init = require("llex.lua") | ||
22 | -- local llex = lex_init(z, source) | ||
23 | -- llex:chunkid() | ||
24 | -- * returns formatted name of chunk id | ||
25 | -- llex:errorline(s, token, line) | ||
26 | -- * throws an error with a formatted message | ||
27 | -- llex:lex() | ||
28 | -- * returns next lexical element (token, seminfo) | ||
29 | ----------------------------------------------------------------------]] | ||
30 | |||
31 | return | ||
32 | function(z, source) | ||
33 | --[[-------------------------------------------------------------------- | ||
34 | -- lexer initialization | ||
35 | ----------------------------------------------------------------------]] | ||
36 | -------------------------------------------------------------------- | ||
37 | -- initialize variables | ||
38 | -------------------------------------------------------------------- | ||
39 | local string = string | ||
40 | local EOF = "<eof>" | ||
41 | local z = z | ||
42 | local luaX = {source = source, lineno = 1,} | ||
43 | local curr, buff | ||
44 | -------------------------------------------------------------------- | ||
45 | -- initialize keyword list | ||
46 | -------------------------------------------------------------------- | ||
47 | local kw = {} | ||
48 | for v in string.gfind([[ | ||
49 | and break do else elseif end false for function if in | ||
50 | local nil not or repeat return then true until while]], "%S+") do | ||
51 | kw[v] = true | ||
52 | end | ||
53 | --[[-------------------------------------------------------------------- | ||
54 | -- support functions | ||
55 | ----------------------------------------------------------------------]] | ||
56 | -------------------------------------------------------------------- | ||
57 | -- returns a chunk name or id | ||
58 | -------------------------------------------------------------------- | ||
59 | function luaX:chunkid() | ||
60 | local sub = string.sub | ||
61 | local first = sub(source, 1, 1) | ||
62 | if first == "=" or first == "@" then | ||
63 | return sub(source, 2) -- remove first char | ||
64 | end | ||
65 | return "[string]" | ||
66 | end | ||
67 | -------------------------------------------------------------------- | ||
68 | -- formats error message and throws error | ||
69 | -------------------------------------------------------------------- | ||
70 | function luaX:errorline(s, token, line) | ||
71 | if not line then line = self.lineno end | ||
72 | error(string.format("%s:%d: %s near '%s'", self:chunkid(), line, s, token)) | ||
73 | end | ||
74 | -------------------------------------------------------------------- | ||
75 | -- throws a lexer error | ||
76 | -------------------------------------------------------------------- | ||
77 | local function lexerror(s, token) | ||
78 | if not token then token = buff end | ||
79 | luaX:errorline(s, token) | ||
80 | end | ||
81 | -------------------------------------------------------------------- | ||
82 | -- gets the next character and returns it | ||
83 | -------------------------------------------------------------------- | ||
84 | local function nextc() | ||
85 | local c = z:getc() | ||
86 | curr = c | ||
87 | return c | ||
88 | end | ||
89 | -------------------------------------------------------------------- | ||
90 | -- save current character into token buffer, grabs next character | ||
91 | -- * save(c) merged into this and elsewhere to save space | ||
92 | -------------------------------------------------------------------- | ||
93 | local function save_next() | ||
94 | buff = buff..curr | ||
95 | return nextc() | ||
96 | end | ||
97 | -------------------------------------------------------------------- | ||
98 | -- move on to next line | ||
99 | -------------------------------------------------------------------- | ||
100 | local function nextline() | ||
101 | local luaX = luaX | ||
102 | nextc() -- skip '\n' | ||
103 | luaX.lineno = luaX.lineno + 1 | ||
104 | end | ||
105 | --[[-------------------------------------------------------------------- | ||
106 | -- reads a number (LUA_NUMBER) | ||
107 | ----------------------------------------------------------------------]] | ||
108 | local function read_numeral(comma) | ||
109 | buff = "" | ||
110 | local find = string.find | ||
111 | if comma then buff = "." end | ||
112 | ------------------------------------------------------------------ | ||
113 | while find(curr, "%d") do save_next() end | ||
114 | if curr == "." then | ||
115 | if save_next() == "." then | ||
116 | save_next() | ||
117 | lexerror("ambiguous syntax (dots follows digits)") | ||
118 | end | ||
119 | end | ||
120 | ------------------------------------------------------------------ | ||
121 | while find(curr, "%d") do save_next() end | ||
122 | if find(curr, "^[eE]$") then | ||
123 | save_next() -- read 'E' and optional exponent sign | ||
124 | if find(curr, "^[+-]$") then save_next() end | ||
125 | while find(curr, "%d") do save_next() end | ||
126 | end | ||
127 | c = tonumber(buff) | ||
128 | if c then return c end | ||
129 | lexerror("malformed number") | ||
130 | end | ||
131 | --[[-------------------------------------------------------------------- | ||
132 | -- reads a long string or long comment | ||
133 | ----------------------------------------------------------------------]] | ||
134 | local function read_long(is_str) | ||
135 | local cont = 0 | ||
136 | buff = "" | ||
137 | nextc() -- pass the '[[' | ||
138 | if curr == "\n" then -- string starts with a newline? | ||
139 | nextline() -- skip it | ||
140 | end | ||
141 | while true do | ||
142 | local c = curr | ||
143 | ---------------------------------------------------------------- | ||
144 | if c == "EOZ" then | ||
145 | lexerror(is_str and "unfinished long string" or | ||
146 | "unfinished long comment", EOF) | ||
147 | ---------------------------------------------------------------- | ||
148 | elseif c == "[" then | ||
149 | if save_next() == "[" then | ||
150 | cont = cont + 1; save_next() | ||
151 | end | ||
152 | ---------------------------------------------------------------- | ||
153 | elseif c == "]" then | ||
154 | if save_next() == "]" then | ||
155 | if cont == 0 then break end | ||
156 | cont = cont - 1; save_next() | ||
157 | end | ||
158 | ---------------------------------------------------------------- | ||
159 | elseif c == "\n" then | ||
160 | buff = buff.."\n"; nextline() | ||
161 | if not is_str then buff = "" end -- avoid wasting space | ||
162 | ---------------------------------------------------------------- | ||
163 | else | ||
164 | save_next() | ||
165 | ---------------------------------------------------------------- | ||
166 | end--if c | ||
167 | end--while | ||
168 | nextc() -- skip second ']' | ||
169 | return string.sub(buff, 1, -2) | ||
170 | end | ||
171 | --[[-------------------------------------------------------------------- | ||
172 | -- reads a string | ||
173 | ----------------------------------------------------------------------]] | ||
174 | local function read_string(del) | ||
175 | local find = string.find | ||
176 | buff = "" | ||
177 | save_next() -- save delimiter | ||
178 | while curr ~= del do | ||
179 | local c = curr | ||
180 | ---------------------------------------------------------------- | ||
181 | -- end-of-file, newline | ||
182 | ---------------------------------------------------------------- | ||
183 | if c == "EOZ" then | ||
184 | lexerror("unfinished string", EOF) | ||
185 | elseif c == "\n" then | ||
186 | lexerror("unfinished string") | ||
187 | ---------------------------------------------------------------- | ||
188 | -- escapes | ||
189 | ---------------------------------------------------------------- | ||
190 | elseif c == "\\" then | ||
191 | c = nextc() -- do not save the '\' | ||
192 | if c ~= "EOZ" then -- will raise an error next loop iteration | ||
193 | local d = find("\nabfnrtv", c, 1, 1) | ||
194 | if d then | ||
195 | buff = buff..string.sub("\n\a\b\f\n\r\t\v", d, d) | ||
196 | if d == 1 then nextline() else nextc() end | ||
197 | elseif find(c, "%D") then | ||
198 | save_next() -- handles \\, \", \', and \? | ||
199 | else -- \xxx | ||
200 | c, d = 0, 0 | ||
201 | repeat | ||
202 | c = 10 * c + curr; d = d + 1; nextc() | ||
203 | until d >= 3 or find(curr, "%D") | ||
204 | if c > 255 then -- UCHAR_MAX | ||
205 | lexerror("escape sequence too large") | ||
206 | end | ||
207 | buff = buff..string.char(c) | ||
208 | end | ||
209 | end | ||
210 | ---------------------------------------------------------------- | ||
211 | -- a regular character | ||
212 | ---------------------------------------------------------------- | ||
213 | else | ||
214 | save_next() | ||
215 | ---------------------------------------------------------------- | ||
216 | end--if c | ||
217 | end--while | ||
218 | nextc() -- skip delimiter | ||
219 | return string.sub(buff, 2) | ||
220 | end | ||
221 | --[[-------------------------------------------------------------------- | ||
222 | -- main lexer function | ||
223 | ----------------------------------------------------------------------]] | ||
224 | function luaX:lex() | ||
225 | local find = string.find | ||
226 | while true do | ||
227 | local c = curr | ||
228 | ---------------------------------------------------------------- | ||
229 | -- operators, numbers | ||
230 | ---------------------------------------------------------------- | ||
231 | local d = find("=<>~\"'-[.\n", c, 1, 1) | ||
232 | if d then | ||
233 | ------------------------------------------------------------ | ||
234 | if d <= 4 then -- "=<>~" (relational operators) | ||
235 | if nextc() ~= "=" then return c end | ||
236 | nextc(); return c.."=" | ||
237 | ------------------------------------------------------------ | ||
238 | elseif d <= 6 then -- "\"" or "'" (string) | ||
239 | return "<string>", read_string(c) | ||
240 | ------------------------------------------------------------ | ||
241 | elseif c == "-" then -- "-" ("-", comment, or long comment) | ||
242 | if nextc() ~= "-" then return "-" end | ||
243 | c = nextc() -- otherwise it is a comment | ||
244 | if c == "[" and nextc() == "[" then | ||
245 | read_long() -- long comment | ||
246 | else -- short comment | ||
247 | while c ~= "\n" and c ~= "EOZ" do c = nextc() end | ||
248 | end | ||
249 | ------------------------------------------------------------ | ||
250 | elseif c == "[" then -- "[" ("[" or long string) | ||
251 | if nextc() ~= "[" then return c end | ||
252 | return "<string>", read_long(true) | ||
253 | ------------------------------------------------------------ | ||
254 | elseif c == "." then -- "." (".", concatenation, or dots) | ||
255 | buff = "" | ||
256 | c = save_next() | ||
257 | if c == "." then -- interpret 2 or 3 dots | ||
258 | if save_next() == "." then save_next() end | ||
259 | return buff | ||
260 | end | ||
261 | if find(c, "%d") then | ||
262 | return "<number>", read_numeral(true) | ||
263 | end | ||
264 | return "." | ||
265 | ------------------------------------------------------------ | ||
266 | else-- c == "\n" then -- "\n" (newline) | ||
267 | nextline() | ||
268 | ------------------------------------------------------------ | ||
269 | end--if d/c | ||
270 | ---------------------------------------------------------------- | ||
271 | -- number, end-of-file, identifier or reserved word | ||
272 | ---------------------------------------------------------------- | ||
273 | elseif find(c, "%d") then -- number | ||
274 | return "<number>", read_numeral(false) | ||
275 | ---------------------------------------------------------------- | ||
276 | elseif find(c, "[_%a]") then -- reads a name | ||
277 | if c == "EOZ" then return EOF end -- end-of-file | ||
278 | buff = "" | ||
279 | repeat | ||
280 | c = save_next() | ||
281 | until c == "EOZ" or find(c, "[^_%w]") | ||
282 | c = buff | ||
283 | if kw[c] then return c end -- reserved word | ||
284 | return "<name>", c | ||
285 | ---------------------------------------------------------------- | ||
286 | -- whitespace, other characters, control characters | ||
287 | ---------------------------------------------------------------- | ||
288 | elseif find(c, "%s") then -- whitespace | ||
289 | nextc() | ||
290 | ---------------------------------------------------------------- | ||
291 | elseif find(c, "%c") then -- control characters | ||
292 | lexerror("invalid control char", "char("..string.byte(c)..")") | ||
293 | ---------------------------------------------------------------- | ||
294 | else -- single-char tokens (+ - / etc.) | ||
295 | nextc(); return c | ||
296 | ---------------------------------------------------------------- | ||
297 | end--if d/c | ||
298 | end--while | ||
299 | end | ||
300 | --[[-------------------------------------------------------------------- | ||
301 | -- initial processing (shbang handling) | ||
302 | ----------------------------------------------------------------------]] | ||
303 | nextc() -- read first char | ||
304 | if cur == "#" then -- skip first line | ||
305 | repeat nextc() until curr == "\n" or curr == "EOZ" | ||
306 | end | ||
307 | return luaX | ||
308 | --[[------------------------------------------------------------------]] | ||
309 | end | ||