irb 1.1.0.pre.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +55 -0
- data/exe/irb +11 -0
- data/irb.gemspec +29 -0
- data/lib/irb.rb +855 -0
- data/lib/irb/cmd/chws.rb +34 -0
- data/lib/irb/cmd/fork.rb +39 -0
- data/lib/irb/cmd/help.rb +46 -0
- data/lib/irb/cmd/load.rb +67 -0
- data/lib/irb/cmd/nop.rb +39 -0
- data/lib/irb/cmd/pushws.rb +41 -0
- data/lib/irb/cmd/subirb.rb +43 -0
- data/lib/irb/color.rb +218 -0
- data/lib/irb/completion.rb +339 -0
- data/lib/irb/context.rb +459 -0
- data/lib/irb/ext/change-ws.rb +46 -0
- data/lib/irb/ext/history.rb +120 -0
- data/lib/irb/ext/loader.rb +129 -0
- data/lib/irb/ext/multi-irb.rb +265 -0
- data/lib/irb/ext/save-history.rb +117 -0
- data/lib/irb/ext/tracer.rb +72 -0
- data/lib/irb/ext/use-loader.rb +77 -0
- data/lib/irb/ext/workspaces.rb +67 -0
- data/lib/irb/extend-command.rb +328 -0
- data/lib/irb/frame.rb +81 -0
- data/lib/irb/help.rb +37 -0
- data/lib/irb/init.rb +312 -0
- data/lib/irb/input-method.rb +298 -0
- data/lib/irb/inspector.rb +142 -0
- data/lib/irb/lc/.document +4 -0
- data/lib/irb/lc/error.rb +32 -0
- data/lib/irb/lc/help-message +50 -0
- data/lib/irb/lc/ja/encoding_aliases.rb +11 -0
- data/lib/irb/lc/ja/error.rb +31 -0
- data/lib/irb/lc/ja/help-message +52 -0
- data/lib/irb/locale.rb +182 -0
- data/lib/irb/magic-file.rb +38 -0
- data/lib/irb/notifier.rb +232 -0
- data/lib/irb/output-method.rb +92 -0
- data/lib/irb/ruby-lex.rb +492 -0
- data/lib/irb/ruby-token.rb +267 -0
- data/lib/irb/slex.rb +282 -0
- data/lib/irb/src_encoding.rb +7 -0
- data/lib/irb/version.rb +17 -0
- data/lib/irb/workspace.rb +190 -0
- data/lib/irb/ws-for-case-2.rb +15 -0
- data/lib/irb/xmp.rb +170 -0
- metadata +133 -0
@@ -0,0 +1,267 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# irb/ruby-token.rb - ruby tokens
|
4
|
+
# $Release Version: 0.9.6$
|
5
|
+
# $Revision$
|
6
|
+
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
|
+
#
|
8
|
+
# --
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
# :stopdoc:
|
13
|
+
module RubyToken
|
14
|
+
EXPR_BEG = :EXPR_BEG
|
15
|
+
EXPR_MID = :EXPR_MID
|
16
|
+
EXPR_END = :EXPR_END
|
17
|
+
EXPR_ARG = :EXPR_ARG
|
18
|
+
EXPR_FNAME = :EXPR_FNAME
|
19
|
+
EXPR_DOT = :EXPR_DOT
|
20
|
+
EXPR_CLASS = :EXPR_CLASS
|
21
|
+
|
22
|
+
class Token
|
23
|
+
def initialize(seek, line_no, char_no)
|
24
|
+
@seek = seek
|
25
|
+
@line_no = line_no
|
26
|
+
@char_no = char_no
|
27
|
+
end
|
28
|
+
attr_reader :seek, :line_no, :char_no
|
29
|
+
end
|
30
|
+
|
31
|
+
class TkNode < Token
|
32
|
+
def initialize(seek, line_no, char_no)
|
33
|
+
super
|
34
|
+
end
|
35
|
+
attr_reader :node
|
36
|
+
end
|
37
|
+
|
38
|
+
class TkId < Token
|
39
|
+
def initialize(seek, line_no, char_no, name)
|
40
|
+
super(seek, line_no, char_no)
|
41
|
+
@name = name
|
42
|
+
end
|
43
|
+
attr_reader :name
|
44
|
+
end
|
45
|
+
|
46
|
+
class TkVal < Token
|
47
|
+
def initialize(seek, line_no, char_no, value = nil)
|
48
|
+
super(seek, line_no, char_no)
|
49
|
+
@value = value
|
50
|
+
end
|
51
|
+
attr_reader :value
|
52
|
+
end
|
53
|
+
|
54
|
+
class TkOp < Token
|
55
|
+
attr_accessor :name
|
56
|
+
end
|
57
|
+
|
58
|
+
class TkOPASGN < TkOp
|
59
|
+
def initialize(seek, line_no, char_no, op)
|
60
|
+
super(seek, line_no, char_no)
|
61
|
+
op = TkReading2Token[op][0] unless op.kind_of?(Symbol)
|
62
|
+
@op = op
|
63
|
+
end
|
64
|
+
attr_reader :op
|
65
|
+
end
|
66
|
+
|
67
|
+
class TkUnknownChar < Token
|
68
|
+
def initialize(seek, line_no, char_no, id)
|
69
|
+
super(seek, line_no, char_no)
|
70
|
+
@name = name
|
71
|
+
end
|
72
|
+
attr_reader :name
|
73
|
+
end
|
74
|
+
|
75
|
+
class TkError < Token
|
76
|
+
end
|
77
|
+
|
78
|
+
def Token(token, value = nil)
|
79
|
+
case token
|
80
|
+
when String
|
81
|
+
if (tk = TkReading2Token[token]).nil?
|
82
|
+
IRB.fail TkReading2TokenNoKey, token
|
83
|
+
end
|
84
|
+
tk = Token(tk[0], value)
|
85
|
+
if tk.kind_of?(TkOp)
|
86
|
+
tk.name = token
|
87
|
+
end
|
88
|
+
return tk
|
89
|
+
when Symbol
|
90
|
+
if (tk = TkSymbol2Token[token]).nil?
|
91
|
+
IRB.fail TkSymbol2TokenNoKey, token
|
92
|
+
end
|
93
|
+
return Token(tk[0], value)
|
94
|
+
else
|
95
|
+
if (token.ancestors & [TkId, TkVal, TkOPASGN, TkUnknownChar]).empty?
|
96
|
+
token.new(@prev_seek, @prev_line_no, @prev_char_no)
|
97
|
+
else
|
98
|
+
token.new(@prev_seek, @prev_line_no, @prev_char_no, value)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
TokenDefinitions = [
|
104
|
+
[:TkCLASS, TkId, "class", EXPR_CLASS],
|
105
|
+
[:TkMODULE, TkId, "module", EXPR_BEG],
|
106
|
+
[:TkDEF, TkId, "def", EXPR_FNAME],
|
107
|
+
[:TkUNDEF, TkId, "undef", EXPR_FNAME],
|
108
|
+
[:TkBEGIN, TkId, "begin", EXPR_BEG],
|
109
|
+
[:TkRESCUE, TkId, "rescue", EXPR_MID],
|
110
|
+
[:TkENSURE, TkId, "ensure", EXPR_BEG],
|
111
|
+
[:TkEND, TkId, "end", EXPR_END],
|
112
|
+
[:TkIF, TkId, "if", EXPR_BEG, :TkIF_MOD],
|
113
|
+
[:TkUNLESS, TkId, "unless", EXPR_BEG, :TkUNLESS_MOD],
|
114
|
+
[:TkTHEN, TkId, "then", EXPR_BEG],
|
115
|
+
[:TkELSIF, TkId, "elsif", EXPR_BEG],
|
116
|
+
[:TkELSE, TkId, "else", EXPR_BEG],
|
117
|
+
[:TkCASE, TkId, "case", EXPR_BEG],
|
118
|
+
[:TkWHEN, TkId, "when", EXPR_BEG],
|
119
|
+
[:TkWHILE, TkId, "while", EXPR_BEG, :TkWHILE_MOD],
|
120
|
+
[:TkUNTIL, TkId, "until", EXPR_BEG, :TkUNTIL_MOD],
|
121
|
+
[:TkFOR, TkId, "for", EXPR_BEG],
|
122
|
+
[:TkBREAK, TkId, "break", EXPR_END],
|
123
|
+
[:TkNEXT, TkId, "next", EXPR_END],
|
124
|
+
[:TkREDO, TkId, "redo", EXPR_END],
|
125
|
+
[:TkRETRY, TkId, "retry", EXPR_END],
|
126
|
+
[:TkIN, TkId, "in", EXPR_BEG],
|
127
|
+
[:TkDO, TkId, "do", EXPR_BEG],
|
128
|
+
[:TkRETURN, TkId, "return", EXPR_MID],
|
129
|
+
[:TkYIELD, TkId, "yield", EXPR_END],
|
130
|
+
[:TkSUPER, TkId, "super", EXPR_END],
|
131
|
+
[:TkSELF, TkId, "self", EXPR_END],
|
132
|
+
[:TkNIL, TkId, "nil", EXPR_END],
|
133
|
+
[:TkTRUE, TkId, "true", EXPR_END],
|
134
|
+
[:TkFALSE, TkId, "false", EXPR_END],
|
135
|
+
[:TkAND, TkId, "and", EXPR_BEG],
|
136
|
+
[:TkOR, TkId, "or", EXPR_BEG],
|
137
|
+
[:TkNOT, TkId, "not", EXPR_BEG],
|
138
|
+
[:TkIF_MOD, TkId],
|
139
|
+
[:TkUNLESS_MOD, TkId],
|
140
|
+
[:TkWHILE_MOD, TkId],
|
141
|
+
[:TkUNTIL_MOD, TkId],
|
142
|
+
[:TkALIAS, TkId, "alias", EXPR_FNAME],
|
143
|
+
[:TkDEFINED, TkId, "defined?", EXPR_END],
|
144
|
+
[:TklBEGIN, TkId, "BEGIN", EXPR_END],
|
145
|
+
[:TklEND, TkId, "END", EXPR_END],
|
146
|
+
[:Tk__LINE__, TkId, "__LINE__", EXPR_END],
|
147
|
+
[:Tk__FILE__, TkId, "__FILE__", EXPR_END],
|
148
|
+
|
149
|
+
[:TkIDENTIFIER, TkId],
|
150
|
+
[:TkFID, TkId],
|
151
|
+
[:TkGVAR, TkId],
|
152
|
+
[:TkCVAR, TkId],
|
153
|
+
[:TkIVAR, TkId],
|
154
|
+
[:TkCONSTANT, TkId],
|
155
|
+
|
156
|
+
[:TkINTEGER, TkVal],
|
157
|
+
[:TkFLOAT, TkVal],
|
158
|
+
[:TkSTRING, TkVal],
|
159
|
+
[:TkXSTRING, TkVal],
|
160
|
+
[:TkREGEXP, TkVal],
|
161
|
+
[:TkSYMBOL, TkVal],
|
162
|
+
|
163
|
+
[:TkDSTRING, TkNode],
|
164
|
+
[:TkDXSTRING, TkNode],
|
165
|
+
[:TkDREGEXP, TkNode],
|
166
|
+
[:TkNTH_REF, TkNode],
|
167
|
+
[:TkBACK_REF, TkNode],
|
168
|
+
|
169
|
+
[:TkUPLUS, TkOp, "+@"],
|
170
|
+
[:TkUMINUS, TkOp, "-@"],
|
171
|
+
[:TkPOW, TkOp, "**"],
|
172
|
+
[:TkCMP, TkOp, "<=>"],
|
173
|
+
[:TkEQ, TkOp, "=="],
|
174
|
+
[:TkEQQ, TkOp, "==="],
|
175
|
+
[:TkNEQ, TkOp, "!="],
|
176
|
+
[:TkGEQ, TkOp, ">="],
|
177
|
+
[:TkLEQ, TkOp, "<="],
|
178
|
+
[:TkANDOP, TkOp, "&&"],
|
179
|
+
[:TkOROP, TkOp, "||"],
|
180
|
+
[:TkMATCH, TkOp, "=~"],
|
181
|
+
[:TkNMATCH, TkOp, "!~"],
|
182
|
+
[:TkDOT2, TkOp, ".."],
|
183
|
+
[:TkDOT3, TkOp, "..."],
|
184
|
+
[:TkAREF, TkOp, "[]"],
|
185
|
+
[:TkASET, TkOp, "[]="],
|
186
|
+
[:TkLSHFT, TkOp, "<<"],
|
187
|
+
[:TkRSHFT, TkOp, ">>"],
|
188
|
+
[:TkCOLON2, TkOp],
|
189
|
+
[:TkCOLON3, TkOp],
|
190
|
+
[:TkASSOC, TkOp, "=>"],
|
191
|
+
[:TkQUESTION, TkOp, "?"], #?
|
192
|
+
[:TkCOLON, TkOp, ":"], #:
|
193
|
+
|
194
|
+
[:TkfLPAREN], # func( #
|
195
|
+
[:TkfLBRACK], # func[ #
|
196
|
+
[:TkfLBRACE], # func{ #
|
197
|
+
[:TkSTAR], # *arg
|
198
|
+
[:TkAMPER], # &arg #
|
199
|
+
[:TkSYMBEG], # :SYMBOL
|
200
|
+
|
201
|
+
[:TkGT, TkOp, ">"],
|
202
|
+
[:TkLT, TkOp, "<"],
|
203
|
+
[:TkPLUS, TkOp, "+"],
|
204
|
+
[:TkMINUS, TkOp, "-"],
|
205
|
+
[:TkMULT, TkOp, "*"],
|
206
|
+
[:TkDIV, TkOp, "/"],
|
207
|
+
[:TkMOD, TkOp, "%"],
|
208
|
+
[:TkBITOR, TkOp, "|"],
|
209
|
+
[:TkBITXOR, TkOp, "^"],
|
210
|
+
[:TkBITAND, TkOp, "&"],
|
211
|
+
[:TkBITNOT, TkOp, "~"],
|
212
|
+
[:TkNOTOP, TkOp, "!"],
|
213
|
+
|
214
|
+
[:TkBACKQUOTE, TkOp, "`"],
|
215
|
+
|
216
|
+
[:TkASSIGN, Token, "="],
|
217
|
+
[:TkDOT, Token, "."],
|
218
|
+
[:TkLPAREN, Token, "("], #(exp)
|
219
|
+
[:TkLBRACK, Token, "["], #[arry]
|
220
|
+
[:TkLBRACE, Token, "{"], #{hash}
|
221
|
+
[:TkRPAREN, Token, ")"],
|
222
|
+
[:TkRBRACK, Token, "]"],
|
223
|
+
[:TkRBRACE, Token, "}"],
|
224
|
+
[:TkCOMMA, Token, ","],
|
225
|
+
[:TkSEMICOLON, Token, ";"],
|
226
|
+
|
227
|
+
[:TkCOMMENT],
|
228
|
+
[:TkRD_COMMENT],
|
229
|
+
[:TkSPACE],
|
230
|
+
[:TkNL],
|
231
|
+
[:TkEND_OF_SCRIPT],
|
232
|
+
|
233
|
+
[:TkBACKSLASH, TkUnknownChar, "\\"],
|
234
|
+
[:TkAT, TkUnknownChar, "@"],
|
235
|
+
[:TkDOLLAR, TkUnknownChar, "$"],
|
236
|
+
]
|
237
|
+
|
238
|
+
# {reading => token_class}
|
239
|
+
# {reading => [token_class, *opt]}
|
240
|
+
TkReading2Token = {}
|
241
|
+
TkSymbol2Token = {}
|
242
|
+
|
243
|
+
def RubyToken.def_token(token_n, super_token = Token, reading = nil, *opts)
|
244
|
+
token_n = token_n.id2name if token_n.kind_of?(Symbol)
|
245
|
+
if RubyToken.const_defined?(token_n)
|
246
|
+
IRB.fail AlreadyDefinedToken, token_n
|
247
|
+
end
|
248
|
+
token_c = eval("class #{token_n} < #{super_token}; end; #{token_n}")
|
249
|
+
|
250
|
+
if reading
|
251
|
+
if TkReading2Token[reading]
|
252
|
+
IRB.fail TkReading2TokenDuplicateError, token_n, reading
|
253
|
+
end
|
254
|
+
if opts.empty?
|
255
|
+
TkReading2Token[reading] = [token_c]
|
256
|
+
else
|
257
|
+
TkReading2Token[reading] = [token_c].concat(opts)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
TkSymbol2Token[token_n.intern] = token_c
|
261
|
+
end
|
262
|
+
|
263
|
+
for defs in TokenDefinitions
|
264
|
+
def_token(*defs)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
# :startdoc:
|
data/lib/irb/slex.rb
ADDED
@@ -0,0 +1,282 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# irb/slex.rb - simple lex analyzer
|
4
|
+
# $Release Version: 0.9.6$
|
5
|
+
# $Revision$
|
6
|
+
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
|
+
#
|
8
|
+
# --
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
|
13
|
+
require "e2mmap"
|
14
|
+
require_relative "notifier"
|
15
|
+
|
16
|
+
# :stopdoc:
|
17
|
+
module IRB
|
18
|
+
class SLex
|
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
|
+
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
|
+
# need a check?
|
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_DETAIL.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
|
246
|
+
end
|
247
|
+
# :startdoc:
|
248
|
+
|
249
|
+
if $0 == __FILE__
|
250
|
+
case $1
|
251
|
+
when "1"
|
252
|
+
tr = SLex.new
|
253
|
+
print "0: ", tr.inspect, "\n"
|
254
|
+
tr.def_rule("=") {print "=\n"}
|
255
|
+
print "1: ", tr.inspect, "\n"
|
256
|
+
tr.def_rule("==") {print "==\n"}
|
257
|
+
print "2: ", tr.inspect, "\n"
|
258
|
+
|
259
|
+
print "case 1:\n"
|
260
|
+
print tr.match("="), "\n"
|
261
|
+
print "case 2:\n"
|
262
|
+
print tr.match("=="), "\n"
|
263
|
+
print "case 3:\n"
|
264
|
+
print tr.match("=>"), "\n"
|
265
|
+
|
266
|
+
when "2"
|
267
|
+
tr = SLex.new
|
268
|
+
print "0: ", tr.inspect, "\n"
|
269
|
+
tr.def_rule("=") {print "=\n"}
|
270
|
+
print "1: ", tr.inspect, "\n"
|
271
|
+
tr.def_rule("==", proc{false}) {print "==\n"}
|
272
|
+
print "2: ", tr.inspect, "\n"
|
273
|
+
|
274
|
+
print "case 1:\n"
|
275
|
+
print tr.match("="), "\n"
|
276
|
+
print "case 2:\n"
|
277
|
+
print tr.match("=="), "\n"
|
278
|
+
print "case 3:\n"
|
279
|
+
print tr.match("=>"), "\n"
|
280
|
+
end
|
281
|
+
exit
|
282
|
+
end
|