diff options
Diffstat (limited to '')
-rw-r--r-- | LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/sample_expr.lua | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/sample_expr.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/sample_expr.lua new file mode 100644 index 0000000..519cd4c --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/sample_expr.lua | |||
@@ -0,0 +1,195 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | sample_expr.lua | ||
4 | Stand-alone expression parsing demonstrator. | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005 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 | -- * this is an interactive demonstrator for implementing expression | ||
18 | -- parsing in ChunkBake, a Lua assembler | ||
19 | -- * evaluation is immediate, and a result is immediately generated | ||
20 | ----------------------------------------------------------------------]] | ||
21 | |||
22 | require("../lzio.lua") | ||
23 | require("../llex.lua") | ||
24 | luaX:init() | ||
25 | |||
26 | ------------------------------------------------------------------------ | ||
27 | -- expression parser | ||
28 | ------------------------------------------------------------------------ | ||
29 | |||
30 | expr = {} | ||
31 | |||
32 | expr.unop = { | ||
33 | ["TK_NOT"] = true, | ||
34 | ["-"] = true, | ||
35 | } | ||
36 | expr.binop = { | ||
37 | ["^"] = 10, | ||
38 | ["*"] = 7, | ||
39 | ["/"] = 7, | ||
40 | ["+"] = 6, | ||
41 | ["-"] = 6, | ||
42 | ["TK_CONCAT"] = 5, | ||
43 | ["TK_NE"] = 3, | ||
44 | ["TK_EQ"] = 3, | ||
45 | ["<"] = 3, | ||
46 | ["TK_LE"] = 3, | ||
47 | [">"] = 3, | ||
48 | ["TK_GE"] = 3, | ||
49 | ["TK_AND"] = 2, | ||
50 | ["TK_OR"] = 1, | ||
51 | } | ||
52 | expr.binop_r = { | ||
53 | ["^"] = 9, | ||
54 | ["*"] = 7, | ||
55 | ["/"] = 7, | ||
56 | ["+"] = 6, | ||
57 | ["-"] = 6, | ||
58 | ["TK_CONCAT"] = 4, | ||
59 | ["TK_NE"] = 3, | ||
60 | ["TK_EQ"] = 3, | ||
61 | ["<"] = 3, | ||
62 | ["TK_LE"] = 3, | ||
63 | [">"] = 3, | ||
64 | ["TK_GE"] = 3, | ||
65 | ["TK_AND"] = 2, | ||
66 | ["TK_OR"] = 1, | ||
67 | } | ||
68 | |||
69 | function expr:parse(str) | ||
70 | self.LS = {} | ||
71 | self.L = {} | ||
72 | self.z = luaZ:init(luaZ:make_getS(str), nil, "=string") | ||
73 | luaX:setinput(self.L, self.LS, self.z, self.z.name) | ||
74 | self:token() | ||
75 | local v = self:expr() | ||
76 | if self.tok ~= "TK_EOS" then | ||
77 | io.stderr:write("parse error: some tokens unparsed\n") | ||
78 | end | ||
79 | return v | ||
80 | end | ||
81 | |||
82 | function expr:token() | ||
83 | self.tok = luaX:lex(self.LS, self.LS.t) | ||
84 | self.seminfo = self.LS.t.seminfo | ||
85 | return self.tok | ||
86 | end | ||
87 | |||
88 | function expr:simpleexpr() | ||
89 | local tok = self.tok | ||
90 | if tok == "TK_NIL" then | ||
91 | self:token() | ||
92 | return nil | ||
93 | elseif tok == "TK_TRUE" then | ||
94 | self:token() | ||
95 | return true | ||
96 | elseif tok == "TK_FALSE" then | ||
97 | self:token() | ||
98 | return false | ||
99 | elseif tok == "TK_NUMBER" or tok == "TK_STRING" then | ||
100 | self:token() | ||
101 | return self.seminfo | ||
102 | elseif tok == "(" then | ||
103 | self:token() | ||
104 | local v = self:expr() | ||
105 | if self.tok ~= ")" then | ||
106 | io.stderr:write("parse error: expecting ')' to delimit\n") | ||
107 | else | ||
108 | self:token() | ||
109 | return v | ||
110 | end | ||
111 | end | ||
112 | self:token() | ||
113 | io.stderr:write("parse error: "..tok.." encountered, substituting nil\n") | ||
114 | return nil | ||
115 | end | ||
116 | |||
117 | function expr:subexpr(prev_op) | ||
118 | local v, op | ||
119 | if self.unop[self.tok] then | ||
120 | op = self.tok | ||
121 | self:token() | ||
122 | v = self:subexpr(8) | ||
123 | if op == "TK_NOT" then | ||
124 | v = not v | ||
125 | else-- op == "-" then | ||
126 | v = -v | ||
127 | end | ||
128 | else | ||
129 | v = self:simpleexpr() | ||
130 | end | ||
131 | op = self.tok | ||
132 | if self.binop[op] then | ||
133 | while self.binop[op] and self.binop[op] > prev_op do | ||
134 | self:token() | ||
135 | local v2, next_op = self:subexpr(self.binop_r[op]) | ||
136 | if op == "^" then | ||
137 | v = v ^ v2 | ||
138 | elseif op == "*" then | ||
139 | v = v * v2 | ||
140 | elseif op == "/" then | ||
141 | v = v / v2 | ||
142 | elseif op == "+" then | ||
143 | v = v + v2 | ||
144 | elseif op == "-" then | ||
145 | v = v - v2 | ||
146 | elseif op == "TK_CONCAT" then | ||
147 | v = v .. v2 | ||
148 | elseif op == "TK_NE" then | ||
149 | v = v ~= v2 | ||
150 | elseif op == "TK_EQ" then | ||
151 | v = v == v2 | ||
152 | elseif op == "<" then | ||
153 | v = v < v2 | ||
154 | elseif op == "TK_LE" then | ||
155 | v = v <= v2 | ||
156 | elseif op == ">" then | ||
157 | v = v > v2 | ||
158 | elseif op == "TK_GE" then | ||
159 | v = v >= v2 | ||
160 | elseif op == "TK_AND" then | ||
161 | v = v and v2 | ||
162 | else-- op == "TK_OR" then | ||
163 | v = v or v2 | ||
164 | end | ||
165 | op = next_op | ||
166 | end | ||
167 | end | ||
168 | return v, op | ||
169 | end | ||
170 | |||
171 | function expr:expr() | ||
172 | return self:subexpr(-1) | ||
173 | end | ||
174 | |||
175 | ------------------------------------------------------------------------ | ||
176 | -- interactive test code | ||
177 | ------------------------------------------------------------------------ | ||
178 | |||
179 | io.stdout:write([[ | ||
180 | Lua-style expression parsing demonstrator. | ||
181 | Type 'exit' or 'quit' at the prompt to terminate session. | ||
182 | ]]) | ||
183 | local done = false | ||
184 | while not done do | ||
185 | io.stdout:write(":>") | ||
186 | io.stdout:flush() | ||
187 | local l = io.stdin:read("*l") | ||
188 | if l == nil or (l == "exit" or l == "quit" and not prevline) then | ||
189 | done = true | ||
190 | else | ||
191 | local v = tostring(expr:parse(l)) | ||
192 | io.stdout:write(v, "\n") | ||
193 | end | ||
194 | end--while | ||
195 | --end | ||