source: extensions/gsdl-video/trunk/installed/cmdline/lib/ruby/1.8/irb/slex.rb@ 18425

Last change on this file since 18425 was 18425, checked in by davidb, 15 years ago

Video extension to Greenstone

File size: 6.1 KB
Line 
1#
2# irb/slex.rb - symple lex analizer
3# $Release Version: 0.9.5$
4# $Revision: 11708 $
5# $Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
6# by Keiju ISHITSUKA([email protected])
7#
8# --
9#
10#
11#
12
13require "e2mmap"
14require "irb/notifier"
15
16module IRB
17 class SLex
18 @RCS_ID='-$Id: slex.rb 11708 2007-02-12 23:01:19Z shyouhei $-'
19
20 extend Exception2MessageMapper
21 def_exception :ErrNodeNothing, "node nothing"
22 def_exception :ErrNodeAlreadyExists, "node already exists"
23
24 DOUT = Notifier::def_notifier("SLex::")
25 D_WARN = DOUT::def_notifier(1, "Warn: ")
26 D_DEBUG = DOUT::def_notifier(2, "Debug: ")
27 D_DETAIL = DOUT::def_notifier(4, "Detail: ")
28
29 DOUT.level = Notifier::D_NOMSG
30
31 def initialize
32 @head = Node.new("")
33 end
34
35 def def_rule(token, preproc = nil, postproc = nil, &block)
36 D_DETAIL.pp token
37
38 postproc = block if block_given?
39 node = create(token, preproc, postproc)
40 end
41
42 def def_rules(*tokens, &block)
43 if block_given?
44 p = block
45 end
46 for token in tokens
47 def_rule(token, nil, p)
48 end
49 end
50
51 def preproc(token, proc)
52 node = search(token)
53 node.preproc=proc
54 end
55
56 #$BMW%A%'%C%/(B?
57 def postproc(token)
58 node = search(token, proc)
59 node.postproc=proc
60 end
61
62 def search(token)
63 @head.search(token.split(//))
64 end
65
66 def create(token, preproc = nil, postproc = nil)
67 @head.create_subnode(token.split(//), preproc, postproc)
68 end
69
70 def match(token)
71 case token
72 when Array
73 when String
74 return match(token.split(//))
75 else
76 return @head.match_io(token)
77 end
78 ret = @head.match(token)
79 D_DETAIL.exec_if{D_DEATIL.printf "match end: %s:%s\n", ret, token.inspect}
80 ret
81 end
82
83 def inspect
84 format("<SLex: @head = %s>", @head.inspect)
85 end
86
87 #----------------------------------------------------------------------
88 #
89 # class Node -
90 #
91 #----------------------------------------------------------------------
92 class Node
93 # if postproc is nil, this node is an abstract node.
94 # if postproc is non-nil, this node is a real node.
95 def initialize(preproc = nil, postproc = nil)
96 @Tree = {}
97 @preproc = preproc
98 @postproc = postproc
99 end
100
101 attr_accessor :preproc
102 attr_accessor :postproc
103
104 def search(chrs, opt = nil)
105 return self if chrs.empty?
106 ch = chrs.shift
107 if node = @Tree[ch]
108 node.search(chrs, opt)
109 else
110 if opt
111 chrs.unshift ch
112 self.create_subnode(chrs)
113 else
114 SLex.fail ErrNodeNothing
115 end
116 end
117 end
118
119 def create_subnode(chrs, preproc = nil, postproc = nil)
120 if chrs.empty?
121 if @postproc
122 D_DETAIL.pp node
123 SLex.fail ErrNodeAlreadyExists
124 else
125 D_DEBUG.puts "change abstract node to real node."
126 @preproc = preproc
127 @postproc = postproc
128 end
129 return self
130 end
131
132 ch = chrs.shift
133 if node = @Tree[ch]
134 if chrs.empty?
135 if node.postproc
136 DebugLogger.pp node
137 DebugLogger.pp self
138 DebugLogger.pp ch
139 DebugLogger.pp chrs
140 SLex.fail ErrNodeAlreadyExists
141 else
142 D_WARN.puts "change abstract node to real node"
143 node.preproc = preproc
144 node.postproc = postproc
145 end
146 else
147 node.create_subnode(chrs, preproc, postproc)
148 end
149 else
150 if chrs.empty?
151 node = Node.new(preproc, postproc)
152 else
153 node = Node.new
154 node.create_subnode(chrs, preproc, postproc)
155 end
156 @Tree[ch] = node
157 end
158 node
159 end
160
161 #
162 # chrs: String
163 # character array
164 # io must have getc()/ungetc(); and ungetc() must be
165 # able to be called arbitrary number of times.
166 #
167 def match(chrs, op = "")
168 D_DETAIL.print "match>: ", chrs, "op:", op, "\n"
169 if chrs.empty?
170 if @preproc.nil? || @preproc.call(op, chrs)
171 DOUT.printf(D_DETAIL, "op1: %s\n", op)
172 @postproc.call(op, chrs)
173 else
174 nil
175 end
176 else
177 ch = chrs.shift
178 if node = @Tree[ch]
179 if ret = node.match(chrs, op+ch)
180 return ret
181 else
182 chrs.unshift ch
183 if @postproc and @preproc.nil? || @preproc.call(op, chrs)
184 DOUT.printf(D_DETAIL, "op2: %s\n", op.inspect)
185 ret = @postproc.call(op, chrs)
186 return ret
187 else
188 return nil
189 end
190 end
191 else
192 chrs.unshift ch
193 if @postproc and @preproc.nil? || @preproc.call(op, chrs)
194 DOUT.printf(D_DETAIL, "op3: %s\n", op)
195 @postproc.call(op, chrs)
196 return ""
197 else
198 return nil
199 end
200 end
201 end
202 end
203
204 def match_io(io, op = "")
205 if op == ""
206 ch = io.getc
207 if ch == nil
208 return nil
209 end
210 else
211 ch = io.getc_of_rests
212 end
213 if ch.nil?
214 if @preproc.nil? || @preproc.call(op, io)
215 D_DETAIL.printf("op1: %s\n", op)
216 @postproc.call(op, io)
217 else
218 nil
219 end
220 else
221 if node = @Tree[ch]
222 if ret = node.match_io(io, op+ch)
223 ret
224 else
225 io.ungetc ch
226 if @postproc and @preproc.nil? || @preproc.call(op, io)
227 DOUT.exec_if{D_DETAIL.printf "op2: %s\n", op.inspect}
228 @postproc.call(op, io)
229 else
230 nil
231 end
232 end
233 else
234 io.ungetc ch
235 if @postproc and @preproc.nil? || @preproc.call(op, io)
236 D_DETAIL.printf("op3: %s\n", op)
237 @postproc.call(op, io)
238 else
239 nil
240 end
241 end
242 end
243 end
244 end
245 end
246end
247
248SLex=IRB::SLex
249
250if $0 == __FILE__
251 # Tracer.on
252 case $1
253 when "1"
254 tr = SLex.new
255 print "0: ", tr.inspect, "\n"
256 tr.def_rule("=") {print "=\n"}
257 print "1: ", tr.inspect, "\n"
258 tr.def_rule("==") {print "==\n"}
259 print "2: ", tr.inspect, "\n"
260
261 print "case 1:\n"
262 print tr.match("="), "\n"
263 print "case 2:\n"
264 print tr.match("=="), "\n"
265 print "case 3:\n"
266 print tr.match("=>"), "\n"
267
268 when "2"
269 tr = SLex.new
270 print "0: ", tr.inspect, "\n"
271 tr.def_rule("=") {print "=\n"}
272 print "1: ", tr.inspect, "\n"
273 tr.def_rule("==", proc{false}) {print "==\n"}
274 print "2: ", tr.inspect, "\n"
275
276 print "case 1:\n"
277 print tr.match("="), "\n"
278 print "case 2:\n"
279 print tr.match("=="), "\n"
280 print "case 3:\n"
281 print tr.match("=>"), "\n"
282 end
283 exit
284end
285
Note: See TracBrowser for help on using the repository browser.