atomy 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. data/COPYING +30 -0
  2. data/README.md +1 -0
  3. data/bin/atomy +134 -0
  4. data/kernel/block.ay +30 -0
  5. data/kernel/boot.ay +10 -0
  6. data/kernel/comparison.ay +61 -0
  7. data/kernel/concurrency.ay +84 -0
  8. data/kernel/condition.ay +277 -0
  9. data/kernel/control-flow.ay +222 -0
  10. data/kernel/cosmetics.ay +3 -0
  11. data/kernel/data-delta.ay +105 -0
  12. data/kernel/data.ay +56 -0
  13. data/kernel/define.ay +93 -0
  14. data/kernel/doc.ay +453 -0
  15. data/kernel/documentation.ay +135 -0
  16. data/kernel/dynamic.ay +42 -0
  17. data/kernel/errors.ay +6 -0
  18. data/kernel/format.ay +13 -0
  19. data/kernel/format/data.ay +89 -0
  20. data/kernel/format/formatter.ay +345 -0
  21. data/kernel/format/parser.ay +13 -0
  22. data/kernel/hashes.ay +39 -0
  23. data/kernel/io.ay +244 -0
  24. data/kernel/namespaces.ay +63 -0
  25. data/kernel/node.ay +48 -0
  26. data/kernel/operators.ay +28 -0
  27. data/kernel/particles.ay +53 -0
  28. data/kernel/patterns.ay +256 -0
  29. data/kernel/precision.ay +148 -0
  30. data/kernel/pretty.ay +283 -0
  31. data/kernel/repl.ay +140 -0
  32. data/kernel/therie.ay +204 -0
  33. data/lib/ast/binary_send.rb +44 -0
  34. data/lib/ast/block.rb +268 -0
  35. data/lib/ast/constant.rb +88 -0
  36. data/lib/ast/internal/assign.rb +19 -0
  37. data/lib/ast/internal/block_pass.rb +21 -0
  38. data/lib/ast/internal/catch.rb +247 -0
  39. data/lib/ast/internal/class.rb +30 -0
  40. data/lib/ast/internal/class_variable.rb +23 -0
  41. data/lib/ast/internal/define.rb +174 -0
  42. data/lib/ast/internal/ensure.rb +135 -0
  43. data/lib/ast/internal/file.rb +14 -0
  44. data/lib/ast/internal/global_variable.rb +20 -0
  45. data/lib/ast/internal/if_then_else.rb +24 -0
  46. data/lib/ast/internal/instance_variable.rb +17 -0
  47. data/lib/ast/internal/let_macro.rb +35 -0
  48. data/lib/ast/internal/macro_quote.rb +23 -0
  49. data/lib/ast/internal/match.rb +53 -0
  50. data/lib/ast/internal/module.rb +30 -0
  51. data/lib/ast/internal/pattern.rb +17 -0
  52. data/lib/ast/internal/return.rb +29 -0
  53. data/lib/ast/internal/set.rb +19 -0
  54. data/lib/ast/internal/singleton_class.rb +18 -0
  55. data/lib/ast/internal/splat.rb +14 -0
  56. data/lib/ast/internal/when.rb +24 -0
  57. data/lib/ast/list.rb +25 -0
  58. data/lib/ast/macro.rb +37 -0
  59. data/lib/ast/node.rb +599 -0
  60. data/lib/ast/operator.rb +21 -0
  61. data/lib/ast/particle.rb +13 -0
  62. data/lib/ast/primitive.rb +20 -0
  63. data/lib/ast/quasi_quote.rb +20 -0
  64. data/lib/ast/quote.rb +13 -0
  65. data/lib/ast/send.rb +104 -0
  66. data/lib/ast/splice.rb +32 -0
  67. data/lib/ast/string.rb +23 -0
  68. data/lib/ast/unary.rb +44 -0
  69. data/lib/ast/unquote.rb +45 -0
  70. data/lib/ast/variable.rb +64 -0
  71. data/lib/atomy.kpeg.rb +3995 -0
  72. data/lib/code_loader.rb +137 -0
  73. data/lib/compiler/compiler.rb +155 -0
  74. data/lib/compiler/stages.rb +81 -0
  75. data/lib/formatter.kpeg.rb +1394 -0
  76. data/lib/macros.rb +317 -0
  77. data/lib/method.rb +261 -0
  78. data/lib/namespace.rb +236 -0
  79. data/lib/parser.rb +28 -0
  80. data/lib/patterns.rb +276 -0
  81. data/lib/patterns/any.rb +21 -0
  82. data/lib/patterns/attribute.rb +59 -0
  83. data/lib/patterns/block_pass.rb +54 -0
  84. data/lib/patterns/constant.rb +33 -0
  85. data/lib/patterns/default.rb +44 -0
  86. data/lib/patterns/head_tail.rb +63 -0
  87. data/lib/patterns/list.rb +77 -0
  88. data/lib/patterns/match.rb +45 -0
  89. data/lib/patterns/named.rb +55 -0
  90. data/lib/patterns/named_class.rb +46 -0
  91. data/lib/patterns/named_global.rb +46 -0
  92. data/lib/patterns/named_instance.rb +46 -0
  93. data/lib/patterns/particle.rb +29 -0
  94. data/lib/patterns/quasi_quote.rb +184 -0
  95. data/lib/patterns/quote.rb +33 -0
  96. data/lib/patterns/singleton_class.rb +31 -0
  97. data/lib/patterns/splat.rb +57 -0
  98. data/lib/util.rb +37 -0
  99. metadata +164 -0
@@ -0,0 +1,137 @@
1
+ require("stringio")
2
+
3
+ module Atomy
4
+ class CodeLoader
5
+ class << self
6
+ def reason
7
+ @reason ||= :run
8
+ end
9
+
10
+ def reason=(x)
11
+ @reason = x
12
+ end
13
+
14
+ def when_load
15
+ @when_load ||= []
16
+ end
17
+
18
+ def when_load=(x)
19
+ @when_load = x
20
+ end
21
+
22
+ def compiled?
23
+ @compiled ||= false
24
+ end
25
+
26
+ def compiled!(x = false)
27
+ @compiled = x
28
+ end
29
+
30
+ def documentation
31
+ @documentation ||= false
32
+ end
33
+
34
+ def documentation=(x)
35
+ @documentation = x
36
+ end
37
+
38
+ def compiled_name(fn)
39
+ Atomy::Compiler.compiled_name(fn)
40
+ end
41
+
42
+ def source_name(fn)
43
+ if fn.suffix? ".compiled.ayc"
44
+ fn[0..-(".compiled.ayc".size)]
45
+ elsif fn.suffix? ".ayc"
46
+ fn[0..-2]
47
+ end
48
+ end
49
+
50
+ def docs_name(fn)
51
+ CodeLoader.documentation + "/" + File.basename(fn, ".ay") + ".ddl"
52
+ end
53
+
54
+ def compile_if_needed(fn, debug = false, docs = false)
55
+ source = source_name(fn)
56
+ compiled = compiled_name(fn)
57
+
58
+ if !File.exists?(compiled) ||
59
+ File.stat(compiled).mtime < File.stat(fn).mtime ||
60
+ CodeLoader.documentation
61
+ if CodeLoader.documentation
62
+ Thread.current[:atomy_documentation] = docs = StringIO.new
63
+ docs << "\\style{Atomy}\n\n"
64
+ before = docs.size
65
+ end
66
+
67
+ CodeLoader.compiled! true
68
+ Compiler.compile fn, nil, debug
69
+
70
+ if CodeLoader.documentation && docs.size > before
71
+ File.open(docs_name(fn), "w") do |f|
72
+ f.write(Thread.current[:atomy_documentation].string)
73
+ end
74
+ end
75
+ end
76
+
77
+ compiled
78
+ end
79
+
80
+ def find_file(fn)
81
+ if fn.suffix?(".ay") || fn.suffix?(".rb")
82
+ fn
83
+ elsif File.exists?(fn + ".ay")
84
+ fn + ".ay"
85
+ elsif File.exists?(fn + ".rb")
86
+ fn + ".rb"
87
+ else
88
+ fn
89
+ end
90
+ end
91
+
92
+ def loadable?(fn)
93
+ return false unless File.exists? fn
94
+
95
+ stat = File.stat fn
96
+ stat.file? && stat.readable?
97
+ end
98
+
99
+ def search_path(fn)
100
+ $LOAD_PATH.each do |dir|
101
+ path = find_file("#{dir}/#{fn}")
102
+ return path if loadable? path
103
+ end
104
+
105
+ nil
106
+ end
107
+
108
+ def qualified_path?(path)
109
+ path[0] == ?/ or path.prefix?("./") or path.prefix?("../")
110
+ end
111
+
112
+ def load_file(fn, r = :run, debug = false)
113
+ if qualified_path?(fn)
114
+ file = find_file(fn)
115
+ else
116
+ file = search_path(fn)
117
+ end
118
+
119
+ raise("cannot find file to load for #{fn}") unless file
120
+
121
+ return require(file) unless file.suffix?(".ay")
122
+
123
+ CodeLoader.when_load = []
124
+ CodeLoader.reason = r
125
+ CodeLoader.compiled! false
126
+
127
+ cfn = compile_if_needed(file, debug)
128
+ cl = Rubinius::CodeLoader.new(cfn)
129
+ cm = cl.load_compiled_file(cfn, 0)
130
+ script = cm.create_script(false)
131
+ script.file_path = fn
132
+
133
+ MAIN.__send__ :__script__
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,155 @@
1
+ module Atomy
2
+ class Compiler < Rubinius::Compiler
3
+ attr_accessor :expander
4
+
5
+ def self.compiled_name(file)
6
+ if file.suffix? ".ay"
7
+ file + "c"
8
+ else
9
+ file + ".compiled.ayc"
10
+ end
11
+ end
12
+
13
+ def self.compile(file, output = nil, debug = false)
14
+ compiler = new :atomy_file, :compiled_file
15
+
16
+ parser = compiler.parser
17
+ parser.root Atomy::AST::Script
18
+ parser.input file, 1
19
+
20
+ if debug
21
+ printer = compiler.packager.print
22
+ printer.bytecode = debug
23
+ end
24
+
25
+ writer = compiler.writer
26
+ writer.name = output ? output : compiled_name(file)
27
+
28
+ compiler.run
29
+ end
30
+
31
+ def self.compile_file(file, debug = false)
32
+ compiler = new :atomy_file, :compiled_method
33
+
34
+ parser = compiler.parser
35
+ parser.root Atomy::AST::Script
36
+ parser.input file, 1
37
+
38
+ printer = compiler.packager.print
39
+ printer.bytecode = debug
40
+
41
+ compiler.run
42
+ end
43
+
44
+ def self.compile_string(string, file = "(eval)", line = 1, debug = false)
45
+ compiler = new :atomy_string, :compiled_method
46
+
47
+ parser = compiler.parser
48
+ parser.root Rubinius::AST::Script
49
+ parser.input string, file, line
50
+
51
+ if debug
52
+ printer = compiler.packager.print
53
+ printer.bytecode = debug
54
+ end
55
+
56
+ compiler.run
57
+ end
58
+
59
+ def self.compile_eval(string, scope = nil, file = "(eval)", line = 1, debug = false)
60
+ compiler = new :atomy_string, :compiled_method
61
+
62
+ parser = compiler.parser
63
+ parser.root Rubinius::AST::EvalExpression
64
+ parser.input string, file, line
65
+
66
+ if debug
67
+ printer = compiler.packager.print
68
+ printer.bytecode = debug
69
+ end
70
+
71
+ compiler.generator.variable_scope = scope
72
+
73
+ compiler.run
74
+ end
75
+
76
+ def self.compile_node(node, scope = nil, file = "(eval)", line = 1, debug = false)
77
+ compiler = new :atomy_bytecode, :compiled_method
78
+
79
+ eval = Rubinius::AST::EvalExpression.new(AST::Tree.new([node]))
80
+ eval.file = file
81
+
82
+ if debug
83
+ printer = compiler.packager.print
84
+ printer.bytecode = debug
85
+ end
86
+
87
+ compiler.generator.input eval
88
+ compiler.generator.variable_scope = scope
89
+
90
+ compiler.run
91
+ end
92
+
93
+ def self.evaluate_node(node, instance = nil, bnd = nil, file = "(eval)", line = 1)
94
+ if bnd.nil?
95
+ bnd = Binding.setup(
96
+ Rubinius::VariableScope.of_sender,
97
+ Rubinius::CompiledMethod.of_sender,
98
+ Rubinius::StaticScope.of_sender
99
+ )
100
+ end
101
+
102
+ cm = compile_node(node, bnd.variables, file, line)
103
+ cm.scope = bnd.static_scope.dup
104
+ cm.name = :__atomy_eval__
105
+
106
+ script = Rubinius::CompiledMethod::Script.new(cm, file, true)
107
+ script.eval_binding = bnd
108
+
109
+ cm.scope.script = script
110
+
111
+ be = Rubinius::BlockEnvironment.new
112
+ be.under_context(bnd.variables, cm)
113
+
114
+ if bnd.from_proc?
115
+ be.proc_environment = bnd.proc_environment
116
+ end
117
+
118
+ if instance
119
+ be.call_on_instance instance
120
+ else
121
+ be.call
122
+ end
123
+ end
124
+
125
+ def self.evaluate(string, bnd = nil, file = "(eval)", line = 1, debug = false)
126
+ if bnd.nil?
127
+ bnd = Binding.setup(
128
+ Rubinius::VariableScope.of_sender,
129
+ Rubinius::CompiledMethod.of_sender,
130
+ Rubinius::StaticScope.of_sender
131
+ )
132
+ end
133
+
134
+ cm = compile_eval(string, bnd.variables, file, line, debug)
135
+ cm.scope = bnd.static_scope.dup
136
+ cm.name = :__eval__
137
+
138
+ script = Rubinius::CompiledMethod::Script.new(cm, file, true)
139
+ script.eval_binding = bnd
140
+ script.eval_source = string
141
+
142
+ cm.scope.script = script
143
+
144
+ be = Rubinius::BlockEnvironment.new
145
+ be.under_context(bnd.variables, cm)
146
+
147
+ if bnd.from_proc?
148
+ be.proc_environment = bnd.proc_environment
149
+ end
150
+
151
+ be.from_eval!
152
+ be.call
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,81 @@
1
+ module Atomy
2
+ class Compiler
3
+ class Generator < Rubinius::Compiler::Stage
4
+ stage :atomy_bytecode
5
+ next_stage Rubinius::Compiler::Encoder
6
+
7
+ attr_accessor :variable_scope
8
+
9
+ def initialize(compiler, last)
10
+ super
11
+ @variable_scope = nil
12
+ compiler.generator = self
13
+ end
14
+
15
+ def run
16
+ @output = Rubinius::Generator.new
17
+ @input.variable_scope = @variable_scope
18
+ @input.bytecode @output
19
+ @output.close
20
+ run_next
21
+ end
22
+
23
+ def input(root)
24
+ @input = root
25
+ end
26
+ end
27
+
28
+ class Parser < Rubinius::Compiler::Stage
29
+ stage :atomy_parser
30
+ next_stage Generator
31
+
32
+ def initialize(compiler, last)
33
+ super
34
+ compiler.parser = self
35
+ end
36
+
37
+ def root(root)
38
+ @root = root
39
+ end
40
+
41
+ def print
42
+ @print = true
43
+ end
44
+
45
+ def input(code, file = "(eval)", line = 1)
46
+ @input = code
47
+ @file = file
48
+ @line = line
49
+ end
50
+
51
+ def run
52
+ @output = @root.new parse
53
+ @output.file = @file
54
+ run_next
55
+ end
56
+ end
57
+
58
+ class FileParser < Parser
59
+ stage :atomy_file
60
+ next_stage Generator
61
+
62
+ def input(file, line = 1)
63
+ @file = file
64
+ @line = line
65
+ end
66
+
67
+ def parse
68
+ Atomy::Parser.parse_file(@file)
69
+ end
70
+ end
71
+
72
+ class StringParser < Parser
73
+ stage :atomy_string
74
+ next_stage Generator
75
+
76
+ def parse
77
+ Atomy::Parser.parse_string(@input)
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,1394 @@
1
+ class Atomy::Format::Parser
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
+
11
+ setup_foreign_grammar
12
+ end
13
+
14
+ # This is distinct from setup_parser so that a standalone parser
15
+ # can redefine #initialize and still have access to the proper
16
+ # parser setup code.
17
+ #
18
+ def initialize(str, debug=false)
19
+ setup_parser(str, debug)
20
+ end
21
+
22
+ attr_reader :string
23
+ attr_reader :failing_rule_offset
24
+ attr_accessor :result, :pos
25
+
26
+ # STANDALONE START
27
+ def current_column(target=pos)
28
+ if c = string.rindex("\n", target-1)
29
+ return target - c - 1
30
+ end
31
+
32
+ target + 1
33
+ end
34
+
35
+ def current_line(target=pos)
36
+ cur_offset = 0
37
+ cur_line = 0
38
+
39
+ string.each_line do |line|
40
+ cur_line += 1
41
+ cur_offset += line.size
42
+ return cur_line if cur_offset >= target
43
+ end
44
+
45
+ -1
46
+ end
47
+
48
+ def lines
49
+ lines = []
50
+ string.each_line { |l| lines << l }
51
+ lines
52
+ end
53
+
54
+ #
55
+
56
+ def get_text(start)
57
+ @string[start..@pos-1]
58
+ end
59
+
60
+ def show_pos
61
+ width = 10
62
+ if @pos < width
63
+ "#{@pos} (\"#{@string[0,@pos]}\" @ \"#{@string[@pos,width]}\")"
64
+ else
65
+ "#{@pos} (\"... #{@string[@pos - width, width]}\" @ \"#{@string[@pos,width]}\")"
66
+ end
67
+ end
68
+
69
+ def failure_info
70
+ l = current_line @failing_rule_offset
71
+ c = current_column @failing_rule_offset
72
+
73
+ if @failed_rule.kind_of? Symbol
74
+ info = self.class::Rules[@failed_rule]
75
+ "line #{l}, column #{c}: failed rule '#{info.name}' = '#{info.rendered}'"
76
+ else
77
+ "line #{l}, column #{c}: failed rule '#{@failed_rule}'"
78
+ end
79
+ end
80
+
81
+ def failure_caret
82
+ l = current_line @failing_rule_offset
83
+ c = current_column @failing_rule_offset
84
+
85
+ line = lines[l-1]
86
+ "#{line}\n#{' ' * (c - 1)}^"
87
+ end
88
+
89
+ def failure_character
90
+ l = current_line @failing_rule_offset
91
+ c = current_column @failing_rule_offset
92
+ lines[l-1][c-1, 1]
93
+ end
94
+
95
+ def failure_oneline
96
+ l = current_line @failing_rule_offset
97
+ c = current_column @failing_rule_offset
98
+
99
+ char = lines[l-1][c-1, 1]
100
+
101
+ if @failed_rule.kind_of? Symbol
102
+ info = self.class::Rules[@failed_rule]
103
+ "@#{l}:#{c} failed rule '#{info.name}', got '#{char}'"
104
+ else
105
+ "@#{l}:#{c} failed rule '#{@failed_rule}', got '#{char}'"
106
+ end
107
+ end
108
+
109
+ class ParseError < RuntimeError
110
+ end
111
+
112
+ def raise_error
113
+ raise ParseError, failure_oneline
114
+ end
115
+
116
+ def show_error(io=STDOUT)
117
+ error_pos = @failing_rule_offset
118
+ line_no = current_line(error_pos)
119
+ col_no = current_column(error_pos)
120
+
121
+ io.puts "On line #{line_no}, column #{col_no}:"
122
+
123
+ if @failed_rule.kind_of? Symbol
124
+ info = self.class::Rules[@failed_rule]
125
+ io.puts "Failed to match '#{info.rendered}' (rule '#{info.name}')"
126
+ else
127
+ io.puts "Failed to match rule '#{@failed_rule}'"
128
+ end
129
+
130
+ io.puts "Got: #{string[error_pos,1].inspect}"
131
+ line = lines[line_no-1]
132
+ io.puts "=> #{line}"
133
+ io.print(" " * (col_no + 3))
134
+ io.puts "^"
135
+ end
136
+
137
+ def set_failed_rule(name)
138
+ if @pos > @failing_rule_offset
139
+ @failed_rule = name
140
+ @failing_rule_offset = @pos
141
+ end
142
+ end
143
+
144
+ attr_reader :failed_rule
145
+
146
+ def match_string(str)
147
+ len = str.size
148
+ if @string[pos,len] == str
149
+ @pos += len
150
+ return str
151
+ end
152
+
153
+ return nil
154
+ end
155
+
156
+ def scan(reg)
157
+ if m = reg.match(@string[@pos..-1])
158
+ width = m.end(0)
159
+ @pos += width
160
+ return true
161
+ end
162
+
163
+ return nil
164
+ end
165
+
166
+ if "".respond_to? :getbyte
167
+ def get_byte
168
+ if @pos >= @string.size
169
+ return nil
170
+ end
171
+
172
+ s = @string.getbyte @pos
173
+ @pos += 1
174
+ s
175
+ end
176
+ else
177
+ def get_byte
178
+ if @pos >= @string.size
179
+ return nil
180
+ end
181
+
182
+ s = @string[@pos]
183
+ @pos += 1
184
+ s
185
+ end
186
+ end
187
+
188
+ def parse(rule=nil)
189
+ if !rule
190
+ _root ? true : false
191
+ else
192
+ # This is not shared with code_generator.rb so this can be standalone
193
+ method = rule.gsub("-","_hyphen_")
194
+ __send__("_#{method}") ? true : false
195
+ end
196
+ end
197
+
198
+ class LeftRecursive
199
+ def initialize(detected=false)
200
+ @detected = detected
201
+ end
202
+
203
+ attr_accessor :detected
204
+ end
205
+
206
+ class MemoEntry
207
+ def initialize(ans, pos)
208
+ @ans = ans
209
+ @pos = pos
210
+ @uses = 1
211
+ @result = nil
212
+ end
213
+
214
+ attr_reader :ans, :pos, :uses, :result
215
+
216
+ def inc!
217
+ @uses += 1
218
+ end
219
+
220
+ def move!(ans, pos, result)
221
+ @ans = ans
222
+ @pos = pos
223
+ @result = result
224
+ end
225
+ end
226
+
227
+ def external_invoke(other, rule, *args)
228
+ old_pos = @pos
229
+ old_string = @string
230
+
231
+ @pos = other.pos
232
+ @string = other.string
233
+
234
+ begin
235
+ if val = __send__(rule, *args)
236
+ other.pos = @pos
237
+ other.result = @result
238
+ else
239
+ other.set_failed_rule "#{self.class}##{rule}"
240
+ end
241
+ val
242
+ ensure
243
+ @pos = old_pos
244
+ @string = old_string
245
+ end
246
+ end
247
+
248
+ def apply(rule)
249
+ if m = @memoizations[rule][@pos]
250
+ m.inc!
251
+
252
+ prev = @pos
253
+ @pos = m.pos
254
+ if m.ans.kind_of? LeftRecursive
255
+ m.ans.detected = true
256
+ return nil
257
+ end
258
+
259
+ @result = m.result
260
+
261
+ return m.ans
262
+ else
263
+ lr = LeftRecursive.new(false)
264
+ m = MemoEntry.new(lr, @pos)
265
+ @memoizations[rule][@pos] = m
266
+ start_pos = @pos
267
+
268
+ ans = __send__ rule
269
+
270
+ m.move! ans, @pos, @result
271
+
272
+ # Don't bother trying to grow the left recursion
273
+ # if it's failing straight away (thus there is no seed)
274
+ if ans and lr.detected
275
+ return grow_lr(rule, start_pos, m)
276
+ else
277
+ return ans
278
+ end
279
+
280
+ return ans
281
+ end
282
+ end
283
+
284
+ def grow_lr(rule, start_pos, m)
285
+ while true
286
+ @pos = start_pos
287
+ @result = m.result
288
+
289
+ ans = __send__ rule
290
+ return nil unless ans
291
+
292
+ break if @pos <= m.pos
293
+
294
+ m.move! ans, @pos, @result
295
+ end
296
+
297
+ @result = m.result
298
+ @pos = m.pos
299
+ return m.ans
300
+ end
301
+
302
+ class RuleInfo
303
+ def initialize(name, rendered)
304
+ @name = name
305
+ @rendered = rendered
306
+ end
307
+
308
+ attr_reader :name, :rendered
309
+ end
310
+
311
+ def self.rule_info(name, rendered)
312
+ RuleInfo.new(name, rendered)
313
+ end
314
+
315
+ #
316
+
317
+
318
+ require File.expand_path("../atomy.kpeg.rb", __FILE__)
319
+ include Atomy::Format
320
+
321
+ def create(x, *as)
322
+ as << []
323
+ x.send(:new, 1, *as)
324
+ end
325
+
326
+
327
+ def setup_foreign_grammar
328
+ @_grammar_atomy = Atomy::Parser.new(nil)
329
+ end
330
+
331
+ # line = { current_line }
332
+ def _line
333
+ @result = begin; current_line ; end
334
+ _tmp = true
335
+ set_failed_rule :_line unless _tmp
336
+ return _tmp
337
+ end
338
+
339
+ # text = (< /[^\\%#{Regexp.quote(e)}]+/ > { text } | "\\" < /[%\(\)\{\}\[\]]/ > { text } | "\\" %atomy.escape:e { e })
340
+ def _text(e)
341
+
342
+ _save = self.pos
343
+ while true # choice
344
+
345
+ _save1 = self.pos
346
+ while true # sequence
347
+ _text_start = self.pos
348
+ _tmp = scan(/\A(?-mix:[^\\%#{Regexp.quote(e)}]+)/)
349
+ if _tmp
350
+ text = get_text(_text_start)
351
+ end
352
+ unless _tmp
353
+ self.pos = _save1
354
+ break
355
+ end
356
+ @result = begin; text ; end
357
+ _tmp = true
358
+ unless _tmp
359
+ self.pos = _save1
360
+ end
361
+ break
362
+ end # end sequence
363
+
364
+ break if _tmp
365
+ self.pos = _save
366
+
367
+ _save2 = self.pos
368
+ while true # sequence
369
+ _tmp = match_string("\\")
370
+ unless _tmp
371
+ self.pos = _save2
372
+ break
373
+ end
374
+ _text_start = self.pos
375
+ _tmp = scan(/\A(?-mix:[%\(\)\{\}\[\]])/)
376
+ if _tmp
377
+ text = get_text(_text_start)
378
+ end
379
+ unless _tmp
380
+ self.pos = _save2
381
+ break
382
+ end
383
+ @result = begin; text ; end
384
+ _tmp = true
385
+ unless _tmp
386
+ self.pos = _save2
387
+ end
388
+ break
389
+ end # end sequence
390
+
391
+ break if _tmp
392
+ self.pos = _save
393
+
394
+ _save3 = self.pos
395
+ while true # sequence
396
+ _tmp = match_string("\\")
397
+ unless _tmp
398
+ self.pos = _save3
399
+ break
400
+ end
401
+ _tmp = @_grammar_atomy.external_invoke(self, :_escape)
402
+ e = @result
403
+ unless _tmp
404
+ self.pos = _save3
405
+ break
406
+ end
407
+ @result = begin; e ; end
408
+ _tmp = true
409
+ unless _tmp
410
+ self.pos = _save3
411
+ end
412
+ break
413
+ end # end sequence
414
+
415
+ break if _tmp
416
+ self.pos = _save
417
+ break
418
+ end # end choice
419
+
420
+ set_failed_rule :_text unless _tmp
421
+ return _tmp
422
+ end
423
+
424
+ # nested = text(e)+:c { Chunk.new(0, [], c.join) }
425
+ def _nested(e)
426
+
427
+ _save = self.pos
428
+ while true # sequence
429
+ _save1 = self.pos
430
+ _ary = []
431
+ _tmp = _text(e)
432
+ if _tmp
433
+ _ary << @result
434
+ while true
435
+ _tmp = _text(e)
436
+ _ary << @result if _tmp
437
+ break unless _tmp
438
+ end
439
+ _tmp = true
440
+ @result = _ary
441
+ else
442
+ self.pos = _save1
443
+ end
444
+ c = @result
445
+ unless _tmp
446
+ self.pos = _save
447
+ break
448
+ end
449
+ @result = begin; Chunk.new(0, [], c.join) ; end
450
+ _tmp = true
451
+ unless _tmp
452
+ self.pos = _save
453
+ end
454
+ break
455
+ end # end sequence
456
+
457
+ set_failed_rule :_nested unless _tmp
458
+ return _tmp
459
+ end
460
+
461
+ # chunk = nested("")
462
+ def _chunk
463
+ _tmp = _nested("")
464
+ set_failed_rule :_chunk unless _tmp
465
+ return _tmp
466
+ end
467
+
468
+ # flagged = "%" flag*:fs segment:s { s.flags = fs; s }
469
+ def _flagged
470
+
471
+ _save = self.pos
472
+ while true # sequence
473
+ _tmp = match_string("%")
474
+ unless _tmp
475
+ self.pos = _save
476
+ break
477
+ end
478
+ _ary = []
479
+ while true
480
+ _tmp = apply(:_flag)
481
+ _ary << @result if _tmp
482
+ break unless _tmp
483
+ end
484
+ _tmp = true
485
+ @result = _ary
486
+ fs = @result
487
+ unless _tmp
488
+ self.pos = _save
489
+ break
490
+ end
491
+ _tmp = apply(:_segment)
492
+ s = @result
493
+ unless _tmp
494
+ self.pos = _save
495
+ break
496
+ end
497
+ @result = begin; s.flags = fs; s ; end
498
+ _tmp = true
499
+ unless _tmp
500
+ self.pos = _save
501
+ end
502
+ break
503
+ end # end sequence
504
+
505
+ set_failed_rule :_flagged unless _tmp
506
+ return _tmp
507
+ end
508
+
509
+ # flag = ("#" { Number.new(0, nil) } | "0" &("." /\d/ | /\d/) { ZeroPad.new(0) } | "." < /\d+/ > { Precision.new(0, text.to_i) } | < /\d+/ > { Number.new(0, text.to_i) } | < /[\.\+\*=<>,\?]/ > { Symbol.new(0, text) })
510
+ def _flag
511
+
512
+ _save = self.pos
513
+ while true # choice
514
+
515
+ _save1 = self.pos
516
+ while true # sequence
517
+ _tmp = match_string("#")
518
+ unless _tmp
519
+ self.pos = _save1
520
+ break
521
+ end
522
+ @result = begin; Number.new(0, nil) ; end
523
+ _tmp = true
524
+ unless _tmp
525
+ self.pos = _save1
526
+ end
527
+ break
528
+ end # end sequence
529
+
530
+ break if _tmp
531
+ self.pos = _save
532
+
533
+ _save2 = self.pos
534
+ while true # sequence
535
+ _tmp = match_string("0")
536
+ unless _tmp
537
+ self.pos = _save2
538
+ break
539
+ end
540
+ _save3 = self.pos
541
+
542
+ _save4 = self.pos
543
+ while true # choice
544
+
545
+ _save5 = self.pos
546
+ while true # sequence
547
+ _tmp = match_string(".")
548
+ unless _tmp
549
+ self.pos = _save5
550
+ break
551
+ end
552
+ _tmp = scan(/\A(?-mix:\d)/)
553
+ unless _tmp
554
+ self.pos = _save5
555
+ end
556
+ break
557
+ end # end sequence
558
+
559
+ break if _tmp
560
+ self.pos = _save4
561
+ _tmp = scan(/\A(?-mix:\d)/)
562
+ break if _tmp
563
+ self.pos = _save4
564
+ break
565
+ end # end choice
566
+
567
+ self.pos = _save3
568
+ unless _tmp
569
+ self.pos = _save2
570
+ break
571
+ end
572
+ @result = begin; ZeroPad.new(0) ; end
573
+ _tmp = true
574
+ unless _tmp
575
+ self.pos = _save2
576
+ end
577
+ break
578
+ end # end sequence
579
+
580
+ break if _tmp
581
+ self.pos = _save
582
+
583
+ _save6 = self.pos
584
+ while true # sequence
585
+ _tmp = match_string(".")
586
+ unless _tmp
587
+ self.pos = _save6
588
+ break
589
+ end
590
+ _text_start = self.pos
591
+ _tmp = scan(/\A(?-mix:\d+)/)
592
+ if _tmp
593
+ text = get_text(_text_start)
594
+ end
595
+ unless _tmp
596
+ self.pos = _save6
597
+ break
598
+ end
599
+ @result = begin; Precision.new(0, text.to_i) ; end
600
+ _tmp = true
601
+ unless _tmp
602
+ self.pos = _save6
603
+ end
604
+ break
605
+ end # end sequence
606
+
607
+ break if _tmp
608
+ self.pos = _save
609
+
610
+ _save7 = self.pos
611
+ while true # sequence
612
+ _text_start = self.pos
613
+ _tmp = scan(/\A(?-mix:\d+)/)
614
+ if _tmp
615
+ text = get_text(_text_start)
616
+ end
617
+ unless _tmp
618
+ self.pos = _save7
619
+ break
620
+ end
621
+ @result = begin; Number.new(0, text.to_i) ; end
622
+ _tmp = true
623
+ unless _tmp
624
+ self.pos = _save7
625
+ end
626
+ break
627
+ end # end sequence
628
+
629
+ break if _tmp
630
+ self.pos = _save
631
+
632
+ _save8 = self.pos
633
+ while true # sequence
634
+ _text_start = self.pos
635
+ _tmp = scan(/\A(?-mix:[\.\+\*=<>,\?])/)
636
+ if _tmp
637
+ text = get_text(_text_start)
638
+ end
639
+ unless _tmp
640
+ self.pos = _save8
641
+ break
642
+ end
643
+ @result = begin; Symbol.new(0, text) ; end
644
+ _tmp = true
645
+ unless _tmp
646
+ self.pos = _save8
647
+ end
648
+ break
649
+ end # end sequence
650
+
651
+ break if _tmp
652
+ self.pos = _save
653
+ break
654
+ end # end choice
655
+
656
+ set_failed_rule :_flag unless _tmp
657
+ return _tmp
658
+ end
659
+
660
+ # segment = ("p" "(" sub(")"):s ")" ("(" sub(")"):p ")")? { Pluralize.new(0, s, [], p) } | "l" "(" sub(")"):c ")" { create(Lowercase, c) } | "c" "(" sub(")"):c ")" { create(Capitalize, c) } | "u" "(" sub(")"):c ")" { create(Uppercase, c) } | "j" ("(" sub(")"):c ")" { c })+:cs { create(Justify, cs) } | "{" sub("}"):c "}" { create(Iterate, c) } | ("[" sub("]"):c "]" { c })+:bs ("(" sub(")"):d ")" { d })? { Conditional.new(0, Array(bs), [], d) } | "_" { create(Skip) } | "^" { create(Break) } | "%" { create(Indirection) } | "s" { create(String) } | "d" { create(Decimal) } | "x" { create(Hex) } | "o" { create(Octal) } | "b" { create(Binary) } | "r" { create(Radix) } | "f" { create(Float) } | "e" { create(Exponent) } | "g" { create(General) } | "c" { create(Character) } | "v" { create(Any) })
661
+ def _segment
662
+
663
+ _save = self.pos
664
+ while true # choice
665
+
666
+ _save1 = self.pos
667
+ while true # sequence
668
+ _tmp = match_string("p")
669
+ unless _tmp
670
+ self.pos = _save1
671
+ break
672
+ end
673
+ _tmp = match_string("(")
674
+ unless _tmp
675
+ self.pos = _save1
676
+ break
677
+ end
678
+ _tmp = _sub(")")
679
+ s = @result
680
+ unless _tmp
681
+ self.pos = _save1
682
+ break
683
+ end
684
+ _tmp = match_string(")")
685
+ unless _tmp
686
+ self.pos = _save1
687
+ break
688
+ end
689
+ _save2 = self.pos
690
+
691
+ _save3 = self.pos
692
+ while true # sequence
693
+ _tmp = match_string("(")
694
+ unless _tmp
695
+ self.pos = _save3
696
+ break
697
+ end
698
+ _tmp = _sub(")")
699
+ p = @result
700
+ unless _tmp
701
+ self.pos = _save3
702
+ break
703
+ end
704
+ _tmp = match_string(")")
705
+ unless _tmp
706
+ self.pos = _save3
707
+ end
708
+ break
709
+ end # end sequence
710
+
711
+ unless _tmp
712
+ _tmp = true
713
+ self.pos = _save2
714
+ end
715
+ unless _tmp
716
+ self.pos = _save1
717
+ break
718
+ end
719
+ @result = begin; Pluralize.new(0, s, [], p) ; end
720
+ _tmp = true
721
+ unless _tmp
722
+ self.pos = _save1
723
+ end
724
+ break
725
+ end # end sequence
726
+
727
+ break if _tmp
728
+ self.pos = _save
729
+
730
+ _save4 = self.pos
731
+ while true # sequence
732
+ _tmp = match_string("l")
733
+ unless _tmp
734
+ self.pos = _save4
735
+ break
736
+ end
737
+ _tmp = match_string("(")
738
+ unless _tmp
739
+ self.pos = _save4
740
+ break
741
+ end
742
+ _tmp = _sub(")")
743
+ c = @result
744
+ unless _tmp
745
+ self.pos = _save4
746
+ break
747
+ end
748
+ _tmp = match_string(")")
749
+ unless _tmp
750
+ self.pos = _save4
751
+ break
752
+ end
753
+ @result = begin; create(Lowercase, c) ; end
754
+ _tmp = true
755
+ unless _tmp
756
+ self.pos = _save4
757
+ end
758
+ break
759
+ end # end sequence
760
+
761
+ break if _tmp
762
+ self.pos = _save
763
+
764
+ _save5 = self.pos
765
+ while true # sequence
766
+ _tmp = match_string("c")
767
+ unless _tmp
768
+ self.pos = _save5
769
+ break
770
+ end
771
+ _tmp = match_string("(")
772
+ unless _tmp
773
+ self.pos = _save5
774
+ break
775
+ end
776
+ _tmp = _sub(")")
777
+ c = @result
778
+ unless _tmp
779
+ self.pos = _save5
780
+ break
781
+ end
782
+ _tmp = match_string(")")
783
+ unless _tmp
784
+ self.pos = _save5
785
+ break
786
+ end
787
+ @result = begin; create(Capitalize, c) ; end
788
+ _tmp = true
789
+ unless _tmp
790
+ self.pos = _save5
791
+ end
792
+ break
793
+ end # end sequence
794
+
795
+ break if _tmp
796
+ self.pos = _save
797
+
798
+ _save6 = self.pos
799
+ while true # sequence
800
+ _tmp = match_string("u")
801
+ unless _tmp
802
+ self.pos = _save6
803
+ break
804
+ end
805
+ _tmp = match_string("(")
806
+ unless _tmp
807
+ self.pos = _save6
808
+ break
809
+ end
810
+ _tmp = _sub(")")
811
+ c = @result
812
+ unless _tmp
813
+ self.pos = _save6
814
+ break
815
+ end
816
+ _tmp = match_string(")")
817
+ unless _tmp
818
+ self.pos = _save6
819
+ break
820
+ end
821
+ @result = begin; create(Uppercase, c) ; end
822
+ _tmp = true
823
+ unless _tmp
824
+ self.pos = _save6
825
+ end
826
+ break
827
+ end # end sequence
828
+
829
+ break if _tmp
830
+ self.pos = _save
831
+
832
+ _save7 = self.pos
833
+ while true # sequence
834
+ _tmp = match_string("j")
835
+ unless _tmp
836
+ self.pos = _save7
837
+ break
838
+ end
839
+ _save8 = self.pos
840
+ _ary = []
841
+
842
+ _save9 = self.pos
843
+ while true # sequence
844
+ _tmp = match_string("(")
845
+ unless _tmp
846
+ self.pos = _save9
847
+ break
848
+ end
849
+ _tmp = _sub(")")
850
+ c = @result
851
+ unless _tmp
852
+ self.pos = _save9
853
+ break
854
+ end
855
+ _tmp = match_string(")")
856
+ unless _tmp
857
+ self.pos = _save9
858
+ break
859
+ end
860
+ @result = begin; c ; end
861
+ _tmp = true
862
+ unless _tmp
863
+ self.pos = _save9
864
+ end
865
+ break
866
+ end # end sequence
867
+
868
+ if _tmp
869
+ _ary << @result
870
+ while true
871
+
872
+ _save10 = self.pos
873
+ while true # sequence
874
+ _tmp = match_string("(")
875
+ unless _tmp
876
+ self.pos = _save10
877
+ break
878
+ end
879
+ _tmp = _sub(")")
880
+ c = @result
881
+ unless _tmp
882
+ self.pos = _save10
883
+ break
884
+ end
885
+ _tmp = match_string(")")
886
+ unless _tmp
887
+ self.pos = _save10
888
+ break
889
+ end
890
+ @result = begin; c ; end
891
+ _tmp = true
892
+ unless _tmp
893
+ self.pos = _save10
894
+ end
895
+ break
896
+ end # end sequence
897
+
898
+ _ary << @result if _tmp
899
+ break unless _tmp
900
+ end
901
+ _tmp = true
902
+ @result = _ary
903
+ else
904
+ self.pos = _save8
905
+ end
906
+ cs = @result
907
+ unless _tmp
908
+ self.pos = _save7
909
+ break
910
+ end
911
+ @result = begin; create(Justify, cs) ; end
912
+ _tmp = true
913
+ unless _tmp
914
+ self.pos = _save7
915
+ end
916
+ break
917
+ end # end sequence
918
+
919
+ break if _tmp
920
+ self.pos = _save
921
+
922
+ _save11 = self.pos
923
+ while true # sequence
924
+ _tmp = match_string("{")
925
+ unless _tmp
926
+ self.pos = _save11
927
+ break
928
+ end
929
+ _tmp = _sub("}")
930
+ c = @result
931
+ unless _tmp
932
+ self.pos = _save11
933
+ break
934
+ end
935
+ _tmp = match_string("}")
936
+ unless _tmp
937
+ self.pos = _save11
938
+ break
939
+ end
940
+ @result = begin; create(Iterate, c) ; end
941
+ _tmp = true
942
+ unless _tmp
943
+ self.pos = _save11
944
+ end
945
+ break
946
+ end # end sequence
947
+
948
+ break if _tmp
949
+ self.pos = _save
950
+
951
+ _save12 = self.pos
952
+ while true # sequence
953
+ _save13 = self.pos
954
+ _ary = []
955
+
956
+ _save14 = self.pos
957
+ while true # sequence
958
+ _tmp = match_string("[")
959
+ unless _tmp
960
+ self.pos = _save14
961
+ break
962
+ end
963
+ _tmp = _sub("]")
964
+ c = @result
965
+ unless _tmp
966
+ self.pos = _save14
967
+ break
968
+ end
969
+ _tmp = match_string("]")
970
+ unless _tmp
971
+ self.pos = _save14
972
+ break
973
+ end
974
+ @result = begin; c ; end
975
+ _tmp = true
976
+ unless _tmp
977
+ self.pos = _save14
978
+ end
979
+ break
980
+ end # end sequence
981
+
982
+ if _tmp
983
+ _ary << @result
984
+ while true
985
+
986
+ _save15 = self.pos
987
+ while true # sequence
988
+ _tmp = match_string("[")
989
+ unless _tmp
990
+ self.pos = _save15
991
+ break
992
+ end
993
+ _tmp = _sub("]")
994
+ c = @result
995
+ unless _tmp
996
+ self.pos = _save15
997
+ break
998
+ end
999
+ _tmp = match_string("]")
1000
+ unless _tmp
1001
+ self.pos = _save15
1002
+ break
1003
+ end
1004
+ @result = begin; c ; end
1005
+ _tmp = true
1006
+ unless _tmp
1007
+ self.pos = _save15
1008
+ end
1009
+ break
1010
+ end # end sequence
1011
+
1012
+ _ary << @result if _tmp
1013
+ break unless _tmp
1014
+ end
1015
+ _tmp = true
1016
+ @result = _ary
1017
+ else
1018
+ self.pos = _save13
1019
+ end
1020
+ bs = @result
1021
+ unless _tmp
1022
+ self.pos = _save12
1023
+ break
1024
+ end
1025
+ _save16 = self.pos
1026
+
1027
+ _save17 = self.pos
1028
+ while true # sequence
1029
+ _tmp = match_string("(")
1030
+ unless _tmp
1031
+ self.pos = _save17
1032
+ break
1033
+ end
1034
+ _tmp = _sub(")")
1035
+ d = @result
1036
+ unless _tmp
1037
+ self.pos = _save17
1038
+ break
1039
+ end
1040
+ _tmp = match_string(")")
1041
+ unless _tmp
1042
+ self.pos = _save17
1043
+ break
1044
+ end
1045
+ @result = begin; d ; end
1046
+ _tmp = true
1047
+ unless _tmp
1048
+ self.pos = _save17
1049
+ end
1050
+ break
1051
+ end # end sequence
1052
+
1053
+ unless _tmp
1054
+ _tmp = true
1055
+ self.pos = _save16
1056
+ end
1057
+ unless _tmp
1058
+ self.pos = _save12
1059
+ break
1060
+ end
1061
+ @result = begin; Conditional.new(0, Array(bs), [], d) ; end
1062
+ _tmp = true
1063
+ unless _tmp
1064
+ self.pos = _save12
1065
+ end
1066
+ break
1067
+ end # end sequence
1068
+
1069
+ break if _tmp
1070
+ self.pos = _save
1071
+
1072
+ _save18 = self.pos
1073
+ while true # sequence
1074
+ _tmp = match_string("_")
1075
+ unless _tmp
1076
+ self.pos = _save18
1077
+ break
1078
+ end
1079
+ @result = begin; create(Skip) ; end
1080
+ _tmp = true
1081
+ unless _tmp
1082
+ self.pos = _save18
1083
+ end
1084
+ break
1085
+ end # end sequence
1086
+
1087
+ break if _tmp
1088
+ self.pos = _save
1089
+
1090
+ _save19 = self.pos
1091
+ while true # sequence
1092
+ _tmp = match_string("^")
1093
+ unless _tmp
1094
+ self.pos = _save19
1095
+ break
1096
+ end
1097
+ @result = begin; create(Break) ; end
1098
+ _tmp = true
1099
+ unless _tmp
1100
+ self.pos = _save19
1101
+ end
1102
+ break
1103
+ end # end sequence
1104
+
1105
+ break if _tmp
1106
+ self.pos = _save
1107
+
1108
+ _save20 = self.pos
1109
+ while true # sequence
1110
+ _tmp = match_string("%")
1111
+ unless _tmp
1112
+ self.pos = _save20
1113
+ break
1114
+ end
1115
+ @result = begin; create(Indirection) ; end
1116
+ _tmp = true
1117
+ unless _tmp
1118
+ self.pos = _save20
1119
+ end
1120
+ break
1121
+ end # end sequence
1122
+
1123
+ break if _tmp
1124
+ self.pos = _save
1125
+
1126
+ _save21 = self.pos
1127
+ while true # sequence
1128
+ _tmp = match_string("s")
1129
+ unless _tmp
1130
+ self.pos = _save21
1131
+ break
1132
+ end
1133
+ @result = begin; create(String) ; end
1134
+ _tmp = true
1135
+ unless _tmp
1136
+ self.pos = _save21
1137
+ end
1138
+ break
1139
+ end # end sequence
1140
+
1141
+ break if _tmp
1142
+ self.pos = _save
1143
+
1144
+ _save22 = self.pos
1145
+ while true # sequence
1146
+ _tmp = match_string("d")
1147
+ unless _tmp
1148
+ self.pos = _save22
1149
+ break
1150
+ end
1151
+ @result = begin; create(Decimal) ; end
1152
+ _tmp = true
1153
+ unless _tmp
1154
+ self.pos = _save22
1155
+ end
1156
+ break
1157
+ end # end sequence
1158
+
1159
+ break if _tmp
1160
+ self.pos = _save
1161
+
1162
+ _save23 = self.pos
1163
+ while true # sequence
1164
+ _tmp = match_string("x")
1165
+ unless _tmp
1166
+ self.pos = _save23
1167
+ break
1168
+ end
1169
+ @result = begin; create(Hex) ; end
1170
+ _tmp = true
1171
+ unless _tmp
1172
+ self.pos = _save23
1173
+ end
1174
+ break
1175
+ end # end sequence
1176
+
1177
+ break if _tmp
1178
+ self.pos = _save
1179
+
1180
+ _save24 = self.pos
1181
+ while true # sequence
1182
+ _tmp = match_string("o")
1183
+ unless _tmp
1184
+ self.pos = _save24
1185
+ break
1186
+ end
1187
+ @result = begin; create(Octal) ; end
1188
+ _tmp = true
1189
+ unless _tmp
1190
+ self.pos = _save24
1191
+ end
1192
+ break
1193
+ end # end sequence
1194
+
1195
+ break if _tmp
1196
+ self.pos = _save
1197
+
1198
+ _save25 = self.pos
1199
+ while true # sequence
1200
+ _tmp = match_string("b")
1201
+ unless _tmp
1202
+ self.pos = _save25
1203
+ break
1204
+ end
1205
+ @result = begin; create(Binary) ; end
1206
+ _tmp = true
1207
+ unless _tmp
1208
+ self.pos = _save25
1209
+ end
1210
+ break
1211
+ end # end sequence
1212
+
1213
+ break if _tmp
1214
+ self.pos = _save
1215
+
1216
+ _save26 = self.pos
1217
+ while true # sequence
1218
+ _tmp = match_string("r")
1219
+ unless _tmp
1220
+ self.pos = _save26
1221
+ break
1222
+ end
1223
+ @result = begin; create(Radix) ; end
1224
+ _tmp = true
1225
+ unless _tmp
1226
+ self.pos = _save26
1227
+ end
1228
+ break
1229
+ end # end sequence
1230
+
1231
+ break if _tmp
1232
+ self.pos = _save
1233
+
1234
+ _save27 = self.pos
1235
+ while true # sequence
1236
+ _tmp = match_string("f")
1237
+ unless _tmp
1238
+ self.pos = _save27
1239
+ break
1240
+ end
1241
+ @result = begin; create(Float) ; end
1242
+ _tmp = true
1243
+ unless _tmp
1244
+ self.pos = _save27
1245
+ end
1246
+ break
1247
+ end # end sequence
1248
+
1249
+ break if _tmp
1250
+ self.pos = _save
1251
+
1252
+ _save28 = self.pos
1253
+ while true # sequence
1254
+ _tmp = match_string("e")
1255
+ unless _tmp
1256
+ self.pos = _save28
1257
+ break
1258
+ end
1259
+ @result = begin; create(Exponent) ; end
1260
+ _tmp = true
1261
+ unless _tmp
1262
+ self.pos = _save28
1263
+ end
1264
+ break
1265
+ end # end sequence
1266
+
1267
+ break if _tmp
1268
+ self.pos = _save
1269
+
1270
+ _save29 = self.pos
1271
+ while true # sequence
1272
+ _tmp = match_string("g")
1273
+ unless _tmp
1274
+ self.pos = _save29
1275
+ break
1276
+ end
1277
+ @result = begin; create(General) ; end
1278
+ _tmp = true
1279
+ unless _tmp
1280
+ self.pos = _save29
1281
+ end
1282
+ break
1283
+ end # end sequence
1284
+
1285
+ break if _tmp
1286
+ self.pos = _save
1287
+
1288
+ _save30 = self.pos
1289
+ while true # sequence
1290
+ _tmp = match_string("c")
1291
+ unless _tmp
1292
+ self.pos = _save30
1293
+ break
1294
+ end
1295
+ @result = begin; create(Character) ; end
1296
+ _tmp = true
1297
+ unless _tmp
1298
+ self.pos = _save30
1299
+ end
1300
+ break
1301
+ end # end sequence
1302
+
1303
+ break if _tmp
1304
+ self.pos = _save
1305
+
1306
+ _save31 = self.pos
1307
+ while true # sequence
1308
+ _tmp = match_string("v")
1309
+ unless _tmp
1310
+ self.pos = _save31
1311
+ break
1312
+ end
1313
+ @result = begin; create(Any) ; end
1314
+ _tmp = true
1315
+ unless _tmp
1316
+ self.pos = _save31
1317
+ end
1318
+ break
1319
+ end # end sequence
1320
+
1321
+ break if _tmp
1322
+ self.pos = _save
1323
+ break
1324
+ end # end choice
1325
+
1326
+ set_failed_rule :_segment unless _tmp
1327
+ return _tmp
1328
+ end
1329
+
1330
+ # sub = (flagged | nested(e))*:as { Array(as) } { Formatter.new(0, Array(as)) }
1331
+ def _sub(e)
1332
+
1333
+ _save = self.pos
1334
+ while true # sequence
1335
+ _ary = []
1336
+ while true
1337
+
1338
+ _save2 = self.pos
1339
+ while true # choice
1340
+ _tmp = apply(:_flagged)
1341
+ break if _tmp
1342
+ self.pos = _save2
1343
+ _tmp = _nested(e)
1344
+ break if _tmp
1345
+ self.pos = _save2
1346
+ break
1347
+ end # end choice
1348
+
1349
+ _ary << @result if _tmp
1350
+ break unless _tmp
1351
+ end
1352
+ _tmp = true
1353
+ @result = _ary
1354
+ as = @result
1355
+ unless _tmp
1356
+ self.pos = _save
1357
+ break
1358
+ end
1359
+ @result = begin; Array(as) ; end
1360
+ _tmp = true
1361
+ unless _tmp
1362
+ self.pos = _save
1363
+ break
1364
+ end
1365
+ @result = begin; Formatter.new(0, Array(as)) ; end
1366
+ _tmp = true
1367
+ unless _tmp
1368
+ self.pos = _save
1369
+ end
1370
+ break
1371
+ end # end sequence
1372
+
1373
+ set_failed_rule :_sub unless _tmp
1374
+ return _tmp
1375
+ end
1376
+
1377
+ # root = sub("")
1378
+ def _root
1379
+ _tmp = _sub("")
1380
+ set_failed_rule :_root unless _tmp
1381
+ return _tmp
1382
+ end
1383
+
1384
+ Rules = {}
1385
+ Rules[:_line] = rule_info("line", "{ current_line }")
1386
+ Rules[:_text] = rule_info("text", "(< /[^\\\\%\#{Regexp.quote(e)}]+/ > { text } | \"\\\\\" < /[%\\(\\)\\{\\}\\[\\]]/ > { text } | \"\\\\\" %atomy.escape:e { e })")
1387
+ Rules[:_nested] = rule_info("nested", "text(e)+:c { Chunk.new(0, [], c.join) }")
1388
+ Rules[:_chunk] = rule_info("chunk", "nested(\"\")")
1389
+ Rules[:_flagged] = rule_info("flagged", "\"%\" flag*:fs segment:s { s.flags = fs; s }")
1390
+ Rules[:_flag] = rule_info("flag", "(\"\#\" { Number.new(0, nil) } | \"0\" &(\".\" /\\d/ | /\\d/) { ZeroPad.new(0) } | \".\" < /\\d+/ > { Precision.new(0, text.to_i) } | < /\\d+/ > { Number.new(0, text.to_i) } | < /[\\.\\+\\*=<>,\\?]/ > { Symbol.new(0, text) })")
1391
+ Rules[:_segment] = rule_info("segment", "(\"p\" \"(\" sub(\")\"):s \")\" (\"(\" sub(\")\"):p \")\")? { Pluralize.new(0, s, [], p) } | \"l\" \"(\" sub(\")\"):c \")\" { create(Lowercase, c) } | \"c\" \"(\" sub(\")\"):c \")\" { create(Capitalize, c) } | \"u\" \"(\" sub(\")\"):c \")\" { create(Uppercase, c) } | \"j\" (\"(\" sub(\")\"):c \")\" { c })+:cs { create(Justify, cs) } | \"{\" sub(\"}\"):c \"}\" { create(Iterate, c) } | (\"[\" sub(\"]\"):c \"]\" { c })+:bs (\"(\" sub(\")\"):d \")\" { d })? { Conditional.new(0, Array(bs), [], d) } | \"_\" { create(Skip) } | \"^\" { create(Break) } | \"%\" { create(Indirection) } | \"s\" { create(String) } | \"d\" { create(Decimal) } | \"x\" { create(Hex) } | \"o\" { create(Octal) } | \"b\" { create(Binary) } | \"r\" { create(Radix) } | \"f\" { create(Float) } | \"e\" { create(Exponent) } | \"g\" { create(General) } | \"c\" { create(Character) } | \"v\" { create(Any) })")
1392
+ Rules[:_sub] = rule_info("sub", "(flagged | nested(e))*:as { Array(as) } { Formatter.new(0, Array(as)) }")
1393
+ Rules[:_root] = rule_info("root", "sub(\"\")")
1394
+ end