trepanning 0.1.0 → 0.1.1

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.
Files changed (181) hide show
  1. data/.gitignore +4 -0
  2. data/ChangeLog +1279 -235
  3. data/Makefile +13 -0
  4. data/NEWS +30 -0
  5. data/Rakefile +50 -14
  6. data/app/.gitignore +1 -0
  7. data/app/breakpoint.rb +7 -2
  8. data/app/brkptmgr.rb +12 -0
  9. data/app/cmd_parse.citrus +167 -0
  10. data/app/cmd_parse.kpeg +221 -0
  11. data/app/cmd_parse.rb +201 -0
  12. data/app/cmd_parser.rb +1914 -0
  13. data/app/complete.rb +79 -0
  14. data/app/condition.rb +1 -1
  15. data/app/core.rb +7 -11
  16. data/app/default.rb +1 -1
  17. data/app/disassemble.rb +3 -2
  18. data/app/file.rb +12 -36
  19. data/app/frame.rb +3 -2
  20. data/app/irb.rb +9 -5
  21. data/app/iseq.rb +46 -0
  22. data/app/options.rb +6 -30
  23. data/app/run.rb +5 -2
  24. data/app/util.rb +1 -2
  25. data/app/yarv.rb +11 -1
  26. data/bin/.gitignore +1 -0
  27. data/bin/trepan +6 -6
  28. data/data/.gitignore +1 -0
  29. data/interface/.gitignore +1 -0
  30. data/interface/base_intf.rb +9 -5
  31. data/interface/comcodes.rb +10 -8
  32. data/interface/user.rb +76 -17
  33. data/io/.gitignore +1 -0
  34. data/io/input.rb +39 -15
  35. data/io/tcpclient.rb +7 -1
  36. data/io/tcpfns.rb +5 -3
  37. data/io/tcpserver.rb +13 -10
  38. data/lib/.gitignore +1 -0
  39. data/lib/trepanning.rb +50 -13
  40. data/processor/.gitignore +1 -0
  41. data/processor/Makefile +7 -0
  42. data/processor/breakpoint.rb +7 -2
  43. data/processor/command/.gitignore +1 -0
  44. data/processor/command/Makefile +7 -0
  45. data/processor/command/alias.rb +2 -2
  46. data/processor/command/backtrace.rb +4 -0
  47. data/processor/command/base/cmd.rb +45 -2
  48. data/processor/command/base/subcmd.rb +4 -2
  49. data/processor/command/base/submgr.rb +23 -19
  50. data/processor/command/base/subsubcmd.rb +23 -1
  51. data/processor/command/base/subsubmgr.rb +13 -0
  52. data/processor/command/break.rb +34 -29
  53. data/processor/command/complete.rb +37 -0
  54. data/processor/command/condition.rb +2 -0
  55. data/processor/command/continue.rb +15 -18
  56. data/processor/command/disassemble.rb +5 -0
  57. data/processor/command/down.rb +1 -1
  58. data/processor/command/eval.rb +70 -0
  59. data/processor/command/exit.rb +4 -1
  60. data/processor/command/finish.rb +6 -4
  61. data/processor/command/frame.rb +6 -3
  62. data/processor/command/help.rb +97 -54
  63. data/processor/command/help/.gitignore +1 -0
  64. data/processor/command/help/README +10 -0
  65. data/processor/command/help/command.txt +48 -0
  66. data/processor/command/help/filename.txt +40 -0
  67. data/processor/command/help/location.txt +37 -0
  68. data/processor/command/info_subcmd/.gitignore +1 -0
  69. data/processor/command/info_subcmd/breakpoints.rb +9 -9
  70. data/processor/command/info_subcmd/{file.rb → files.rb} +92 -27
  71. data/processor/command/info_subcmd/frame.rb +41 -15
  72. data/processor/command/info_subcmd/iseq.rb +39 -17
  73. data/processor/command/info_subcmd/program.rb +2 -8
  74. data/processor/command/info_subcmd/registers.rb +12 -10
  75. data/processor/command/info_subcmd/registers_subcmd/.gitignore +1 -0
  76. data/processor/command/info_subcmd/ruby.rb +60 -0
  77. data/processor/command/irb.rb +26 -3
  78. data/processor/command/kill.rb +21 -10
  79. data/processor/command/list.rb +1 -1
  80. data/processor/command/macro.rb +37 -23
  81. data/processor/command/pr.rb +1 -1
  82. data/processor/command/reload.rb +4 -0
  83. data/processor/command/reload_subcmd/.gitignore +1 -0
  84. data/processor/command/restart.rb +9 -9
  85. data/processor/command/save.rb +29 -36
  86. data/processor/command/set_subcmd/.gitignore +1 -0
  87. data/processor/command/set_subcmd/auto_subcmd/.gitignore +1 -0
  88. data/processor/command/set_subcmd/confirm.rb +23 -0
  89. data/processor/command/set_subcmd/debug_subcmd/.gitignore +1 -0
  90. data/processor/command/set_subcmd/different.rb +2 -0
  91. data/processor/command/set_subcmd/events.rb +2 -0
  92. data/processor/command/set_subcmd/max.rb +9 -12
  93. data/processor/command/set_subcmd/max_subcmd/.gitignore +1 -0
  94. data/processor/command/set_subcmd/substitute_subcmd/.gitignore +1 -0
  95. data/processor/command/set_subcmd/trace.rb +7 -13
  96. data/processor/command/set_subcmd/trace_subcmd/.gitignore +1 -0
  97. data/processor/command/set_subcmd/trace_subcmd/buffer.rb +12 -27
  98. data/processor/command/set_subcmd/trace_subcmd/print.rb +10 -8
  99. data/processor/command/set_subcmd/trace_subcmd/var.rb +6 -10
  100. data/processor/command/show.rb +12 -1
  101. data/processor/command/show_subcmd/.gitignore +1 -0
  102. data/processor/command/show_subcmd/alias.rb +11 -15
  103. data/processor/command/show_subcmd/auto_subcmd/.gitignore +1 -0
  104. data/processor/command/show_subcmd/basename.rb +1 -9
  105. data/processor/command/show_subcmd/confirm.rb +25 -0
  106. data/processor/command/show_subcmd/debug_subcmd/.gitignore +1 -0
  107. data/processor/command/show_subcmd/macro.rb +32 -14
  108. data/processor/command/show_subcmd/max_subcmd/.gitignore +1 -0
  109. data/processor/command/show_subcmd/trace_subcmd/.gitignore +1 -0
  110. data/processor/command/show_subcmd/trace_subcmd/buffer.rb +11 -31
  111. data/processor/command/show_subcmd/trace_subcmd/print.rb +4 -20
  112. data/processor/command/source.rb +7 -1
  113. data/processor/command/up.rb +7 -4
  114. data/processor/default.rb +3 -1
  115. data/processor/eval.rb +13 -0
  116. data/processor/eventbuf.rb +3 -2
  117. data/processor/frame.rb +19 -0
  118. data/processor/help.rb +20 -0
  119. data/processor/load_cmds.rb +143 -24
  120. data/processor/location.rb +61 -10
  121. data/processor/main.rb +30 -11
  122. data/processor/mock.rb +5 -3
  123. data/processor/msg.rb +17 -0
  124. data/processor/running.rb +1 -1
  125. data/processor/subcmd.rb +3 -2
  126. data/processor/validate.rb +173 -185
  127. data/sample/.gitignore +1 -0
  128. data/sample/list-terminal-colors.rb +139 -0
  129. data/sample/rocky-dot-trepanrc +14 -0
  130. data/sample/rocky-trepan-colors.rb +47 -0
  131. data/test/Makefile +7 -0
  132. data/test/data/.gitignore +1 -0
  133. data/test/data/debugger-stop.cmd +3 -0
  134. data/test/data/debugger-stop.right +5 -0
  135. data/test/data/fname-with-blank.right +0 -3
  136. data/test/data/quit.right +0 -1
  137. data/test/data/quit2.cmd +6 -0
  138. data/test/data/quit2.right +3 -0
  139. data/test/data/testing.cmd +1 -0
  140. data/test/example/.gitignore +1 -0
  141. data/test/example/debugger-stop.rb +14 -0
  142. data/test/functional/.gitignore +2 -0
  143. data/test/functional/fn_helper.rb +7 -9
  144. data/test/functional/test-break-long.rb +7 -7
  145. data/test/functional/test-break.rb +7 -7
  146. data/test/functional/test-condition.rb +4 -4
  147. data/test/functional/test-delete.rb +6 -5
  148. data/test/functional/test-eval.rb +115 -0
  149. data/test/functional/test-raise.rb +1 -1
  150. data/test/functional/test-return.rb +1 -1
  151. data/test/integration/.gitignore +2 -0
  152. data/test/integration/helper.rb +6 -3
  153. data/test/integration/test-debugger-stop.rb +22 -0
  154. data/test/integration/test-quit.rb +8 -0
  155. data/test/unit/.gitignore +1 -0
  156. data/test/unit/Makefile +7 -0
  157. data/test/unit/test-app-brkpt.rb +0 -1
  158. data/test/unit/test-app-cmd_parse.rb +107 -0
  159. data/test/unit/test-app-cmd_parser.rb +22 -0
  160. data/test/unit/test-app-complete.rb +38 -0
  161. data/test/unit/test-app-condition.rb +20 -0
  162. data/test/unit/test-app-iseq.rb +31 -0
  163. data/test/unit/test-app-options.rb +9 -1
  164. data/test/unit/test-app-util.rb +0 -1
  165. data/test/unit/test-base-cmd.rb +46 -0
  166. data/test/unit/test-base-subcmd.rb +11 -2
  167. data/test/unit/test-base-submgr.rb +23 -0
  168. data/test/unit/test-base-subsubcmd.rb +20 -0
  169. data/test/unit/test-cmd-break.rb +22 -23
  170. data/test/unit/test-cmd-help.rb +4 -0
  171. data/test/unit/test-completion.rb +43 -0
  172. data/test/unit/test-io-tcpclient.rb +3 -2
  173. data/test/unit/test-proc-load_cmds.rb +10 -1
  174. data/test/unit/test-proc-location.rb +39 -0
  175. data/test/unit/test-proc-main.rb +1 -1
  176. data/test/unit/test-proc-validate.rb +47 -31
  177. data/trepanning.gemspec +45 -0
  178. metadata +247 -179
  179. data/app/core.rb-consider +0 -198
  180. data/test/functional/tmp/b3.rb +0 -5
  181. data/test/functional/tmp/immediate-bug1.rb +0 -9
data/app/cmd_parse.rb ADDED
@@ -0,0 +1,201 @@
1
+ # use_grammar.rb
2
+ require 'rubygems'
3
+ require_relative 'cmd_parser'
4
+
5
+ class Trepan
6
+ module CmdParser
7
+
8
+ # Given a KPeg parse object, return the method of that parse or raise a
9
+ # Name error if we can't find a method. parent_class is the parent class of
10
+ # the object we've found so far and "binding" is used if we need
11
+ # to use eval to find the method.
12
+ def resolve_method(m, bind, parent_class = nil)
13
+ name = m.name
14
+ # DEBUG p name
15
+ errmsg = nil
16
+ if m.type == :constant
17
+ begin
18
+ if parent_class
19
+ klass = parent_class.const_get(m.chain[0].name)
20
+ else
21
+ errmsg = "Constant #{m} is not a class or module"
22
+ raise NameError, errmsg unless m.chain[0]
23
+ klass = eval(m.chain[0].name, bind)
24
+ end
25
+ errmsg = "Constant #{klass} is not a class or module" unless
26
+ raise NameError, errmsg unless
27
+ klass.kind_of?(Class) or klass.kind_of?(Module)
28
+ m = m.chain[1]
29
+ if klass.instance_methods.member?(:binding)
30
+ bind = klass.bind
31
+ elsif klass.private_instance_methods.member?(:binding)
32
+ bind = klass.send(:binding)
33
+ else
34
+ bind = nil
35
+ end
36
+ resolve_method(m, bind, klass)
37
+ rescue NameError
38
+ errmsg ||= "Can't resolve constant #{name}"
39
+ raise NameError, errmsg
40
+ end
41
+ else
42
+ is_class =
43
+ begin
44
+ m.chain && m.chain[0] &&
45
+ Class == eval("#{m.chain[0].name}.class", bind)
46
+ rescue
47
+ false
48
+ end
49
+ if is_class
50
+ # Handles stuff like:
51
+ # x = File
52
+ # x.basename
53
+ # Above, we tested we get a class back when we evalate m.chain[0]
54
+ # below. So it is safe to run the eval.
55
+ klass = eval("#{m.chain[0].name}", bind)
56
+ resolve_method(m.chain[1], klass.send(:binding), klass)
57
+ else
58
+ begin
59
+ errmsg = "Can't get method for #{name.inspect}"
60
+ if m.chain && m.chain[0]
61
+ parent_obj = eval("#{m.chain[0].name}", bind) if !parent_class && bind
62
+ end
63
+ parent = parent_class || parent_obj
64
+ meth =
65
+ if parent
66
+ errmsg << "in #{parent}"
67
+ lookup_name = m.chain && m.chain[1] ? m.chain[1].name : name
68
+ if parent.respond_to?('instance_methods') &&
69
+ parent.instance_methods.member?(lookup_name.to_sym)
70
+ parent.instance_method(lookup_name.to_sym)
71
+ elsif parent.respond_to?('methods')
72
+ parent.method(lookup_name.to_sym)
73
+ end
74
+ elsif m.chain && m.chain[1]
75
+ eval("#{m.chain[0].name}.method(#{lookup_name.name.inspect})", bind)
76
+ else
77
+ eval("self.method(#{name.inspect})", bind)
78
+ end
79
+ return meth
80
+ rescue
81
+ raise NameError, errmsg
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ # Return the method by evaluating parse_struct.
88
+ # nil is returned if we can't parse str
89
+ def meth_for_parse_struct(parse_struct, start_binding)
90
+ resolve_method(parse_struct, start_binding)
91
+ end
92
+
93
+ # Parse str and return the method associated with that.
94
+ # nil is returned if we can't parse str
95
+ def meth_for_string(str, start_binding)
96
+ @cp ? @cp.setup_parser(str) : @cp = CmdParse.new(str)
97
+ begin
98
+ if @cp._class_module_chain
99
+ # Did we match all of it?
100
+ if @cp.result.name == str.strip
101
+ meth_for_parse_struct(@cp.result, start_binding)
102
+ else
103
+ nil
104
+ end
105
+ else
106
+ # FIXME: change to raise ParseError?
107
+ nil
108
+ end
109
+ rescue NameError
110
+ return nil
111
+ end
112
+ end
113
+
114
+ def parse_terminal(terminal_name, loc_str)
115
+ @cp ? @cp.setup_parser(loc_str) : @cp = CmdParse.new(loc_str)
116
+ @cp.send(terminal_name) ? @cp : nil
117
+ end
118
+
119
+ def parse_location(loc_str)
120
+ parse = parse_terminal(:_location, loc_str)
121
+ parse ? parse.result : nil
122
+ end
123
+
124
+ def parse_breakpoint(str)
125
+ parse = parse_terminal(:_breakpoint_stmt, str)
126
+ parse ? parse.result : nil
127
+ end
128
+
129
+ def parse_breakpoint_no_condition(str)
130
+ parse = parse_terminal(:_breakpoint_stmt_no_condition, str)
131
+ parse ? parse.result : nil
132
+ end
133
+
134
+ def parse_list(str)
135
+ parse = parse_terminal(:_list_stmt, str)
136
+ parse ? parse.result : nil
137
+ end
138
+ end
139
+ end
140
+
141
+ if __FILE__ == $0
142
+ # Demo it.
143
+ %w(a a1 $global __FILE__ Constant 0 1e10 a.b).each do |name|
144
+ cp = CmdParse.new(name)
145
+ if cp._identifier && cp.result.name == name
146
+ p [cp.string, cp.result, 'succeeded']
147
+ else
148
+ puts "#{name} failed"
149
+ end
150
+ end
151
+
152
+ %w(Object A::B A::B::C A::B::C::D A::B.c A.b.c.d A(5)
153
+ RubyVM::InstructionSequence.new
154
+ ).each do |name|
155
+ cp = CmdParse.new(name)
156
+ if cp._class_module_chain && cp.result.name == name
157
+ p [cp.string, cp.result, 'succeeded']
158
+ else
159
+ puts "#{name} failed"
160
+ end
161
+ end
162
+
163
+ def five; 5 end
164
+ include Trepan::CmdParser
165
+ p meth_for_string('Array.map', binding)
166
+ p meth_for_string('Rubinius::VM.backtrace', binding)
167
+ %w(five
168
+ Array.map
169
+ RubyVM::InstructionSequence.new
170
+ Kernel.eval
171
+ Kernel::eval).each do |str|
172
+ meth = meth_for_string(str, binding)
173
+ p meth
174
+ end
175
+ module Testing
176
+ def testing; 5 end
177
+ module_function :testing
178
+ end
179
+ p meth_for_string('Testing.testing', binding)
180
+ p meth_for_string('File.basename', binding)
181
+ x = File
182
+ p meth_for_string('x.basename', binding)
183
+ def x.five; 5; end
184
+ p meth_for_string('x.five', binding)
185
+ p x.five
186
+
187
+ p parse_terminal(:_line_number, '5').result
188
+ p parse_terminal(:_vm_offset, '@5').result
189
+
190
+ # Location stuff
191
+ ['fn', 'fn 5', 'fn @5', '@5', '5'].each do |location|
192
+ p parse_location(location)
193
+ end
194
+
195
+ # Location stuff
196
+ ['fn if a > b', 'fn 5 unless c > d', 'fn:5 if x', '@5', '5'].each do |str|
197
+ p parse_breakpoint(str)
198
+ end
199
+
200
+ end
201
+
data/app/cmd_parser.rb ADDED
@@ -0,0 +1,1914 @@
1
+ class CmdParse
2
+ # STANDALONE START
3
+ def setup_parser(str, debug=false)
4
+ @string = str
5
+ @pos = 0
6
+ @memoizations = Hash.new { |h,k| h[k] = {} }
7
+ @result = nil
8
+ @failed_rule = nil
9
+ @failing_rule_offset = -1
10
+ end
11
+
12
+ # This is distinct from setup_parser so that a standalone parser
13
+ # can redefine #initialize and still have access to the proper
14
+ # parser setup code.
15
+ #
16
+ def initialize(str, debug=false)
17
+ setup_parser(str, debug)
18
+ end
19
+
20
+ attr_reader :string
21
+ attr_reader :result, :failing_rule_offset
22
+ attr_accessor :pos
23
+
24
+ # STANDALONE START
25
+ def current_column(target=pos)
26
+ if c = string.rindex("\n", target-1)
27
+ return target - c - 1
28
+ end
29
+
30
+ target + 1
31
+ end
32
+
33
+ def current_line(target=pos)
34
+ cur_offset = 0
35
+ cur_line = 0
36
+
37
+ string.each_line do |line|
38
+ cur_line += 1
39
+ cur_offset += line.size
40
+ return cur_line if cur_offset >= target
41
+ end
42
+
43
+ -1
44
+ end
45
+
46
+ def lines
47
+ lines = []
48
+ string.each_line { |l| lines << l }
49
+ lines
50
+ end
51
+
52
+ #
53
+
54
+ def get_text(start)
55
+ @string[start..@pos-1]
56
+ end
57
+
58
+ def show_pos
59
+ width = 10
60
+ if @pos < width
61
+ "#{@pos} (\"#{@string[0,@pos]}\" @ \"#{@string[@pos,width]}\")"
62
+ else
63
+ "#{@pos} (\"... #{@string[@pos - width, width]}\" @ \"#{@string[@pos,width]}\")"
64
+ end
65
+ end
66
+
67
+ def failure_info
68
+ l = current_line @failing_rule_offset
69
+ c = current_column @failing_rule_offset
70
+ info = self.class::Rules[@failed_rule]
71
+
72
+ "line #{l}, column #{c}: failed rule '#{info.name}' = '#{info.rendered}'"
73
+ end
74
+
75
+ def failure_caret
76
+ l = current_line @failing_rule_offset
77
+ c = current_column @failing_rule_offset
78
+
79
+ line = lines[l-1]
80
+ "#{line}\n#{' ' * (c - 1)}^"
81
+ end
82
+
83
+ def failure_character
84
+ l = current_line @failing_rule_offset
85
+ c = current_column @failing_rule_offset
86
+ lines[l-1][c-1, 1]
87
+ end
88
+
89
+ def failure_oneline
90
+ l = current_line @failing_rule_offset
91
+ c = current_column @failing_rule_offset
92
+
93
+ info = self.class::Rules[@failed_rule]
94
+ char = lines[l-1][c-1, 1]
95
+
96
+ "@#{l}:#{c} failed rule '#{info.name}', got '#{char}'"
97
+ end
98
+
99
+ class ParseError < RuntimeError
100
+ end
101
+
102
+ def raise_error
103
+ raise ParseError, failure_oneline
104
+ end
105
+
106
+ def show_error(io=STDOUT)
107
+ error_pos = @failing_rule_offset
108
+ line_no = current_line(error_pos)
109
+ col_no = current_column(error_pos)
110
+
111
+ info = self.class::Rules[@failed_rule]
112
+ io.puts "On line #{line_no}, column #{col_no}:"
113
+ io.puts "Failed to match '#{info.rendered}' (rule '#{info.name}')"
114
+ io.puts "Got: #{string[error_pos,1].inspect}"
115
+ line = lines[line_no-1]
116
+ io.puts "=> #{line}"
117
+ io.print(" " * (col_no + 3))
118
+ io.puts "^"
119
+ end
120
+
121
+ def set_failed_rule(name)
122
+ if @pos > @failing_rule_offset
123
+ @failed_rule = name
124
+ @failing_rule_offset = @pos
125
+ end
126
+ end
127
+
128
+ attr_reader :failed_rule
129
+
130
+ def match_string(str)
131
+ len = str.size
132
+ if @string[pos,len] == str
133
+ @pos += len
134
+ return str
135
+ end
136
+
137
+ return nil
138
+ end
139
+
140
+ def scan(reg)
141
+ if m = reg.match(@string[@pos..-1])
142
+ width = m.end(0)
143
+ @pos += width
144
+ return true
145
+ end
146
+
147
+ return nil
148
+ end
149
+
150
+ if "".respond_to? :getbyte
151
+ def get_byte
152
+ if @pos >= @string.size
153
+ return nil
154
+ end
155
+
156
+ s = @string.getbyte @pos
157
+ @pos += 1
158
+ s
159
+ end
160
+ else
161
+ def get_byte
162
+ if @pos >= @string.size
163
+ return nil
164
+ end
165
+
166
+ s = @string[@pos]
167
+ @pos += 1
168
+ s
169
+ end
170
+ end
171
+
172
+ def parse
173
+ _root ? true : false
174
+ end
175
+
176
+ class LeftRecursive
177
+ def initialize(detected=false)
178
+ @detected = detected
179
+ end
180
+
181
+ attr_accessor :detected
182
+ end
183
+
184
+ class MemoEntry
185
+ def initialize(ans, pos)
186
+ @ans = ans
187
+ @pos = pos
188
+ @uses = 1
189
+ @result = nil
190
+ end
191
+
192
+ attr_reader :ans, :pos, :uses, :result
193
+
194
+ def inc!
195
+ @uses += 1
196
+ end
197
+
198
+ def move!(ans, pos, result)
199
+ @ans = ans
200
+ @pos = pos
201
+ @result = result
202
+ end
203
+ end
204
+
205
+ def apply(rule)
206
+ if m = @memoizations[rule][@pos]
207
+ m.inc!
208
+
209
+ prev = @pos
210
+ @pos = m.pos
211
+ if m.ans.kind_of? LeftRecursive
212
+ m.ans.detected = true
213
+ return nil
214
+ end
215
+
216
+ @result = m.result
217
+
218
+ return m.ans
219
+ else
220
+ lr = LeftRecursive.new(false)
221
+ m = MemoEntry.new(lr, @pos)
222
+ @memoizations[rule][@pos] = m
223
+ start_pos = @pos
224
+
225
+ ans = __send__ rule
226
+
227
+ m.move! ans, @pos, @result
228
+
229
+ # Don't bother trying to grow the left recursion
230
+ # if it's failing straight away (thus there is no seed)
231
+ if ans and lr.detected
232
+ return grow_lr(rule, start_pos, m)
233
+ else
234
+ return ans
235
+ end
236
+
237
+ return ans
238
+ end
239
+ end
240
+
241
+ def grow_lr(rule, start_pos, m)
242
+ while true
243
+ @pos = start_pos
244
+ @result = m.result
245
+
246
+ ans = __send__ rule
247
+ return nil unless ans
248
+
249
+ break if @pos <= m.pos
250
+
251
+ m.move! ans, @pos, @result
252
+ end
253
+
254
+ @result = m.result
255
+ @pos = m.pos
256
+ return m.ans
257
+ end
258
+
259
+ class RuleInfo
260
+ def initialize(name, rendered)
261
+ @name = name
262
+ @rendered = rendered
263
+ end
264
+
265
+ attr_reader :name, :rendered
266
+ end
267
+
268
+ def self.rule_info(name, rendered)
269
+ RuleInfo.new(name, rendered)
270
+ end
271
+
272
+ #
273
+
274
+
275
+ #####################################################
276
+ # Structure to hold composite method names
277
+ SymbolEntry = Struct.new(:type, :name, :chain)
278
+
279
+
280
+ # Structure to hold position information
281
+ Position = Struct.new(:container_type, :container,
282
+ :position_type, :position)
283
+
284
+ # Structure to hold breakpoint information
285
+ Breakpoint = Struct.new(:position, :negate, :condition)
286
+
287
+ # Structure to hold list information
288
+ List = Struct.new(:position, :num)
289
+
290
+
291
+
292
+
293
+ # upcase_letter = /[A-Z]/
294
+ def _upcase_letter
295
+ _tmp = scan(/\A(?-mix:[A-Z])/)
296
+ set_failed_rule :_upcase_letter unless _tmp
297
+ return _tmp
298
+ end
299
+
300
+ # downcase_letter = /[a-z]/
301
+ def _downcase_letter
302
+ _tmp = scan(/\A(?-mix:[a-z])/)
303
+ set_failed_rule :_downcase_letter unless _tmp
304
+ return _tmp
305
+ end
306
+
307
+ # suffix_letter = /[=!?]/
308
+ def _suffix_letter
309
+ _tmp = scan(/\A(?-mix:[=!?])/)
310
+ set_failed_rule :_suffix_letter unless _tmp
311
+ return _tmp
312
+ end
313
+
314
+ # letter = (upcase_letter | downcase_letter)
315
+ def _letter
316
+
317
+ _save = self.pos
318
+ while true # choice
319
+ _tmp = apply(:_upcase_letter)
320
+ break if _tmp
321
+ self.pos = _save
322
+ _tmp = apply(:_downcase_letter)
323
+ break if _tmp
324
+ self.pos = _save
325
+ break
326
+ end # end choice
327
+
328
+ set_failed_rule :_letter unless _tmp
329
+ return _tmp
330
+ end
331
+
332
+ # id_symbol = (letter | "_" | [0-9])
333
+ def _id_symbol
334
+
335
+ _save = self.pos
336
+ while true # choice
337
+ _tmp = apply(:_letter)
338
+ break if _tmp
339
+ self.pos = _save
340
+ _tmp = match_string("_")
341
+ break if _tmp
342
+ self.pos = _save
343
+ _save1 = self.pos
344
+ _tmp = get_byte
345
+ if _tmp
346
+ unless _tmp >= 48 and _tmp <= 57
347
+ self.pos = _save1
348
+ _tmp = nil
349
+ end
350
+ end
351
+ break if _tmp
352
+ self.pos = _save
353
+ break
354
+ end # end choice
355
+
356
+ set_failed_rule :_id_symbol unless _tmp
357
+ return _tmp
358
+ end
359
+
360
+ # vm_identifier = < (downcase_letter | "_") id_symbol* suffix_letter? > { SymbolEntry.new(:variable, text) }
361
+ def _vm_identifier
362
+
363
+ _save = self.pos
364
+ while true # sequence
365
+ _text_start = self.pos
366
+
367
+ _save1 = self.pos
368
+ while true # sequence
369
+
370
+ _save2 = self.pos
371
+ while true # choice
372
+ _tmp = apply(:_downcase_letter)
373
+ break if _tmp
374
+ self.pos = _save2
375
+ _tmp = match_string("_")
376
+ break if _tmp
377
+ self.pos = _save2
378
+ break
379
+ end # end choice
380
+
381
+ unless _tmp
382
+ self.pos = _save1
383
+ break
384
+ end
385
+ while true
386
+ _tmp = apply(:_id_symbol)
387
+ break unless _tmp
388
+ end
389
+ _tmp = true
390
+ unless _tmp
391
+ self.pos = _save1
392
+ break
393
+ end
394
+ _save4 = self.pos
395
+ _tmp = apply(:_suffix_letter)
396
+ unless _tmp
397
+ _tmp = true
398
+ self.pos = _save4
399
+ end
400
+ unless _tmp
401
+ self.pos = _save1
402
+ end
403
+ break
404
+ end # end sequence
405
+
406
+ if _tmp
407
+ text = get_text(_text_start)
408
+ end
409
+ unless _tmp
410
+ self.pos = _save
411
+ break
412
+ end
413
+ @result = begin;
414
+ SymbolEntry.new(:variable, text)
415
+ ; end
416
+ _tmp = true
417
+ unless _tmp
418
+ self.pos = _save
419
+ end
420
+ break
421
+ end # end sequence
422
+
423
+ set_failed_rule :_vm_identifier unless _tmp
424
+ return _tmp
425
+ end
426
+
427
+ # variable_identifier = < (downcase_letter | "_") id_symbol* > { SymbolEntry.new(:variable, text) }
428
+ def _variable_identifier
429
+
430
+ _save = self.pos
431
+ while true # sequence
432
+ _text_start = self.pos
433
+
434
+ _save1 = self.pos
435
+ while true # sequence
436
+
437
+ _save2 = self.pos
438
+ while true # choice
439
+ _tmp = apply(:_downcase_letter)
440
+ break if _tmp
441
+ self.pos = _save2
442
+ _tmp = match_string("_")
443
+ break if _tmp
444
+ self.pos = _save2
445
+ break
446
+ end # end choice
447
+
448
+ unless _tmp
449
+ self.pos = _save1
450
+ break
451
+ end
452
+ while true
453
+ _tmp = apply(:_id_symbol)
454
+ break unless _tmp
455
+ end
456
+ _tmp = true
457
+ unless _tmp
458
+ self.pos = _save1
459
+ end
460
+ break
461
+ end # end sequence
462
+
463
+ if _tmp
464
+ text = get_text(_text_start)
465
+ end
466
+ unless _tmp
467
+ self.pos = _save
468
+ break
469
+ end
470
+ @result = begin;
471
+ SymbolEntry.new(:variable, text)
472
+ ; end
473
+ _tmp = true
474
+ unless _tmp
475
+ self.pos = _save
476
+ end
477
+ break
478
+ end # end sequence
479
+
480
+ set_failed_rule :_variable_identifier unless _tmp
481
+ return _tmp
482
+ end
483
+
484
+ # constant_identifier = < upcase_letter id_symbol* > { SymbolEntry.new(:constant, text) }
485
+ def _constant_identifier
486
+
487
+ _save = self.pos
488
+ while true # sequence
489
+ _text_start = self.pos
490
+
491
+ _save1 = self.pos
492
+ while true # sequence
493
+ _tmp = apply(:_upcase_letter)
494
+ unless _tmp
495
+ self.pos = _save1
496
+ break
497
+ end
498
+ while true
499
+ _tmp = apply(:_id_symbol)
500
+ break unless _tmp
501
+ end
502
+ _tmp = true
503
+ unless _tmp
504
+ self.pos = _save1
505
+ end
506
+ break
507
+ end # end sequence
508
+
509
+ if _tmp
510
+ text = get_text(_text_start)
511
+ end
512
+ unless _tmp
513
+ self.pos = _save
514
+ break
515
+ end
516
+ @result = begin;
517
+ SymbolEntry.new(:constant, text)
518
+ ; end
519
+ _tmp = true
520
+ unless _tmp
521
+ self.pos = _save
522
+ end
523
+ break
524
+ end # end sequence
525
+
526
+ set_failed_rule :_constant_identifier unless _tmp
527
+ return _tmp
528
+ end
529
+
530
+ # global_identifier = < "$" (constant_identifier | variable_identifier) > { SymbolEntry.new(:global, text) }
531
+ def _global_identifier
532
+
533
+ _save = self.pos
534
+ while true # sequence
535
+ _text_start = self.pos
536
+
537
+ _save1 = self.pos
538
+ while true # sequence
539
+ _tmp = match_string("$")
540
+ unless _tmp
541
+ self.pos = _save1
542
+ break
543
+ end
544
+
545
+ _save2 = self.pos
546
+ while true # choice
547
+ _tmp = apply(:_constant_identifier)
548
+ break if _tmp
549
+ self.pos = _save2
550
+ _tmp = apply(:_variable_identifier)
551
+ break if _tmp
552
+ self.pos = _save2
553
+ break
554
+ end # end choice
555
+
556
+ unless _tmp
557
+ self.pos = _save1
558
+ end
559
+ break
560
+ end # end sequence
561
+
562
+ if _tmp
563
+ text = get_text(_text_start)
564
+ end
565
+ unless _tmp
566
+ self.pos = _save
567
+ break
568
+ end
569
+ @result = begin;
570
+ SymbolEntry.new(:global, text)
571
+ ; end
572
+ _tmp = true
573
+ unless _tmp
574
+ self.pos = _save
575
+ end
576
+ break
577
+ end # end sequence
578
+
579
+ set_failed_rule :_global_identifier unless _tmp
580
+ return _tmp
581
+ end
582
+
583
+ # local_internal_identifier = (constant_identifier | variable_identifier)
584
+ def _local_internal_identifier
585
+
586
+ _save = self.pos
587
+ while true # choice
588
+ _tmp = apply(:_constant_identifier)
589
+ break if _tmp
590
+ self.pos = _save
591
+ _tmp = apply(:_variable_identifier)
592
+ break if _tmp
593
+ self.pos = _save
594
+ break
595
+ end # end choice
596
+
597
+ set_failed_rule :_local_internal_identifier unless _tmp
598
+ return _tmp
599
+ end
600
+
601
+ # local_identifier = (constant_identifier | vm_identifier)
602
+ def _local_identifier
603
+
604
+ _save = self.pos
605
+ while true # choice
606
+ _tmp = apply(:_constant_identifier)
607
+ break if _tmp
608
+ self.pos = _save
609
+ _tmp = apply(:_vm_identifier)
610
+ break if _tmp
611
+ self.pos = _save
612
+ break
613
+ end # end choice
614
+
615
+ set_failed_rule :_local_identifier unless _tmp
616
+ return _tmp
617
+ end
618
+
619
+ # instance_identifier = < "@" local_identifier > { SymbolEntry.new(:instance, text) }
620
+ def _instance_identifier
621
+
622
+ _save = self.pos
623
+ while true # sequence
624
+ _text_start = self.pos
625
+
626
+ _save1 = self.pos
627
+ while true # sequence
628
+ _tmp = match_string("@")
629
+ unless _tmp
630
+ self.pos = _save1
631
+ break
632
+ end
633
+ _tmp = apply(:_local_identifier)
634
+ unless _tmp
635
+ self.pos = _save1
636
+ end
637
+ break
638
+ end # end sequence
639
+
640
+ if _tmp
641
+ text = get_text(_text_start)
642
+ end
643
+ unless _tmp
644
+ self.pos = _save
645
+ break
646
+ end
647
+ @result = begin;
648
+ SymbolEntry.new(:instance, text)
649
+ ; end
650
+ _tmp = true
651
+ unless _tmp
652
+ self.pos = _save
653
+ end
654
+ break
655
+ end # end sequence
656
+
657
+ set_failed_rule :_instance_identifier unless _tmp
658
+ return _tmp
659
+ end
660
+
661
+ # classvar_identifier = "@@" local_identifier:id { SymbolEntry.new(:classvar, id) }
662
+ def _classvar_identifier
663
+
664
+ _save = self.pos
665
+ while true # sequence
666
+ _tmp = match_string("@@")
667
+ unless _tmp
668
+ self.pos = _save
669
+ break
670
+ end
671
+ _tmp = apply(:_local_identifier)
672
+ id = @result
673
+ unless _tmp
674
+ self.pos = _save
675
+ break
676
+ end
677
+ @result = begin;
678
+ SymbolEntry.new(:classvar, id)
679
+ ; end
680
+ _tmp = true
681
+ unless _tmp
682
+ self.pos = _save
683
+ end
684
+ break
685
+ end # end sequence
686
+
687
+ set_failed_rule :_classvar_identifier unless _tmp
688
+ return _tmp
689
+ end
690
+
691
+ # identifier = (global_identifier | instance_identifier | classvar_identifier | local_identifier)
692
+ def _identifier
693
+
694
+ _save = self.pos
695
+ while true # choice
696
+ _tmp = apply(:_global_identifier)
697
+ break if _tmp
698
+ self.pos = _save
699
+ _tmp = apply(:_instance_identifier)
700
+ break if _tmp
701
+ self.pos = _save
702
+ _tmp = apply(:_classvar_identifier)
703
+ break if _tmp
704
+ self.pos = _save
705
+ _tmp = apply(:_local_identifier)
706
+ break if _tmp
707
+ self.pos = _save
708
+ break
709
+ end # end choice
710
+
711
+ set_failed_rule :_identifier unless _tmp
712
+ return _tmp
713
+ end
714
+
715
+ # id_separator = < ("::" | ".") > { text }
716
+ def _id_separator
717
+
718
+ _save = self.pos
719
+ while true # sequence
720
+ _text_start = self.pos
721
+
722
+ _save1 = self.pos
723
+ while true # choice
724
+ _tmp = match_string("::")
725
+ break if _tmp
726
+ self.pos = _save1
727
+ _tmp = match_string(".")
728
+ break if _tmp
729
+ self.pos = _save1
730
+ break
731
+ end # end choice
732
+
733
+ if _tmp
734
+ text = get_text(_text_start)
735
+ end
736
+ unless _tmp
737
+ self.pos = _save
738
+ break
739
+ end
740
+ @result = begin; text ; end
741
+ _tmp = true
742
+ unless _tmp
743
+ self.pos = _save
744
+ end
745
+ break
746
+ end # end sequence
747
+
748
+ set_failed_rule :_id_separator unless _tmp
749
+ return _tmp
750
+ end
751
+
752
+ # internal_class_module_chain = (< local_internal_identifier:parent id_separator:sep internal_class_module_chain:child > { SymbolEntry.new(parent.type, text, [parent, child, sep]) } | local_identifier)
753
+ def _internal_class_module_chain
754
+
755
+ _save = self.pos
756
+ while true # choice
757
+
758
+ _save1 = self.pos
759
+ while true # sequence
760
+ _text_start = self.pos
761
+
762
+ _save2 = self.pos
763
+ while true # sequence
764
+ _tmp = apply(:_local_internal_identifier)
765
+ parent = @result
766
+ unless _tmp
767
+ self.pos = _save2
768
+ break
769
+ end
770
+ _tmp = apply(:_id_separator)
771
+ sep = @result
772
+ unless _tmp
773
+ self.pos = _save2
774
+ break
775
+ end
776
+ _tmp = apply(:_internal_class_module_chain)
777
+ child = @result
778
+ unless _tmp
779
+ self.pos = _save2
780
+ end
781
+ break
782
+ end # end sequence
783
+
784
+ if _tmp
785
+ text = get_text(_text_start)
786
+ end
787
+ unless _tmp
788
+ self.pos = _save1
789
+ break
790
+ end
791
+ @result = begin;
792
+ SymbolEntry.new(parent.type, text, [parent, child, sep])
793
+ ; end
794
+ _tmp = true
795
+ unless _tmp
796
+ self.pos = _save1
797
+ end
798
+ break
799
+ end # end sequence
800
+
801
+ break if _tmp
802
+ self.pos = _save
803
+ _tmp = apply(:_local_identifier)
804
+ break if _tmp
805
+ self.pos = _save
806
+ break
807
+ end # end choice
808
+
809
+ set_failed_rule :_internal_class_module_chain unless _tmp
810
+ return _tmp
811
+ end
812
+
813
+ # class_module_chain = (< identifier:parent id_separator:sep internal_class_module_chain:child > { SymbolEntry.new(parent.type, text, [parent, child, sep]) } | identifier)
814
+ def _class_module_chain
815
+
816
+ _save = self.pos
817
+ while true # choice
818
+
819
+ _save1 = self.pos
820
+ while true # sequence
821
+ _text_start = self.pos
822
+
823
+ _save2 = self.pos
824
+ while true # sequence
825
+ _tmp = apply(:_identifier)
826
+ parent = @result
827
+ unless _tmp
828
+ self.pos = _save2
829
+ break
830
+ end
831
+ _tmp = apply(:_id_separator)
832
+ sep = @result
833
+ unless _tmp
834
+ self.pos = _save2
835
+ break
836
+ end
837
+ _tmp = apply(:_internal_class_module_chain)
838
+ child = @result
839
+ unless _tmp
840
+ self.pos = _save2
841
+ end
842
+ break
843
+ end # end sequence
844
+
845
+ if _tmp
846
+ text = get_text(_text_start)
847
+ end
848
+ unless _tmp
849
+ self.pos = _save1
850
+ break
851
+ end
852
+ @result = begin;
853
+ SymbolEntry.new(parent.type, text, [parent, child, sep])
854
+ ; end
855
+ _tmp = true
856
+ unless _tmp
857
+ self.pos = _save1
858
+ end
859
+ break
860
+ end # end sequence
861
+
862
+ break if _tmp
863
+ self.pos = _save
864
+ _tmp = apply(:_identifier)
865
+ break if _tmp
866
+ self.pos = _save
867
+ break
868
+ end # end choice
869
+
870
+ set_failed_rule :_class_module_chain unless _tmp
871
+ return _tmp
872
+ end
873
+
874
+ # sp = /[ \t]/
875
+ def _sp
876
+ _tmp = scan(/\A(?-mix:[ \t])/)
877
+ set_failed_rule :_sp unless _tmp
878
+ return _tmp
879
+ end
880
+
881
+ # - = sp+
882
+ def __hyphen_
883
+ _save = self.pos
884
+ _tmp = apply(:_sp)
885
+ if _tmp
886
+ while true
887
+ _tmp = apply(:_sp)
888
+ break unless _tmp
889
+ end
890
+ _tmp = true
891
+ else
892
+ self.pos = _save
893
+ end
894
+ set_failed_rule :__hyphen_ unless _tmp
895
+ return _tmp
896
+ end
897
+
898
+ # dbl_escapes = ("\\\"" { '"' } | "\\n" { "\n" } | "\\t" { "\t" } | "\\\\" { "\\" })
899
+ def _dbl_escapes
900
+
901
+ _save = self.pos
902
+ while true # choice
903
+
904
+ _save1 = self.pos
905
+ while true # sequence
906
+ _tmp = match_string("\\\"")
907
+ unless _tmp
908
+ self.pos = _save1
909
+ break
910
+ end
911
+ @result = begin; '"' ; end
912
+ _tmp = true
913
+ unless _tmp
914
+ self.pos = _save1
915
+ end
916
+ break
917
+ end # end sequence
918
+
919
+ break if _tmp
920
+ self.pos = _save
921
+
922
+ _save2 = self.pos
923
+ while true # sequence
924
+ _tmp = match_string("\\n")
925
+ unless _tmp
926
+ self.pos = _save2
927
+ break
928
+ end
929
+ @result = begin; "\n" ; end
930
+ _tmp = true
931
+ unless _tmp
932
+ self.pos = _save2
933
+ end
934
+ break
935
+ end # end sequence
936
+
937
+ break if _tmp
938
+ self.pos = _save
939
+
940
+ _save3 = self.pos
941
+ while true # sequence
942
+ _tmp = match_string("\\t")
943
+ unless _tmp
944
+ self.pos = _save3
945
+ break
946
+ end
947
+ @result = begin; "\t" ; end
948
+ _tmp = true
949
+ unless _tmp
950
+ self.pos = _save3
951
+ end
952
+ break
953
+ end # end sequence
954
+
955
+ break if _tmp
956
+ self.pos = _save
957
+
958
+ _save4 = self.pos
959
+ while true # sequence
960
+ _tmp = match_string("\\\\")
961
+ unless _tmp
962
+ self.pos = _save4
963
+ break
964
+ end
965
+ @result = begin; "\\" ; end
966
+ _tmp = true
967
+ unless _tmp
968
+ self.pos = _save4
969
+ end
970
+ break
971
+ end # end sequence
972
+
973
+ break if _tmp
974
+ self.pos = _save
975
+ break
976
+ end # end choice
977
+
978
+ set_failed_rule :_dbl_escapes unless _tmp
979
+ return _tmp
980
+ end
981
+
982
+ # escapes = ("\\\"" { '"' } | "\\n" { "\n" } | "\\t" { "\t" } | "\\ " { " " } | "\\:" { ":" } | "\\\\" { "\\" })
983
+ def _escapes
984
+
985
+ _save = self.pos
986
+ while true # choice
987
+
988
+ _save1 = self.pos
989
+ while true # sequence
990
+ _tmp = match_string("\\\"")
991
+ unless _tmp
992
+ self.pos = _save1
993
+ break
994
+ end
995
+ @result = begin; '"' ; end
996
+ _tmp = true
997
+ unless _tmp
998
+ self.pos = _save1
999
+ end
1000
+ break
1001
+ end # end sequence
1002
+
1003
+ break if _tmp
1004
+ self.pos = _save
1005
+
1006
+ _save2 = self.pos
1007
+ while true # sequence
1008
+ _tmp = match_string("\\n")
1009
+ unless _tmp
1010
+ self.pos = _save2
1011
+ break
1012
+ end
1013
+ @result = begin; "\n" ; end
1014
+ _tmp = true
1015
+ unless _tmp
1016
+ self.pos = _save2
1017
+ end
1018
+ break
1019
+ end # end sequence
1020
+
1021
+ break if _tmp
1022
+ self.pos = _save
1023
+
1024
+ _save3 = self.pos
1025
+ while true # sequence
1026
+ _tmp = match_string("\\t")
1027
+ unless _tmp
1028
+ self.pos = _save3
1029
+ break
1030
+ end
1031
+ @result = begin; "\t" ; end
1032
+ _tmp = true
1033
+ unless _tmp
1034
+ self.pos = _save3
1035
+ end
1036
+ break
1037
+ end # end sequence
1038
+
1039
+ break if _tmp
1040
+ self.pos = _save
1041
+
1042
+ _save4 = self.pos
1043
+ while true # sequence
1044
+ _tmp = match_string("\\ ")
1045
+ unless _tmp
1046
+ self.pos = _save4
1047
+ break
1048
+ end
1049
+ @result = begin; " " ; end
1050
+ _tmp = true
1051
+ unless _tmp
1052
+ self.pos = _save4
1053
+ end
1054
+ break
1055
+ end # end sequence
1056
+
1057
+ break if _tmp
1058
+ self.pos = _save
1059
+
1060
+ _save5 = self.pos
1061
+ while true # sequence
1062
+ _tmp = match_string("\\:")
1063
+ unless _tmp
1064
+ self.pos = _save5
1065
+ break
1066
+ end
1067
+ @result = begin; ":" ; end
1068
+ _tmp = true
1069
+ unless _tmp
1070
+ self.pos = _save5
1071
+ end
1072
+ break
1073
+ end # end sequence
1074
+
1075
+ break if _tmp
1076
+ self.pos = _save
1077
+
1078
+ _save6 = self.pos
1079
+ while true # sequence
1080
+ _tmp = match_string("\\\\")
1081
+ unless _tmp
1082
+ self.pos = _save6
1083
+ break
1084
+ end
1085
+ @result = begin; "\\" ; end
1086
+ _tmp = true
1087
+ unless _tmp
1088
+ self.pos = _save6
1089
+ end
1090
+ break
1091
+ end # end sequence
1092
+
1093
+ break if _tmp
1094
+ self.pos = _save
1095
+ break
1096
+ end # end choice
1097
+
1098
+ set_failed_rule :_escapes unless _tmp
1099
+ return _tmp
1100
+ end
1101
+
1102
+ # dbl_seq = < /[^\\"]+/ > { text }
1103
+ def _dbl_seq
1104
+
1105
+ _save = self.pos
1106
+ while true # sequence
1107
+ _text_start = self.pos
1108
+ _tmp = scan(/\A(?-mix:[^\\"]+)/)
1109
+ if _tmp
1110
+ text = get_text(_text_start)
1111
+ end
1112
+ unless _tmp
1113
+ self.pos = _save
1114
+ break
1115
+ end
1116
+ @result = begin; text ; end
1117
+ _tmp = true
1118
+ unless _tmp
1119
+ self.pos = _save
1120
+ end
1121
+ break
1122
+ end # end sequence
1123
+
1124
+ set_failed_rule :_dbl_seq unless _tmp
1125
+ return _tmp
1126
+ end
1127
+
1128
+ # dbl_not_quote = (dbl_escapes | dbl_seq)+:ary { ary }
1129
+ def _dbl_not_quote
1130
+
1131
+ _save = self.pos
1132
+ while true # sequence
1133
+ _save1 = self.pos
1134
+ _ary = []
1135
+
1136
+ _save2 = self.pos
1137
+ while true # choice
1138
+ _tmp = apply(:_dbl_escapes)
1139
+ break if _tmp
1140
+ self.pos = _save2
1141
+ _tmp = apply(:_dbl_seq)
1142
+ break if _tmp
1143
+ self.pos = _save2
1144
+ break
1145
+ end # end choice
1146
+
1147
+ if _tmp
1148
+ _ary << @result
1149
+ while true
1150
+
1151
+ _save3 = self.pos
1152
+ while true # choice
1153
+ _tmp = apply(:_dbl_escapes)
1154
+ break if _tmp
1155
+ self.pos = _save3
1156
+ _tmp = apply(:_dbl_seq)
1157
+ break if _tmp
1158
+ self.pos = _save3
1159
+ break
1160
+ end # end choice
1161
+
1162
+ _ary << @result if _tmp
1163
+ break unless _tmp
1164
+ end
1165
+ _tmp = true
1166
+ @result = _ary
1167
+ else
1168
+ self.pos = _save1
1169
+ end
1170
+ ary = @result
1171
+ unless _tmp
1172
+ self.pos = _save
1173
+ break
1174
+ end
1175
+ @result = begin; ary ; end
1176
+ _tmp = true
1177
+ unless _tmp
1178
+ self.pos = _save
1179
+ end
1180
+ break
1181
+ end # end sequence
1182
+
1183
+ set_failed_rule :_dbl_not_quote unless _tmp
1184
+ return _tmp
1185
+ end
1186
+
1187
+ # dbl_string = "\"" dbl_not_quote:ary "\"" { ary.join }
1188
+ def _dbl_string
1189
+
1190
+ _save = self.pos
1191
+ while true # sequence
1192
+ _tmp = match_string("\"")
1193
+ unless _tmp
1194
+ self.pos = _save
1195
+ break
1196
+ end
1197
+ _tmp = apply(:_dbl_not_quote)
1198
+ ary = @result
1199
+ unless _tmp
1200
+ self.pos = _save
1201
+ break
1202
+ end
1203
+ _tmp = match_string("\"")
1204
+ unless _tmp
1205
+ self.pos = _save
1206
+ break
1207
+ end
1208
+ @result = begin; ary.join ; end
1209
+ _tmp = true
1210
+ unless _tmp
1211
+ self.pos = _save
1212
+ end
1213
+ break
1214
+ end # end sequence
1215
+
1216
+ set_failed_rule :_dbl_string unless _tmp
1217
+ return _tmp
1218
+ end
1219
+
1220
+ # not_space_colon = (escapes | < /[^ \t\n:]/ > { text })
1221
+ def _not_space_colon
1222
+
1223
+ _save = self.pos
1224
+ while true # choice
1225
+ _tmp = apply(:_escapes)
1226
+ break if _tmp
1227
+ self.pos = _save
1228
+
1229
+ _save1 = self.pos
1230
+ while true # sequence
1231
+ _text_start = self.pos
1232
+ _tmp = scan(/\A(?-mix:[^ \t\n:])/)
1233
+ if _tmp
1234
+ text = get_text(_text_start)
1235
+ end
1236
+ unless _tmp
1237
+ self.pos = _save1
1238
+ break
1239
+ end
1240
+ @result = begin; text ; end
1241
+ _tmp = true
1242
+ unless _tmp
1243
+ self.pos = _save1
1244
+ end
1245
+ break
1246
+ end # end sequence
1247
+
1248
+ break if _tmp
1249
+ self.pos = _save
1250
+ break
1251
+ end # end choice
1252
+
1253
+ set_failed_rule :_not_space_colon unless _tmp
1254
+ return _tmp
1255
+ end
1256
+
1257
+ # not_space_colons = not_space_colon+:ary { ary.join }
1258
+ def _not_space_colons
1259
+
1260
+ _save = self.pos
1261
+ while true # sequence
1262
+ _save1 = self.pos
1263
+ _ary = []
1264
+ _tmp = apply(:_not_space_colon)
1265
+ if _tmp
1266
+ _ary << @result
1267
+ while true
1268
+ _tmp = apply(:_not_space_colon)
1269
+ _ary << @result if _tmp
1270
+ break unless _tmp
1271
+ end
1272
+ _tmp = true
1273
+ @result = _ary
1274
+ else
1275
+ self.pos = _save1
1276
+ end
1277
+ ary = @result
1278
+ unless _tmp
1279
+ self.pos = _save
1280
+ break
1281
+ end
1282
+ @result = begin; ary.join ; end
1283
+ _tmp = true
1284
+ unless _tmp
1285
+ self.pos = _save
1286
+ end
1287
+ break
1288
+ end # end sequence
1289
+
1290
+ set_failed_rule :_not_space_colons unless _tmp
1291
+ return _tmp
1292
+ end
1293
+
1294
+ # filename = (dbl_string | not_space_colons)
1295
+ def _filename
1296
+
1297
+ _save = self.pos
1298
+ while true # choice
1299
+ _tmp = apply(:_dbl_string)
1300
+ break if _tmp
1301
+ self.pos = _save
1302
+ _tmp = apply(:_not_space_colons)
1303
+ break if _tmp
1304
+ self.pos = _save
1305
+ break
1306
+ end # end choice
1307
+
1308
+ set_failed_rule :_filename unless _tmp
1309
+ return _tmp
1310
+ end
1311
+
1312
+ # file_pos_sep = (sp+ | ":")
1313
+ def _file_pos_sep
1314
+
1315
+ _save = self.pos
1316
+ while true # choice
1317
+ _save1 = self.pos
1318
+ _tmp = apply(:_sp)
1319
+ if _tmp
1320
+ while true
1321
+ _tmp = apply(:_sp)
1322
+ break unless _tmp
1323
+ end
1324
+ _tmp = true
1325
+ else
1326
+ self.pos = _save1
1327
+ end
1328
+ break if _tmp
1329
+ self.pos = _save
1330
+ _tmp = match_string(":")
1331
+ break if _tmp
1332
+ self.pos = _save
1333
+ break
1334
+ end # end choice
1335
+
1336
+ set_failed_rule :_file_pos_sep unless _tmp
1337
+ return _tmp
1338
+ end
1339
+
1340
+ # integer = < /[0-9]+/ > { text.to_i }
1341
+ def _integer
1342
+
1343
+ _save = self.pos
1344
+ while true # sequence
1345
+ _text_start = self.pos
1346
+ _tmp = scan(/\A(?-mix:[0-9]+)/)
1347
+ if _tmp
1348
+ text = get_text(_text_start)
1349
+ end
1350
+ unless _tmp
1351
+ self.pos = _save
1352
+ break
1353
+ end
1354
+ @result = begin; text.to_i ; end
1355
+ _tmp = true
1356
+ unless _tmp
1357
+ self.pos = _save
1358
+ end
1359
+ break
1360
+ end # end sequence
1361
+
1362
+ set_failed_rule :_integer unless _tmp
1363
+ return _tmp
1364
+ end
1365
+
1366
+ # line_number = integer
1367
+ def _line_number
1368
+ _tmp = apply(:_integer)
1369
+ set_failed_rule :_line_number unless _tmp
1370
+ return _tmp
1371
+ end
1372
+
1373
+ # vm_offset = "@" integer:int { Position.new(nil, nil, :offset, int) }
1374
+ def _vm_offset
1375
+
1376
+ _save = self.pos
1377
+ while true # sequence
1378
+ _tmp = match_string("@")
1379
+ unless _tmp
1380
+ self.pos = _save
1381
+ break
1382
+ end
1383
+ _tmp = apply(:_integer)
1384
+ int = @result
1385
+ unless _tmp
1386
+ self.pos = _save
1387
+ break
1388
+ end
1389
+ @result = begin;
1390
+ Position.new(nil, nil, :offset, int)
1391
+ ; end
1392
+ _tmp = true
1393
+ unless _tmp
1394
+ self.pos = _save
1395
+ end
1396
+ break
1397
+ end # end sequence
1398
+
1399
+ set_failed_rule :_vm_offset unless _tmp
1400
+ return _tmp
1401
+ end
1402
+
1403
+ # position = (vm_offset | line_number:l { Position.new(nil, nil, :line, l) })
1404
+ def _position
1405
+
1406
+ _save = self.pos
1407
+ while true # choice
1408
+ _tmp = apply(:_vm_offset)
1409
+ break if _tmp
1410
+ self.pos = _save
1411
+
1412
+ _save1 = self.pos
1413
+ while true # sequence
1414
+ _tmp = apply(:_line_number)
1415
+ l = @result
1416
+ unless _tmp
1417
+ self.pos = _save1
1418
+ break
1419
+ end
1420
+ @result = begin;
1421
+ Position.new(nil, nil, :line, l)
1422
+ ; end
1423
+ _tmp = true
1424
+ unless _tmp
1425
+ self.pos = _save1
1426
+ end
1427
+ break
1428
+ end # end sequence
1429
+
1430
+ break if _tmp
1431
+ self.pos = _save
1432
+ break
1433
+ end # end choice
1434
+
1435
+ set_failed_rule :_position unless _tmp
1436
+ return _tmp
1437
+ end
1438
+
1439
+ # location = (position | < filename >:file &{ File.exist?(file) } file_pos_sep position:pos { Position.new(:file, file, pos.position_type, pos.position) } | < filename >:file &{ File.exist?(file) } { Position.new(:file, file, nil, nil) } | class_module_chain?:fn file_pos_sep position:pos { Position.new(:fn, fn, pos.position_type, pos.position) } | class_module_chain?:fn { Position.new(:fn, fn, nil, nil) })
1440
+ def _location
1441
+
1442
+ _save = self.pos
1443
+ while true # choice
1444
+ _tmp = apply(:_position)
1445
+ break if _tmp
1446
+ self.pos = _save
1447
+
1448
+ _save1 = self.pos
1449
+ while true # sequence
1450
+ _text_start = self.pos
1451
+ _tmp = apply(:_filename)
1452
+ if _tmp
1453
+ text = get_text(_text_start)
1454
+ end
1455
+ file = @result
1456
+ unless _tmp
1457
+ self.pos = _save1
1458
+ break
1459
+ end
1460
+ _save2 = self.pos
1461
+ _tmp = begin; File.exist?(file) ; end
1462
+ self.pos = _save2
1463
+ unless _tmp
1464
+ self.pos = _save1
1465
+ break
1466
+ end
1467
+ _tmp = apply(:_file_pos_sep)
1468
+ unless _tmp
1469
+ self.pos = _save1
1470
+ break
1471
+ end
1472
+ _tmp = apply(:_position)
1473
+ pos = @result
1474
+ unless _tmp
1475
+ self.pos = _save1
1476
+ break
1477
+ end
1478
+ @result = begin;
1479
+ Position.new(:file, file, pos.position_type, pos.position)
1480
+ ; end
1481
+ _tmp = true
1482
+ unless _tmp
1483
+ self.pos = _save1
1484
+ end
1485
+ break
1486
+ end # end sequence
1487
+
1488
+ break if _tmp
1489
+ self.pos = _save
1490
+
1491
+ _save3 = self.pos
1492
+ while true # sequence
1493
+ _text_start = self.pos
1494
+ _tmp = apply(:_filename)
1495
+ if _tmp
1496
+ text = get_text(_text_start)
1497
+ end
1498
+ file = @result
1499
+ unless _tmp
1500
+ self.pos = _save3
1501
+ break
1502
+ end
1503
+ _save4 = self.pos
1504
+ _tmp = begin; File.exist?(file) ; end
1505
+ self.pos = _save4
1506
+ unless _tmp
1507
+ self.pos = _save3
1508
+ break
1509
+ end
1510
+ @result = begin;
1511
+ Position.new(:file, file, nil, nil)
1512
+ ; end
1513
+ _tmp = true
1514
+ unless _tmp
1515
+ self.pos = _save3
1516
+ end
1517
+ break
1518
+ end # end sequence
1519
+
1520
+ break if _tmp
1521
+ self.pos = _save
1522
+
1523
+ _save5 = self.pos
1524
+ while true # sequence
1525
+ _save6 = self.pos
1526
+ _tmp = apply(:_class_module_chain)
1527
+ @result = nil unless _tmp
1528
+ unless _tmp
1529
+ _tmp = true
1530
+ self.pos = _save6
1531
+ end
1532
+ fn = @result
1533
+ unless _tmp
1534
+ self.pos = _save5
1535
+ break
1536
+ end
1537
+ _tmp = apply(:_file_pos_sep)
1538
+ unless _tmp
1539
+ self.pos = _save5
1540
+ break
1541
+ end
1542
+ _tmp = apply(:_position)
1543
+ pos = @result
1544
+ unless _tmp
1545
+ self.pos = _save5
1546
+ break
1547
+ end
1548
+ @result = begin;
1549
+ Position.new(:fn, fn, pos.position_type, pos.position)
1550
+ ; end
1551
+ _tmp = true
1552
+ unless _tmp
1553
+ self.pos = _save5
1554
+ end
1555
+ break
1556
+ end # end sequence
1557
+
1558
+ break if _tmp
1559
+ self.pos = _save
1560
+
1561
+ _save7 = self.pos
1562
+ while true # sequence
1563
+ _save8 = self.pos
1564
+ _tmp = apply(:_class_module_chain)
1565
+ @result = nil unless _tmp
1566
+ unless _tmp
1567
+ _tmp = true
1568
+ self.pos = _save8
1569
+ end
1570
+ fn = @result
1571
+ unless _tmp
1572
+ self.pos = _save7
1573
+ break
1574
+ end
1575
+ @result = begin;
1576
+ Position.new(:fn, fn, nil, nil)
1577
+ ; end
1578
+ _tmp = true
1579
+ unless _tmp
1580
+ self.pos = _save7
1581
+ end
1582
+ break
1583
+ end # end sequence
1584
+
1585
+ break if _tmp
1586
+ self.pos = _save
1587
+ break
1588
+ end # end choice
1589
+
1590
+ set_failed_rule :_location unless _tmp
1591
+ return _tmp
1592
+ end
1593
+
1594
+ # if_unless = < ("if" | "unless") > { text }
1595
+ def _if_unless
1596
+
1597
+ _save = self.pos
1598
+ while true # sequence
1599
+ _text_start = self.pos
1600
+
1601
+ _save1 = self.pos
1602
+ while true # choice
1603
+ _tmp = match_string("if")
1604
+ break if _tmp
1605
+ self.pos = _save1
1606
+ _tmp = match_string("unless")
1607
+ break if _tmp
1608
+ self.pos = _save1
1609
+ break
1610
+ end # end choice
1611
+
1612
+ if _tmp
1613
+ text = get_text(_text_start)
1614
+ end
1615
+ unless _tmp
1616
+ self.pos = _save
1617
+ break
1618
+ end
1619
+ @result = begin; text ; end
1620
+ _tmp = true
1621
+ unless _tmp
1622
+ self.pos = _save
1623
+ end
1624
+ break
1625
+ end # end sequence
1626
+
1627
+ set_failed_rule :_if_unless unless _tmp
1628
+ return _tmp
1629
+ end
1630
+
1631
+ # condition = < /.+/ > { text}
1632
+ def _condition
1633
+
1634
+ _save = self.pos
1635
+ while true # sequence
1636
+ _text_start = self.pos
1637
+ _tmp = scan(/\A(?-mix:.+)/)
1638
+ if _tmp
1639
+ text = get_text(_text_start)
1640
+ end
1641
+ unless _tmp
1642
+ self.pos = _save
1643
+ break
1644
+ end
1645
+ @result = begin; text; end
1646
+ _tmp = true
1647
+ unless _tmp
1648
+ self.pos = _save
1649
+ end
1650
+ break
1651
+ end # end sequence
1652
+
1653
+ set_failed_rule :_condition unless _tmp
1654
+ return _tmp
1655
+ end
1656
+
1657
+ # breakpoint_stmt_no_condition = location:loc { Breakpoint.new(loc, false, 'true') }
1658
+ def _breakpoint_stmt_no_condition
1659
+
1660
+ _save = self.pos
1661
+ while true # sequence
1662
+ _tmp = apply(:_location)
1663
+ loc = @result
1664
+ unless _tmp
1665
+ self.pos = _save
1666
+ break
1667
+ end
1668
+ @result = begin;
1669
+ Breakpoint.new(loc, false, 'true')
1670
+ ; end
1671
+ _tmp = true
1672
+ unless _tmp
1673
+ self.pos = _save
1674
+ end
1675
+ break
1676
+ end # end sequence
1677
+
1678
+ set_failed_rule :_breakpoint_stmt_no_condition unless _tmp
1679
+ return _tmp
1680
+ end
1681
+
1682
+ # breakpoint_stmt = (location:loc - if_unless:iu - condition:cond { Breakpoint.new(loc, iu == 'unless', cond) } | breakpoint_stmt_no_condition)
1683
+ def _breakpoint_stmt
1684
+
1685
+ _save = self.pos
1686
+ while true # choice
1687
+
1688
+ _save1 = self.pos
1689
+ while true # sequence
1690
+ _tmp = apply(:_location)
1691
+ loc = @result
1692
+ unless _tmp
1693
+ self.pos = _save1
1694
+ break
1695
+ end
1696
+ _tmp = apply(:__hyphen_)
1697
+ unless _tmp
1698
+ self.pos = _save1
1699
+ break
1700
+ end
1701
+ _tmp = apply(:_if_unless)
1702
+ iu = @result
1703
+ unless _tmp
1704
+ self.pos = _save1
1705
+ break
1706
+ end
1707
+ _tmp = apply(:__hyphen_)
1708
+ unless _tmp
1709
+ self.pos = _save1
1710
+ break
1711
+ end
1712
+ _tmp = apply(:_condition)
1713
+ cond = @result
1714
+ unless _tmp
1715
+ self.pos = _save1
1716
+ break
1717
+ end
1718
+ @result = begin;
1719
+ Breakpoint.new(loc, iu == 'unless', cond)
1720
+ ; end
1721
+ _tmp = true
1722
+ unless _tmp
1723
+ self.pos = _save1
1724
+ end
1725
+ break
1726
+ end # end sequence
1727
+
1728
+ break if _tmp
1729
+ self.pos = _save
1730
+ _tmp = apply(:_breakpoint_stmt_no_condition)
1731
+ break if _tmp
1732
+ self.pos = _save
1733
+ break
1734
+ end # end choice
1735
+
1736
+ set_failed_rule :_breakpoint_stmt unless _tmp
1737
+ return _tmp
1738
+ end
1739
+
1740
+ # list_special_targets = < "." "-" > { text }
1741
+ def _list_special_targets
1742
+
1743
+ _save = self.pos
1744
+ while true # sequence
1745
+ _text_start = self.pos
1746
+
1747
+ _save1 = self.pos
1748
+ while true # sequence
1749
+ _tmp = match_string(".")
1750
+ unless _tmp
1751
+ self.pos = _save1
1752
+ break
1753
+ end
1754
+ _tmp = match_string("-")
1755
+ unless _tmp
1756
+ self.pos = _save1
1757
+ end
1758
+ break
1759
+ end # end sequence
1760
+
1761
+ if _tmp
1762
+ text = get_text(_text_start)
1763
+ end
1764
+ unless _tmp
1765
+ self.pos = _save
1766
+ break
1767
+ end
1768
+ @result = begin; text ; end
1769
+ _tmp = true
1770
+ unless _tmp
1771
+ self.pos = _save
1772
+ end
1773
+ break
1774
+ end # end sequence
1775
+
1776
+ set_failed_rule :_list_special_targets unless _tmp
1777
+ return _tmp
1778
+ end
1779
+
1780
+ # list_stmt = (list_special_target | location):loc - integer:int? { List.new(loc, int) }
1781
+ def _list_stmt
1782
+
1783
+ _save = self.pos
1784
+ while true # sequence
1785
+
1786
+ _save1 = self.pos
1787
+ while true # choice
1788
+ _tmp = apply(:_list_special_target)
1789
+ break if _tmp
1790
+ self.pos = _save1
1791
+ _tmp = apply(:_location)
1792
+ break if _tmp
1793
+ self.pos = _save1
1794
+ break
1795
+ end # end choice
1796
+
1797
+ loc = @result
1798
+ unless _tmp
1799
+ self.pos = _save
1800
+ break
1801
+ end
1802
+ _tmp = apply(:__hyphen_)
1803
+ unless _tmp
1804
+ self.pos = _save
1805
+ break
1806
+ end
1807
+ _save2 = self.pos
1808
+ _tmp = apply(:_integer)
1809
+ int = @result
1810
+ unless _tmp
1811
+ _tmp = true
1812
+ self.pos = _save2
1813
+ end
1814
+ unless _tmp
1815
+ self.pos = _save
1816
+ break
1817
+ end
1818
+ @result = begin;
1819
+ List.new(loc, int)
1820
+ ; end
1821
+ _tmp = true
1822
+ unless _tmp
1823
+ self.pos = _save
1824
+ end
1825
+ break
1826
+ end # end sequence
1827
+
1828
+ set_failed_rule :_list_stmt unless _tmp
1829
+ return _tmp
1830
+ end
1831
+
1832
+ Rules = {}
1833
+ Rules[:_upcase_letter] = rule_info("upcase_letter", "/[A-Z]/")
1834
+ Rules[:_downcase_letter] = rule_info("downcase_letter", "/[a-z]/")
1835
+ Rules[:_suffix_letter] = rule_info("suffix_letter", "/[=!?]/")
1836
+ Rules[:_letter] = rule_info("letter", "(upcase_letter | downcase_letter)")
1837
+ Rules[:_id_symbol] = rule_info("id_symbol", "(letter | \"_\" | [0-9])")
1838
+ Rules[:_vm_identifier] = rule_info("vm_identifier", "< (downcase_letter | \"_\") id_symbol* suffix_letter? > { SymbolEntry.new(:variable, text) }")
1839
+ Rules[:_variable_identifier] = rule_info("variable_identifier", "< (downcase_letter | \"_\") id_symbol* > { SymbolEntry.new(:variable, text) }")
1840
+ Rules[:_constant_identifier] = rule_info("constant_identifier", "< upcase_letter id_symbol* > { SymbolEntry.new(:constant, text) }")
1841
+ Rules[:_global_identifier] = rule_info("global_identifier", "< \"$\" (constant_identifier | variable_identifier) > { SymbolEntry.new(:global, text) }")
1842
+ Rules[:_local_internal_identifier] = rule_info("local_internal_identifier", "(constant_identifier | variable_identifier)")
1843
+ Rules[:_local_identifier] = rule_info("local_identifier", "(constant_identifier | vm_identifier)")
1844
+ Rules[:_instance_identifier] = rule_info("instance_identifier", "< \"@\" local_identifier > { SymbolEntry.new(:instance, text) }")
1845
+ Rules[:_classvar_identifier] = rule_info("classvar_identifier", "\"@@\" local_identifier:id { SymbolEntry.new(:classvar, id) }")
1846
+ Rules[:_identifier] = rule_info("identifier", "(global_identifier | instance_identifier | classvar_identifier | local_identifier)")
1847
+ Rules[:_id_separator] = rule_info("id_separator", "< (\"::\" | \".\") > { text }")
1848
+ Rules[:_internal_class_module_chain] = rule_info("internal_class_module_chain", "(< local_internal_identifier:parent id_separator:sep internal_class_module_chain:child > { SymbolEntry.new(parent.type, text, [parent, child, sep]) } | local_identifier)")
1849
+ Rules[:_class_module_chain] = rule_info("class_module_chain", "(< identifier:parent id_separator:sep internal_class_module_chain:child > { SymbolEntry.new(parent.type, text, [parent, child, sep]) } | identifier)")
1850
+ Rules[:_sp] = rule_info("sp", "/[ \\t]/")
1851
+ Rules[:__hyphen_] = rule_info("-", "sp+")
1852
+ Rules[:_dbl_escapes] = rule_info("dbl_escapes", "(\"\\\\\\\"\" { '\"' } | \"\\\\n\" { \"\\n\" } | \"\\\\t\" { \"\\t\" } | \"\\\\\\\\\" { \"\\\\\" })")
1853
+ Rules[:_escapes] = rule_info("escapes", "(\"\\\\\\\"\" { '\"' } | \"\\\\n\" { \"\\n\" } | \"\\\\t\" { \"\\t\" } | \"\\\\ \" { \" \" } | \"\\\\:\" { \":\" } | \"\\\\\\\\\" { \"\\\\\" })")
1854
+ Rules[:_dbl_seq] = rule_info("dbl_seq", "< /[^\\\\\"]+/ > { text }")
1855
+ Rules[:_dbl_not_quote] = rule_info("dbl_not_quote", "(dbl_escapes | dbl_seq)+:ary { ary }")
1856
+ Rules[:_dbl_string] = rule_info("dbl_string", "\"\\\"\" dbl_not_quote:ary \"\\\"\" { ary.join }")
1857
+ Rules[:_not_space_colon] = rule_info("not_space_colon", "(escapes | < /[^ \\t\\n:]/ > { text })")
1858
+ Rules[:_not_space_colons] = rule_info("not_space_colons", "not_space_colon+:ary { ary.join }")
1859
+ Rules[:_filename] = rule_info("filename", "(dbl_string | not_space_colons)")
1860
+ Rules[:_file_pos_sep] = rule_info("file_pos_sep", "(sp+ | \":\")")
1861
+ Rules[:_integer] = rule_info("integer", "< /[0-9]+/ > { text.to_i }")
1862
+ Rules[:_line_number] = rule_info("line_number", "integer")
1863
+ Rules[:_vm_offset] = rule_info("vm_offset", "\"@\" integer:int { Position.new(nil, nil, :offset, int) }")
1864
+ Rules[:_position] = rule_info("position", "(vm_offset | line_number:l { Position.new(nil, nil, :line, l) })")
1865
+ Rules[:_location] = rule_info("location", "(position | < filename >:file &{ File.exist?(file) } file_pos_sep position:pos { Position.new(:file, file, pos.position_type, pos.position) } | < filename >:file &{ File.exist?(file) } { Position.new(:file, file, nil, nil) } | class_module_chain?:fn file_pos_sep position:pos { Position.new(:fn, fn, pos.position_type, pos.position) } | class_module_chain?:fn { Position.new(:fn, fn, nil, nil) })")
1866
+ Rules[:_if_unless] = rule_info("if_unless", "< (\"if\" | \"unless\") > { text }")
1867
+ Rules[:_condition] = rule_info("condition", "< /.+/ > { text}")
1868
+ Rules[:_breakpoint_stmt_no_condition] = rule_info("breakpoint_stmt_no_condition", "location:loc { Breakpoint.new(loc, false, 'true') }")
1869
+ Rules[:_breakpoint_stmt] = rule_info("breakpoint_stmt", "(location:loc - if_unless:iu - condition:cond { Breakpoint.new(loc, iu == 'unless', cond) } | breakpoint_stmt_no_condition)")
1870
+ Rules[:_list_special_targets] = rule_info("list_special_targets", "< \".\" \"-\" > { text }")
1871
+ Rules[:_list_stmt] = rule_info("list_stmt", "(list_special_target | location):loc - integer:int? { List.new(loc, int) }")
1872
+ end
1873
+ if __FILE__ == $0
1874
+ # require 'rubygems'; require_relative '../lib/trepanning';
1875
+
1876
+ cp = CmdParse.new('', true)
1877
+ %w(A::B @@classvar abc01! @ivar @ivar.meth
1878
+ Object A::B::C A::B::C::D A::B.c A.b.c.d).each do |name|
1879
+ cp.setup_parser(name, true)
1880
+ # debugger if name == '@ivar.meth'
1881
+ res = cp._class_module_chain
1882
+ p res
1883
+ p cp.string
1884
+ p cp.result
1885
+ end
1886
+ %w(A::B:5 A::B:@5 @@classvar abc01!:10 @ivar).each do |name|
1887
+ cp.setup_parser(name, true)
1888
+ res = cp._location
1889
+ p res
1890
+ p cp.string
1891
+ p cp.result
1892
+ end
1893
+ # require 'trepanning';
1894
+ ["#{__FILE__}:10", 'A::B 5',
1895
+ "#{__FILE__} 20"].each do |name|
1896
+ cp.setup_parser(name, true)
1897
+ res = cp._location
1898
+ p res
1899
+ p cp.string
1900
+ p cp.result
1901
+ end
1902
+
1903
+ ['filename', '"this is a filename"',
1904
+ 'this\ is\ another\ filename',
1905
+ 'C\:filename'
1906
+ ].each do |name|
1907
+ puts '-' * 10
1908
+ cp.setup_parser(name, true)
1909
+ res = cp._filename
1910
+ p res
1911
+ puts cp.string
1912
+ puts cp.result
1913
+ end
1914
+ end