weskit 0.1.0 → 0.2.0
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.
- data/.gitignore +1 -0
- data/README.md +25 -10
- data/Rakefile +8 -1
- data/lib/weskit/version.rb +1 -1
- data/lib/weskit/wml.rb +1 -1
- data/lib/weskit/wml/attribute.rb +0 -4
- data/lib/weskit/wml/grammars/wml.kpeg +91 -0
- data/lib/weskit/wml/kpeg_parser.rb +1521 -0
- data/lib/weskit/wml/parser.rb +6 -13
- data/spec/wml/parser_spec.rb +16 -7
- data/weskit.gemspec +4 -6
- metadata +93 -111
- data/lib/weskit/wml/grammars/wml.treetop +0 -195
- data/lib/weskit/wml/wml.rb +0 -1580
data/README.md
CHANGED
@@ -6,7 +6,7 @@ them is the key to understaning any other stuff bundled. This README gives quick
|
|
6
6
|
overview of Weskit WML capabilities. For more information you have to check source code and
|
7
7
|
[generated documentation](http://www.rubydoc.info/github/f6p/weskit/frames).
|
8
8
|
|
9
|
-
##
|
9
|
+
## Containers
|
10
10
|
|
11
11
|
Elements in WML document dosn't have one parent. Instead of using arrays to store multiple WML objects
|
12
12
|
create instance of Weskit::WML::Root. It will let you to call advanced features avaiable for other
|
@@ -78,10 +78,13 @@ you can do this:
|
|
78
78
|
id is a helper method (as it interfers with Object#id) that is equivalent to:
|
79
79
|
|
80
80
|
```ruby
|
81
|
-
attribute
|
81
|
+
attribute(:id, value)
|
82
82
|
```
|
83
83
|
|
84
|
-
|
84
|
+
And oh well... Let's not forget that after all builder block is
|
85
|
+
Ruby code so you can use any langague construct inside it as well.
|
86
|
+
|
87
|
+
## Tree searching
|
85
88
|
|
86
89
|
You can search WML elements and containers for nodes of specific type. For
|
87
90
|
example lets say there is a object tree representing such WML structure:
|
@@ -107,8 +110,8 @@ To get Weskit::WML::Elements container with references to all b elements you can
|
|
107
110
|
root.a.b
|
108
111
|
```
|
109
112
|
|
110
|
-
This code takes advantage of method_missing and if you can't
|
111
|
-
(because of method name conflicts) equivalent
|
113
|
+
This code takes advantage of method_missing as well and if you can't use
|
114
|
+
it that (because of method name conflicts) its equivalent can be used:
|
112
115
|
|
113
116
|
```ruby
|
114
117
|
root.find(:a).find(:b)
|
@@ -117,19 +120,31 @@ This code takes advantage of method_missing and if you can't do that
|
|
117
120
|
as missing calls are delegated to find method. There is also find_recursively
|
118
121
|
method that lets you to find elements using object criteria specified in block.
|
119
122
|
|
120
|
-
##
|
123
|
+
## Representation
|
121
124
|
|
122
125
|
Weskit::WML objects dosn't have any representation code coupled. Special class of objects called Formatters is
|
123
126
|
used to handle their display. Most commonly you will use plain text representation (default formatter)
|
124
127
|
or terminal friendly colorful version of it (color formatter). Most of WML objects provide formatter
|
125
128
|
seter to replace formatter associated with them but you can as well change default formatter globally
|
126
|
-
by calling Formatter.default=
|
129
|
+
by calling Formatter.default= method.
|
127
130
|
|
128
131
|
Whatever representation you need (JSON, XML, YAML) creating new formaters shouldn't
|
129
132
|
be hard. Take look at Weskit::WML::Formatters module for further reference on that matter.
|
130
133
|
|
131
|
-
##
|
134
|
+
## Parser
|
132
135
|
|
133
|
-
Parser
|
134
|
-
|
136
|
+
Parser provides two methods: string - for parsing strings and uri - for parsing files. uri
|
137
|
+
method can load remote files as well as it transparently handles archive extraction. Parsing
|
135
138
|
results in return of WML object tree with one Weskit::WML::Root as the top-most element.
|
139
|
+
|
140
|
+
## Limitations
|
141
|
+
|
142
|
+
Lack of preprocessor support as WML module is supposed to work with preprocessed files
|
143
|
+
(at least for now). Preprocessor directives will be consumed as comments and that can
|
144
|
+
lead to unexpected behaviour at times. For example if you have macro defined its
|
145
|
+
contents will be added to parent element.
|
146
|
+
|
147
|
+
## TODO
|
148
|
+
|
149
|
+
Implement preprocessor directives as first class memebers
|
150
|
+
that could be manipulated like any other WML node.
|
data/Rakefile
CHANGED
@@ -2,4 +2,11 @@ require "bundler/gem_tasks"
|
|
2
2
|
require 'rspec/core/rake_task'
|
3
3
|
|
4
4
|
RSpec::Core::RakeTask.new 'spec'
|
5
|
-
task :default => :spec
|
5
|
+
task :default => :spec
|
6
|
+
|
7
|
+
namespace :kpeg do
|
8
|
+
desc 'Re-build KPEGParser'
|
9
|
+
task :rebuild do
|
10
|
+
puts %x(kpeg -fsvo lib/weskit/wml/kpeg_parser.rb lib/weskit/wml/grammars/wml.kpeg)
|
11
|
+
end
|
12
|
+
end
|
data/lib/weskit/version.rb
CHANGED
data/lib/weskit/wml.rb
CHANGED
@@ -14,4 +14,4 @@ w.require_all %w{validator grammar searchable container}, :mixins
|
|
14
14
|
w.require_all %w{object}, :extensions
|
15
15
|
w.require_all %w{error invalid_identifier invalid_item invalid_option invalid_parameters parse_error read_error}, :errors
|
16
16
|
w.require_all %w{item_formatter attribute element ansi_color ansi_color_attribute ansi_color_element}, :formatters
|
17
|
-
w.require_all %w{item items attribute attributes builder element elements formatter
|
17
|
+
w.require_all %w{item items attribute attributes builder element elements formatter kpeg_parser parser root}
|
data/lib/weskit/wml/attribute.rb
CHANGED
@@ -0,0 +1,91 @@
|
|
1
|
+
# Parser =======================================================================
|
2
|
+
|
3
|
+
%% header {
|
4
|
+
module Weskit::WML
|
5
|
+
}
|
6
|
+
|
7
|
+
%% name = KPEGParser
|
8
|
+
|
9
|
+
%% {
|
10
|
+
attr_accessor :result
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def strip_chars string, chars
|
15
|
+
string[chars, string.length - chars * 2]
|
16
|
+
end
|
17
|
+
}
|
18
|
+
|
19
|
+
%% footer {
|
20
|
+
end
|
21
|
+
}
|
22
|
+
|
23
|
+
# Rules ========================================================================
|
24
|
+
|
25
|
+
id = < /[a-z][a-z_]*/i > { text }
|
26
|
+
ids = ids:i1 - ',' - ids:i2 { i1 + i2 }
|
27
|
+
| id:i { [i] }
|
28
|
+
|
29
|
+
item = attribute | attributes | element
|
30
|
+
items = items:i1 items:i2 { i1 + i2 }
|
31
|
+
| item:i { (i.is_a? Array) ? i : [i] }
|
32
|
+
|
33
|
+
contents = items?:i { i.to_a }
|
34
|
+
|
35
|
+
# Attributes -------------------------------------------------------------------
|
36
|
+
|
37
|
+
single_attr = - id:n - '=' - val:v - eol
|
38
|
+
{ Attribute.new n, *v }
|
39
|
+
multiple_attrs = - ids:n - '=' - vals:v - eol
|
40
|
+
{ n.reduce(Array.new) do |attrs, name|
|
41
|
+
value =v.shift or [nil]
|
42
|
+
attrs << Attribute.new(name, *value)
|
43
|
+
end }
|
44
|
+
|
45
|
+
attribute = blk_lines single_attr:a blk_lines { a }
|
46
|
+
attributes = blk_lines multiple_attrs:a blk_lines { a }
|
47
|
+
|
48
|
+
# Attribute values -------------------------------------------------------------
|
49
|
+
|
50
|
+
code = < /<<.*?>>/m > { [strip_chars(text, 2), {:code => true}] }
|
51
|
+
in_brackets = < /\(.*?\)/m > { [strip_chars(text, 1)] }
|
52
|
+
in_quotes = < /".*?"/m > { [strip_chars(text, 1)] }
|
53
|
+
raw = < /.*/ > { [text.strip] }
|
54
|
+
|
55
|
+
escaped = in_quotes:s1 escaped:s2 { s1[0] += '"' + s2[0] ; s1 }
|
56
|
+
| in_quotes
|
57
|
+
i18n = '_' - (in_brackets | in_quotes):s { [s[0], {:translatable => true}] }
|
58
|
+
|
59
|
+
val = val:v1 - '+' sp_lf val:v2 { v1[0] += v2[0] ; v1 }
|
60
|
+
| escaped | i18n | code | in_brackets | in_quotes | raw
|
61
|
+
vals = vals:v1 - ',' - vals:v2 { v1 + v2 }
|
62
|
+
| val:v { [v] }
|
63
|
+
|
64
|
+
# Elements ---------------------------------------------------------------------
|
65
|
+
|
66
|
+
amendment = - amending_tag:n - eol contents:c - closing_tag(n) - eol
|
67
|
+
{ Element.new(n, :amendment => true).push *c }
|
68
|
+
regular = - opening_tag:n - eol contents:c - closing_tag(n) - eol
|
69
|
+
{ Element.new(n).push *c }
|
70
|
+
|
71
|
+
element = blk_lines (amendment | regular):e blk_lines { e }
|
72
|
+
|
73
|
+
# Tags -------------------------------------------------------------------------
|
74
|
+
|
75
|
+
amending_tag = '[+' id:n ']' { n }
|
76
|
+
closing_tag(m) = '[/' id:n ']' &{ n == m }
|
77
|
+
opening_tag = '[' id:n ']' { n }
|
78
|
+
|
79
|
+
# Whitespace -------------------------------------------------------------------
|
80
|
+
|
81
|
+
eof = !.
|
82
|
+
eol = "\r\n" | "\n"
|
83
|
+
sp = " " | "\t"
|
84
|
+
|
85
|
+
- = sp*
|
86
|
+
sp_lf = (sp | eol)*
|
87
|
+
blk_lines = (- eol)*
|
88
|
+
|
89
|
+
# Root -------------------------------------------------------------------------
|
90
|
+
|
91
|
+
root = contents:c { Root.new.push *c }
|
@@ -0,0 +1,1521 @@
|
|
1
|
+
module Weskit::WML
|
2
|
+
class KPEGParser
|
3
|
+
# :stopdoc:
|
4
|
+
|
5
|
+
# This is distinct from setup_parser so that a standalone parser
|
6
|
+
# can redefine #initialize and still have access to the proper
|
7
|
+
# parser setup code.
|
8
|
+
def initialize(str, debug=false)
|
9
|
+
setup_parser(str, debug)
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
# Prepares for parsing +str+. If you define a custom initialize you must
|
15
|
+
# call this method before #parse
|
16
|
+
def setup_parser(str, debug=false)
|
17
|
+
@string = str
|
18
|
+
@pos = 0
|
19
|
+
@memoizations = Hash.new { |h,k| h[k] = {} }
|
20
|
+
@result = nil
|
21
|
+
@failed_rule = nil
|
22
|
+
@failing_rule_offset = -1
|
23
|
+
|
24
|
+
setup_foreign_grammar
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_reader :string
|
28
|
+
attr_reader :failing_rule_offset
|
29
|
+
attr_accessor :result, :pos
|
30
|
+
|
31
|
+
|
32
|
+
def current_column(target=pos)
|
33
|
+
if c = string.rindex("\n", target-1)
|
34
|
+
return target - c - 1
|
35
|
+
end
|
36
|
+
|
37
|
+
target + 1
|
38
|
+
end
|
39
|
+
|
40
|
+
def current_line(target=pos)
|
41
|
+
cur_offset = 0
|
42
|
+
cur_line = 0
|
43
|
+
|
44
|
+
string.each_line do |line|
|
45
|
+
cur_line += 1
|
46
|
+
cur_offset += line.size
|
47
|
+
return cur_line if cur_offset >= target
|
48
|
+
end
|
49
|
+
|
50
|
+
-1
|
51
|
+
end
|
52
|
+
|
53
|
+
def lines
|
54
|
+
lines = []
|
55
|
+
string.each_line { |l| lines << l }
|
56
|
+
lines
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
def get_text(start)
|
62
|
+
@string[start..@pos-1]
|
63
|
+
end
|
64
|
+
|
65
|
+
def show_pos
|
66
|
+
width = 10
|
67
|
+
if @pos < width
|
68
|
+
"#{@pos} (\"#{@string[0,@pos]}\" @ \"#{@string[@pos,width]}\")"
|
69
|
+
else
|
70
|
+
"#{@pos} (\"... #{@string[@pos - width, width]}\" @ \"#{@string[@pos,width]}\")"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def failure_info
|
75
|
+
l = current_line @failing_rule_offset
|
76
|
+
c = current_column @failing_rule_offset
|
77
|
+
|
78
|
+
if @failed_rule.kind_of? Symbol
|
79
|
+
info = self.class::Rules[@failed_rule]
|
80
|
+
"line #{l}, column #{c}: failed rule '#{info.name}' = '#{info.rendered}'"
|
81
|
+
else
|
82
|
+
"line #{l}, column #{c}: failed rule '#{@failed_rule}'"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def failure_caret
|
87
|
+
l = current_line @failing_rule_offset
|
88
|
+
c = current_column @failing_rule_offset
|
89
|
+
|
90
|
+
line = lines[l-1]
|
91
|
+
"#{line}\n#{' ' * (c - 1)}^"
|
92
|
+
end
|
93
|
+
|
94
|
+
def failure_character
|
95
|
+
l = current_line @failing_rule_offset
|
96
|
+
c = current_column @failing_rule_offset
|
97
|
+
lines[l-1][c-1, 1]
|
98
|
+
end
|
99
|
+
|
100
|
+
def failure_oneline
|
101
|
+
l = current_line @failing_rule_offset
|
102
|
+
c = current_column @failing_rule_offset
|
103
|
+
|
104
|
+
char = lines[l-1][c-1, 1]
|
105
|
+
|
106
|
+
if @failed_rule.kind_of? Symbol
|
107
|
+
info = self.class::Rules[@failed_rule]
|
108
|
+
"@#{l}:#{c} failed rule '#{info.name}', got '#{char}'"
|
109
|
+
else
|
110
|
+
"@#{l}:#{c} failed rule '#{@failed_rule}', got '#{char}'"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
class ParseError < RuntimeError
|
115
|
+
end
|
116
|
+
|
117
|
+
def raise_error
|
118
|
+
raise ParseError, failure_oneline
|
119
|
+
end
|
120
|
+
|
121
|
+
def show_error(io=STDOUT)
|
122
|
+
error_pos = @failing_rule_offset
|
123
|
+
line_no = current_line(error_pos)
|
124
|
+
col_no = current_column(error_pos)
|
125
|
+
|
126
|
+
io.puts "On line #{line_no}, column #{col_no}:"
|
127
|
+
|
128
|
+
if @failed_rule.kind_of? Symbol
|
129
|
+
info = self.class::Rules[@failed_rule]
|
130
|
+
io.puts "Failed to match '#{info.rendered}' (rule '#{info.name}')"
|
131
|
+
else
|
132
|
+
io.puts "Failed to match rule '#{@failed_rule}'"
|
133
|
+
end
|
134
|
+
|
135
|
+
io.puts "Got: #{string[error_pos,1].inspect}"
|
136
|
+
line = lines[line_no-1]
|
137
|
+
io.puts "=> #{line}"
|
138
|
+
io.print(" " * (col_no + 3))
|
139
|
+
io.puts "^"
|
140
|
+
end
|
141
|
+
|
142
|
+
def set_failed_rule(name)
|
143
|
+
if @pos > @failing_rule_offset
|
144
|
+
@failed_rule = name
|
145
|
+
@failing_rule_offset = @pos
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
attr_reader :failed_rule
|
150
|
+
|
151
|
+
def match_string(str)
|
152
|
+
len = str.size
|
153
|
+
if @string[pos,len] == str
|
154
|
+
@pos += len
|
155
|
+
return str
|
156
|
+
end
|
157
|
+
|
158
|
+
return nil
|
159
|
+
end
|
160
|
+
|
161
|
+
def scan(reg)
|
162
|
+
if m = reg.match(@string[@pos..-1])
|
163
|
+
width = m.end(0)
|
164
|
+
@pos += width
|
165
|
+
return true
|
166
|
+
end
|
167
|
+
|
168
|
+
return nil
|
169
|
+
end
|
170
|
+
|
171
|
+
if "".respond_to? :getbyte
|
172
|
+
def get_byte
|
173
|
+
if @pos >= @string.size
|
174
|
+
return nil
|
175
|
+
end
|
176
|
+
|
177
|
+
s = @string.getbyte @pos
|
178
|
+
@pos += 1
|
179
|
+
s
|
180
|
+
end
|
181
|
+
else
|
182
|
+
def get_byte
|
183
|
+
if @pos >= @string.size
|
184
|
+
return nil
|
185
|
+
end
|
186
|
+
|
187
|
+
s = @string[@pos]
|
188
|
+
@pos += 1
|
189
|
+
s
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def parse(rule=nil)
|
194
|
+
# We invoke the rules indirectly via apply
|
195
|
+
# instead of by just calling them as methods because
|
196
|
+
# if the rules use left recursion, apply needs to
|
197
|
+
# manage that.
|
198
|
+
|
199
|
+
if !rule
|
200
|
+
apply(:_root)
|
201
|
+
else
|
202
|
+
method = rule.gsub("-","_hyphen_")
|
203
|
+
apply :"_#{method}"
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
class MemoEntry
|
208
|
+
def initialize(ans, pos)
|
209
|
+
@ans = ans
|
210
|
+
@pos = pos
|
211
|
+
@result = nil
|
212
|
+
@set = false
|
213
|
+
@left_rec = false
|
214
|
+
end
|
215
|
+
|
216
|
+
attr_reader :ans, :pos, :result, :set
|
217
|
+
attr_accessor :left_rec
|
218
|
+
|
219
|
+
def move!(ans, pos, result)
|
220
|
+
@ans = ans
|
221
|
+
@pos = pos
|
222
|
+
@result = result
|
223
|
+
@set = true
|
224
|
+
@left_rec = false
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
def external_invoke(other, rule, *args)
|
229
|
+
old_pos = @pos
|
230
|
+
old_string = @string
|
231
|
+
|
232
|
+
@pos = other.pos
|
233
|
+
@string = other.string
|
234
|
+
|
235
|
+
begin
|
236
|
+
if val = __send__(rule, *args)
|
237
|
+
other.pos = @pos
|
238
|
+
other.result = @result
|
239
|
+
else
|
240
|
+
other.set_failed_rule "#{self.class}##{rule}"
|
241
|
+
end
|
242
|
+
val
|
243
|
+
ensure
|
244
|
+
@pos = old_pos
|
245
|
+
@string = old_string
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
def apply_with_args(rule, *args)
|
250
|
+
memo_key = [rule, args]
|
251
|
+
if m = @memoizations[memo_key][@pos]
|
252
|
+
@pos = m.pos
|
253
|
+
if !m.set
|
254
|
+
m.left_rec = true
|
255
|
+
return nil
|
256
|
+
end
|
257
|
+
|
258
|
+
@result = m.result
|
259
|
+
|
260
|
+
return m.ans
|
261
|
+
else
|
262
|
+
m = MemoEntry.new(nil, @pos)
|
263
|
+
@memoizations[memo_key][@pos] = m
|
264
|
+
start_pos = @pos
|
265
|
+
|
266
|
+
ans = __send__ rule, *args
|
267
|
+
|
268
|
+
lr = m.left_rec
|
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
|
275
|
+
return grow_lr(rule, args, start_pos, m)
|
276
|
+
else
|
277
|
+
return ans
|
278
|
+
end
|
279
|
+
|
280
|
+
return ans
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
def apply(rule)
|
285
|
+
if m = @memoizations[rule][@pos]
|
286
|
+
@pos = m.pos
|
287
|
+
if !m.set
|
288
|
+
m.left_rec = true
|
289
|
+
return nil
|
290
|
+
end
|
291
|
+
|
292
|
+
@result = m.result
|
293
|
+
|
294
|
+
return m.ans
|
295
|
+
else
|
296
|
+
m = MemoEntry.new(nil, @pos)
|
297
|
+
@memoizations[rule][@pos] = m
|
298
|
+
start_pos = @pos
|
299
|
+
|
300
|
+
ans = __send__ rule
|
301
|
+
|
302
|
+
lr = m.left_rec
|
303
|
+
|
304
|
+
m.move! ans, @pos, @result
|
305
|
+
|
306
|
+
# Don't bother trying to grow the left recursion
|
307
|
+
# if it's failing straight away (thus there is no seed)
|
308
|
+
if ans and lr
|
309
|
+
return grow_lr(rule, nil, start_pos, m)
|
310
|
+
else
|
311
|
+
return ans
|
312
|
+
end
|
313
|
+
|
314
|
+
return ans
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
def grow_lr(rule, args, start_pos, m)
|
319
|
+
while true
|
320
|
+
@pos = start_pos
|
321
|
+
@result = m.result
|
322
|
+
|
323
|
+
if args
|
324
|
+
ans = __send__ rule, *args
|
325
|
+
else
|
326
|
+
ans = __send__ rule
|
327
|
+
end
|
328
|
+
return nil unless ans
|
329
|
+
|
330
|
+
break if @pos <= m.pos
|
331
|
+
|
332
|
+
m.move! ans, @pos, @result
|
333
|
+
end
|
334
|
+
|
335
|
+
@result = m.result
|
336
|
+
@pos = m.pos
|
337
|
+
return m.ans
|
338
|
+
end
|
339
|
+
|
340
|
+
class RuleInfo
|
341
|
+
def initialize(name, rendered)
|
342
|
+
@name = name
|
343
|
+
@rendered = rendered
|
344
|
+
end
|
345
|
+
|
346
|
+
attr_reader :name, :rendered
|
347
|
+
end
|
348
|
+
|
349
|
+
def self.rule_info(name, rendered)
|
350
|
+
RuleInfo.new(name, rendered)
|
351
|
+
end
|
352
|
+
|
353
|
+
|
354
|
+
# :startdoc:
|
355
|
+
|
356
|
+
|
357
|
+
attr_accessor :result
|
358
|
+
|
359
|
+
private
|
360
|
+
|
361
|
+
def strip_chars string, chars
|
362
|
+
string[chars, string.length - chars * 2]
|
363
|
+
end
|
364
|
+
|
365
|
+
|
366
|
+
# :stopdoc:
|
367
|
+
def setup_foreign_grammar; end
|
368
|
+
|
369
|
+
# id = < /[a-z][a-z_]*/i > { text }
|
370
|
+
def _id
|
371
|
+
|
372
|
+
_save = self.pos
|
373
|
+
while true # sequence
|
374
|
+
_text_start = self.pos
|
375
|
+
_tmp = scan(/\A(?i-mx:[a-z][a-z_]*)/)
|
376
|
+
if _tmp
|
377
|
+
text = get_text(_text_start)
|
378
|
+
end
|
379
|
+
unless _tmp
|
380
|
+
self.pos = _save
|
381
|
+
break
|
382
|
+
end
|
383
|
+
@result = begin; text ; end
|
384
|
+
_tmp = true
|
385
|
+
unless _tmp
|
386
|
+
self.pos = _save
|
387
|
+
end
|
388
|
+
break
|
389
|
+
end # end sequence
|
390
|
+
|
391
|
+
set_failed_rule :_id unless _tmp
|
392
|
+
return _tmp
|
393
|
+
end
|
394
|
+
|
395
|
+
# ids = (ids:i1 - "," - ids:i2 { i1 + i2 } | id:i { [i] })
|
396
|
+
def _ids
|
397
|
+
|
398
|
+
_save = self.pos
|
399
|
+
while true # choice
|
400
|
+
|
401
|
+
_save1 = self.pos
|
402
|
+
while true # sequence
|
403
|
+
_tmp = apply(:_ids)
|
404
|
+
i1 = @result
|
405
|
+
unless _tmp
|
406
|
+
self.pos = _save1
|
407
|
+
break
|
408
|
+
end
|
409
|
+
_tmp = apply(:__hyphen_)
|
410
|
+
unless _tmp
|
411
|
+
self.pos = _save1
|
412
|
+
break
|
413
|
+
end
|
414
|
+
_tmp = match_string(",")
|
415
|
+
unless _tmp
|
416
|
+
self.pos = _save1
|
417
|
+
break
|
418
|
+
end
|
419
|
+
_tmp = apply(:__hyphen_)
|
420
|
+
unless _tmp
|
421
|
+
self.pos = _save1
|
422
|
+
break
|
423
|
+
end
|
424
|
+
_tmp = apply(:_ids)
|
425
|
+
i2 = @result
|
426
|
+
unless _tmp
|
427
|
+
self.pos = _save1
|
428
|
+
break
|
429
|
+
end
|
430
|
+
@result = begin; i1 + i2 ; end
|
431
|
+
_tmp = true
|
432
|
+
unless _tmp
|
433
|
+
self.pos = _save1
|
434
|
+
end
|
435
|
+
break
|
436
|
+
end # end sequence
|
437
|
+
|
438
|
+
break if _tmp
|
439
|
+
self.pos = _save
|
440
|
+
|
441
|
+
_save2 = self.pos
|
442
|
+
while true # sequence
|
443
|
+
_tmp = apply(:_id)
|
444
|
+
i = @result
|
445
|
+
unless _tmp
|
446
|
+
self.pos = _save2
|
447
|
+
break
|
448
|
+
end
|
449
|
+
@result = begin; [i] ; end
|
450
|
+
_tmp = true
|
451
|
+
unless _tmp
|
452
|
+
self.pos = _save2
|
453
|
+
end
|
454
|
+
break
|
455
|
+
end # end sequence
|
456
|
+
|
457
|
+
break if _tmp
|
458
|
+
self.pos = _save
|
459
|
+
break
|
460
|
+
end # end choice
|
461
|
+
|
462
|
+
set_failed_rule :_ids unless _tmp
|
463
|
+
return _tmp
|
464
|
+
end
|
465
|
+
|
466
|
+
# item = (attribute | attributes | element)
|
467
|
+
def _item
|
468
|
+
|
469
|
+
_save = self.pos
|
470
|
+
while true # choice
|
471
|
+
_tmp = apply(:_attribute)
|
472
|
+
break if _tmp
|
473
|
+
self.pos = _save
|
474
|
+
_tmp = apply(:_attributes)
|
475
|
+
break if _tmp
|
476
|
+
self.pos = _save
|
477
|
+
_tmp = apply(:_element)
|
478
|
+
break if _tmp
|
479
|
+
self.pos = _save
|
480
|
+
break
|
481
|
+
end # end choice
|
482
|
+
|
483
|
+
set_failed_rule :_item unless _tmp
|
484
|
+
return _tmp
|
485
|
+
end
|
486
|
+
|
487
|
+
# items = (items:i1 items:i2 { i1 + i2 } | item:i { (i.is_a? Array) ? i : [i] })
|
488
|
+
def _items
|
489
|
+
|
490
|
+
_save = self.pos
|
491
|
+
while true # choice
|
492
|
+
|
493
|
+
_save1 = self.pos
|
494
|
+
while true # sequence
|
495
|
+
_tmp = apply(:_items)
|
496
|
+
i1 = @result
|
497
|
+
unless _tmp
|
498
|
+
self.pos = _save1
|
499
|
+
break
|
500
|
+
end
|
501
|
+
_tmp = apply(:_items)
|
502
|
+
i2 = @result
|
503
|
+
unless _tmp
|
504
|
+
self.pos = _save1
|
505
|
+
break
|
506
|
+
end
|
507
|
+
@result = begin; i1 + i2 ; end
|
508
|
+
_tmp = true
|
509
|
+
unless _tmp
|
510
|
+
self.pos = _save1
|
511
|
+
end
|
512
|
+
break
|
513
|
+
end # end sequence
|
514
|
+
|
515
|
+
break if _tmp
|
516
|
+
self.pos = _save
|
517
|
+
|
518
|
+
_save2 = self.pos
|
519
|
+
while true # sequence
|
520
|
+
_tmp = apply(:_item)
|
521
|
+
i = @result
|
522
|
+
unless _tmp
|
523
|
+
self.pos = _save2
|
524
|
+
break
|
525
|
+
end
|
526
|
+
@result = begin; (i.is_a? Array) ? i : [i] ; end
|
527
|
+
_tmp = true
|
528
|
+
unless _tmp
|
529
|
+
self.pos = _save2
|
530
|
+
end
|
531
|
+
break
|
532
|
+
end # end sequence
|
533
|
+
|
534
|
+
break if _tmp
|
535
|
+
self.pos = _save
|
536
|
+
break
|
537
|
+
end # end choice
|
538
|
+
|
539
|
+
set_failed_rule :_items unless _tmp
|
540
|
+
return _tmp
|
541
|
+
end
|
542
|
+
|
543
|
+
# contents = items?:i { i.to_a }
|
544
|
+
def _contents
|
545
|
+
|
546
|
+
_save = self.pos
|
547
|
+
while true # sequence
|
548
|
+
_save1 = self.pos
|
549
|
+
_tmp = apply(:_items)
|
550
|
+
@result = nil unless _tmp
|
551
|
+
unless _tmp
|
552
|
+
_tmp = true
|
553
|
+
self.pos = _save1
|
554
|
+
end
|
555
|
+
i = @result
|
556
|
+
unless _tmp
|
557
|
+
self.pos = _save
|
558
|
+
break
|
559
|
+
end
|
560
|
+
@result = begin; i.to_a ; end
|
561
|
+
_tmp = true
|
562
|
+
unless _tmp
|
563
|
+
self.pos = _save
|
564
|
+
end
|
565
|
+
break
|
566
|
+
end # end sequence
|
567
|
+
|
568
|
+
set_failed_rule :_contents unless _tmp
|
569
|
+
return _tmp
|
570
|
+
end
|
571
|
+
|
572
|
+
# attr = - id:n - "=" - val:v - eol { Attribute.new n, *v }
|
573
|
+
def _attr
|
574
|
+
|
575
|
+
_save = self.pos
|
576
|
+
while true # sequence
|
577
|
+
_tmp = apply(:__hyphen_)
|
578
|
+
unless _tmp
|
579
|
+
self.pos = _save
|
580
|
+
break
|
581
|
+
end
|
582
|
+
_tmp = apply(:_id)
|
583
|
+
n = @result
|
584
|
+
unless _tmp
|
585
|
+
self.pos = _save
|
586
|
+
break
|
587
|
+
end
|
588
|
+
_tmp = apply(:__hyphen_)
|
589
|
+
unless _tmp
|
590
|
+
self.pos = _save
|
591
|
+
break
|
592
|
+
end
|
593
|
+
_tmp = match_string("=")
|
594
|
+
unless _tmp
|
595
|
+
self.pos = _save
|
596
|
+
break
|
597
|
+
end
|
598
|
+
_tmp = apply(:__hyphen_)
|
599
|
+
unless _tmp
|
600
|
+
self.pos = _save
|
601
|
+
break
|
602
|
+
end
|
603
|
+
_tmp = apply(:_val)
|
604
|
+
v = @result
|
605
|
+
unless _tmp
|
606
|
+
self.pos = _save
|
607
|
+
break
|
608
|
+
end
|
609
|
+
_tmp = apply(:__hyphen_)
|
610
|
+
unless _tmp
|
611
|
+
self.pos = _save
|
612
|
+
break
|
613
|
+
end
|
614
|
+
_tmp = apply(:_eol)
|
615
|
+
unless _tmp
|
616
|
+
self.pos = _save
|
617
|
+
break
|
618
|
+
end
|
619
|
+
@result = begin; Attribute.new n, *v ; end
|
620
|
+
_tmp = true
|
621
|
+
unless _tmp
|
622
|
+
self.pos = _save
|
623
|
+
end
|
624
|
+
break
|
625
|
+
end # end sequence
|
626
|
+
|
627
|
+
set_failed_rule :_attr unless _tmp
|
628
|
+
return _tmp
|
629
|
+
end
|
630
|
+
|
631
|
+
# multiple_attrs = - ids:n - "=" - vals:v - eol { n.reduce(Array.new) do |attrs, name| value = v.shift or [nil] attrs << Attribute.new(name, *value) end }
|
632
|
+
def _multiple_attrs
|
633
|
+
|
634
|
+
_save = self.pos
|
635
|
+
while true # sequence
|
636
|
+
_tmp = apply(:__hyphen_)
|
637
|
+
unless _tmp
|
638
|
+
self.pos = _save
|
639
|
+
break
|
640
|
+
end
|
641
|
+
_tmp = apply(:_ids)
|
642
|
+
n = @result
|
643
|
+
unless _tmp
|
644
|
+
self.pos = _save
|
645
|
+
break
|
646
|
+
end
|
647
|
+
_tmp = apply(:__hyphen_)
|
648
|
+
unless _tmp
|
649
|
+
self.pos = _save
|
650
|
+
break
|
651
|
+
end
|
652
|
+
_tmp = match_string("=")
|
653
|
+
unless _tmp
|
654
|
+
self.pos = _save
|
655
|
+
break
|
656
|
+
end
|
657
|
+
_tmp = apply(:__hyphen_)
|
658
|
+
unless _tmp
|
659
|
+
self.pos = _save
|
660
|
+
break
|
661
|
+
end
|
662
|
+
_tmp = apply(:_vals)
|
663
|
+
v = @result
|
664
|
+
unless _tmp
|
665
|
+
self.pos = _save
|
666
|
+
break
|
667
|
+
end
|
668
|
+
_tmp = apply(:__hyphen_)
|
669
|
+
unless _tmp
|
670
|
+
self.pos = _save
|
671
|
+
break
|
672
|
+
end
|
673
|
+
_tmp = apply(:_eol)
|
674
|
+
unless _tmp
|
675
|
+
self.pos = _save
|
676
|
+
break
|
677
|
+
end
|
678
|
+
@result = begin; n.reduce(Array.new) do |attrs, name|
|
679
|
+
value = v.shift or [nil]
|
680
|
+
attrs << Attribute.new(name, *value)
|
681
|
+
end ; end
|
682
|
+
_tmp = true
|
683
|
+
unless _tmp
|
684
|
+
self.pos = _save
|
685
|
+
end
|
686
|
+
break
|
687
|
+
end # end sequence
|
688
|
+
|
689
|
+
set_failed_rule :_multiple_attrs unless _tmp
|
690
|
+
return _tmp
|
691
|
+
end
|
692
|
+
|
693
|
+
# attribute = blk_lines attr:a blk_lines { a }
|
694
|
+
def _attribute
|
695
|
+
|
696
|
+
_save = self.pos
|
697
|
+
while true # sequence
|
698
|
+
_tmp = apply(:_blk_lines)
|
699
|
+
unless _tmp
|
700
|
+
self.pos = _save
|
701
|
+
break
|
702
|
+
end
|
703
|
+
_tmp = apply(:_attr)
|
704
|
+
a = @result
|
705
|
+
unless _tmp
|
706
|
+
self.pos = _save
|
707
|
+
break
|
708
|
+
end
|
709
|
+
_tmp = apply(:_blk_lines)
|
710
|
+
unless _tmp
|
711
|
+
self.pos = _save
|
712
|
+
break
|
713
|
+
end
|
714
|
+
@result = begin; a ; end
|
715
|
+
_tmp = true
|
716
|
+
unless _tmp
|
717
|
+
self.pos = _save
|
718
|
+
end
|
719
|
+
break
|
720
|
+
end # end sequence
|
721
|
+
|
722
|
+
set_failed_rule :_attribute unless _tmp
|
723
|
+
return _tmp
|
724
|
+
end
|
725
|
+
|
726
|
+
# attributes = blk_lines multiple_attrs:a blk_lines { a }
|
727
|
+
def _attributes
|
728
|
+
|
729
|
+
_save = self.pos
|
730
|
+
while true # sequence
|
731
|
+
_tmp = apply(:_blk_lines)
|
732
|
+
unless _tmp
|
733
|
+
self.pos = _save
|
734
|
+
break
|
735
|
+
end
|
736
|
+
_tmp = apply(:_multiple_attrs)
|
737
|
+
a = @result
|
738
|
+
unless _tmp
|
739
|
+
self.pos = _save
|
740
|
+
break
|
741
|
+
end
|
742
|
+
_tmp = apply(:_blk_lines)
|
743
|
+
unless _tmp
|
744
|
+
self.pos = _save
|
745
|
+
break
|
746
|
+
end
|
747
|
+
@result = begin; a ; end
|
748
|
+
_tmp = true
|
749
|
+
unless _tmp
|
750
|
+
self.pos = _save
|
751
|
+
end
|
752
|
+
break
|
753
|
+
end # end sequence
|
754
|
+
|
755
|
+
set_failed_rule :_attributes unless _tmp
|
756
|
+
return _tmp
|
757
|
+
end
|
758
|
+
|
759
|
+
# code = < /<<.*?>>/m > { [strip_chars(text, 2), {:code => true}] }
|
760
|
+
def _code
|
761
|
+
|
762
|
+
_save = self.pos
|
763
|
+
while true # sequence
|
764
|
+
_text_start = self.pos
|
765
|
+
_tmp = scan(/\A(?m-ix:<<.*?>>)/)
|
766
|
+
if _tmp
|
767
|
+
text = get_text(_text_start)
|
768
|
+
end
|
769
|
+
unless _tmp
|
770
|
+
self.pos = _save
|
771
|
+
break
|
772
|
+
end
|
773
|
+
@result = begin; [strip_chars(text, 2), {:code => true}] ; end
|
774
|
+
_tmp = true
|
775
|
+
unless _tmp
|
776
|
+
self.pos = _save
|
777
|
+
end
|
778
|
+
break
|
779
|
+
end # end sequence
|
780
|
+
|
781
|
+
set_failed_rule :_code unless _tmp
|
782
|
+
return _tmp
|
783
|
+
end
|
784
|
+
|
785
|
+
# in_brackets = < /\(.*?\)/m > { [strip_chars(text, 1)] }
|
786
|
+
def _in_brackets
|
787
|
+
|
788
|
+
_save = self.pos
|
789
|
+
while true # sequence
|
790
|
+
_text_start = self.pos
|
791
|
+
_tmp = scan(/\A(?m-ix:\(.*?\))/)
|
792
|
+
if _tmp
|
793
|
+
text = get_text(_text_start)
|
794
|
+
end
|
795
|
+
unless _tmp
|
796
|
+
self.pos = _save
|
797
|
+
break
|
798
|
+
end
|
799
|
+
@result = begin; [strip_chars(text, 1)] ; end
|
800
|
+
_tmp = true
|
801
|
+
unless _tmp
|
802
|
+
self.pos = _save
|
803
|
+
end
|
804
|
+
break
|
805
|
+
end # end sequence
|
806
|
+
|
807
|
+
set_failed_rule :_in_brackets unless _tmp
|
808
|
+
return _tmp
|
809
|
+
end
|
810
|
+
|
811
|
+
# in_quotes = < /".*?"/m > { [strip_chars(text, 1)] }
|
812
|
+
def _in_quotes
|
813
|
+
|
814
|
+
_save = self.pos
|
815
|
+
while true # sequence
|
816
|
+
_text_start = self.pos
|
817
|
+
_tmp = scan(/\A(?m-ix:".*?")/)
|
818
|
+
if _tmp
|
819
|
+
text = get_text(_text_start)
|
820
|
+
end
|
821
|
+
unless _tmp
|
822
|
+
self.pos = _save
|
823
|
+
break
|
824
|
+
end
|
825
|
+
@result = begin; [strip_chars(text, 1)] ; end
|
826
|
+
_tmp = true
|
827
|
+
unless _tmp
|
828
|
+
self.pos = _save
|
829
|
+
end
|
830
|
+
break
|
831
|
+
end # end sequence
|
832
|
+
|
833
|
+
set_failed_rule :_in_quotes unless _tmp
|
834
|
+
return _tmp
|
835
|
+
end
|
836
|
+
|
837
|
+
# raw = < /.*/ > { [text.strip] }
|
838
|
+
def _raw
|
839
|
+
|
840
|
+
_save = self.pos
|
841
|
+
while true # sequence
|
842
|
+
_text_start = self.pos
|
843
|
+
_tmp = scan(/\A(?-mix:.*)/)
|
844
|
+
if _tmp
|
845
|
+
text = get_text(_text_start)
|
846
|
+
end
|
847
|
+
unless _tmp
|
848
|
+
self.pos = _save
|
849
|
+
break
|
850
|
+
end
|
851
|
+
@result = begin; [text.strip] ; end
|
852
|
+
_tmp = true
|
853
|
+
unless _tmp
|
854
|
+
self.pos = _save
|
855
|
+
end
|
856
|
+
break
|
857
|
+
end # end sequence
|
858
|
+
|
859
|
+
set_failed_rule :_raw unless _tmp
|
860
|
+
return _tmp
|
861
|
+
end
|
862
|
+
|
863
|
+
# escaped = (in_quotes:s1 escaped:s2 { s1[0] += '"' + s2[0] ; s1 } | in_quotes)
|
864
|
+
def _escaped
|
865
|
+
|
866
|
+
_save = self.pos
|
867
|
+
while true # choice
|
868
|
+
|
869
|
+
_save1 = self.pos
|
870
|
+
while true # sequence
|
871
|
+
_tmp = apply(:_in_quotes)
|
872
|
+
s1 = @result
|
873
|
+
unless _tmp
|
874
|
+
self.pos = _save1
|
875
|
+
break
|
876
|
+
end
|
877
|
+
_tmp = apply(:_escaped)
|
878
|
+
s2 = @result
|
879
|
+
unless _tmp
|
880
|
+
self.pos = _save1
|
881
|
+
break
|
882
|
+
end
|
883
|
+
@result = begin; s1[0] += '"' + s2[0] ; s1 ; end
|
884
|
+
_tmp = true
|
885
|
+
unless _tmp
|
886
|
+
self.pos = _save1
|
887
|
+
end
|
888
|
+
break
|
889
|
+
end # end sequence
|
890
|
+
|
891
|
+
break if _tmp
|
892
|
+
self.pos = _save
|
893
|
+
_tmp = apply(:_in_quotes)
|
894
|
+
break if _tmp
|
895
|
+
self.pos = _save
|
896
|
+
break
|
897
|
+
end # end choice
|
898
|
+
|
899
|
+
set_failed_rule :_escaped unless _tmp
|
900
|
+
return _tmp
|
901
|
+
end
|
902
|
+
|
903
|
+
# i18n = "_" - (in_brackets | in_quotes):s { [s[0], {:translatable => true}] }
|
904
|
+
def _i18n
|
905
|
+
|
906
|
+
_save = self.pos
|
907
|
+
while true # sequence
|
908
|
+
_tmp = match_string("_")
|
909
|
+
unless _tmp
|
910
|
+
self.pos = _save
|
911
|
+
break
|
912
|
+
end
|
913
|
+
_tmp = apply(:__hyphen_)
|
914
|
+
unless _tmp
|
915
|
+
self.pos = _save
|
916
|
+
break
|
917
|
+
end
|
918
|
+
|
919
|
+
_save1 = self.pos
|
920
|
+
while true # choice
|
921
|
+
_tmp = apply(:_in_brackets)
|
922
|
+
break if _tmp
|
923
|
+
self.pos = _save1
|
924
|
+
_tmp = apply(:_in_quotes)
|
925
|
+
break if _tmp
|
926
|
+
self.pos = _save1
|
927
|
+
break
|
928
|
+
end # end choice
|
929
|
+
|
930
|
+
s = @result
|
931
|
+
unless _tmp
|
932
|
+
self.pos = _save
|
933
|
+
break
|
934
|
+
end
|
935
|
+
@result = begin; [s[0], {:translatable => true}] ; end
|
936
|
+
_tmp = true
|
937
|
+
unless _tmp
|
938
|
+
self.pos = _save
|
939
|
+
end
|
940
|
+
break
|
941
|
+
end # end sequence
|
942
|
+
|
943
|
+
set_failed_rule :_i18n unless _tmp
|
944
|
+
return _tmp
|
945
|
+
end
|
946
|
+
|
947
|
+
# val = (val:v1 - "+" sp_lf val:v2 { v1[0] += v2[0] ; v1 } | escaped | i18n | code | in_brackets | in_quotes | raw)
|
948
|
+
def _val
|
949
|
+
|
950
|
+
_save = self.pos
|
951
|
+
while true # choice
|
952
|
+
|
953
|
+
_save1 = self.pos
|
954
|
+
while true # sequence
|
955
|
+
_tmp = apply(:_val)
|
956
|
+
v1 = @result
|
957
|
+
unless _tmp
|
958
|
+
self.pos = _save1
|
959
|
+
break
|
960
|
+
end
|
961
|
+
_tmp = apply(:__hyphen_)
|
962
|
+
unless _tmp
|
963
|
+
self.pos = _save1
|
964
|
+
break
|
965
|
+
end
|
966
|
+
_tmp = match_string("+")
|
967
|
+
unless _tmp
|
968
|
+
self.pos = _save1
|
969
|
+
break
|
970
|
+
end
|
971
|
+
_tmp = apply(:_sp_lf)
|
972
|
+
unless _tmp
|
973
|
+
self.pos = _save1
|
974
|
+
break
|
975
|
+
end
|
976
|
+
_tmp = apply(:_val)
|
977
|
+
v2 = @result
|
978
|
+
unless _tmp
|
979
|
+
self.pos = _save1
|
980
|
+
break
|
981
|
+
end
|
982
|
+
@result = begin; v1[0] += v2[0] ; v1 ; end
|
983
|
+
_tmp = true
|
984
|
+
unless _tmp
|
985
|
+
self.pos = _save1
|
986
|
+
end
|
987
|
+
break
|
988
|
+
end # end sequence
|
989
|
+
|
990
|
+
break if _tmp
|
991
|
+
self.pos = _save
|
992
|
+
_tmp = apply(:_escaped)
|
993
|
+
break if _tmp
|
994
|
+
self.pos = _save
|
995
|
+
_tmp = apply(:_i18n)
|
996
|
+
break if _tmp
|
997
|
+
self.pos = _save
|
998
|
+
_tmp = apply(:_code)
|
999
|
+
break if _tmp
|
1000
|
+
self.pos = _save
|
1001
|
+
_tmp = apply(:_in_brackets)
|
1002
|
+
break if _tmp
|
1003
|
+
self.pos = _save
|
1004
|
+
_tmp = apply(:_in_quotes)
|
1005
|
+
break if _tmp
|
1006
|
+
self.pos = _save
|
1007
|
+
_tmp = apply(:_raw)
|
1008
|
+
break if _tmp
|
1009
|
+
self.pos = _save
|
1010
|
+
break
|
1011
|
+
end # end choice
|
1012
|
+
|
1013
|
+
set_failed_rule :_val unless _tmp
|
1014
|
+
return _tmp
|
1015
|
+
end
|
1016
|
+
|
1017
|
+
# vals = (vals:v1 - "," - vals:v2 { v1 + v2 } | val:v { [v] })
|
1018
|
+
def _vals
|
1019
|
+
|
1020
|
+
_save = self.pos
|
1021
|
+
while true # choice
|
1022
|
+
|
1023
|
+
_save1 = self.pos
|
1024
|
+
while true # sequence
|
1025
|
+
_tmp = apply(:_vals)
|
1026
|
+
v1 = @result
|
1027
|
+
unless _tmp
|
1028
|
+
self.pos = _save1
|
1029
|
+
break
|
1030
|
+
end
|
1031
|
+
_tmp = apply(:__hyphen_)
|
1032
|
+
unless _tmp
|
1033
|
+
self.pos = _save1
|
1034
|
+
break
|
1035
|
+
end
|
1036
|
+
_tmp = match_string(",")
|
1037
|
+
unless _tmp
|
1038
|
+
self.pos = _save1
|
1039
|
+
break
|
1040
|
+
end
|
1041
|
+
_tmp = apply(:__hyphen_)
|
1042
|
+
unless _tmp
|
1043
|
+
self.pos = _save1
|
1044
|
+
break
|
1045
|
+
end
|
1046
|
+
_tmp = apply(:_vals)
|
1047
|
+
v2 = @result
|
1048
|
+
unless _tmp
|
1049
|
+
self.pos = _save1
|
1050
|
+
break
|
1051
|
+
end
|
1052
|
+
@result = begin; v1 + v2 ; end
|
1053
|
+
_tmp = true
|
1054
|
+
unless _tmp
|
1055
|
+
self.pos = _save1
|
1056
|
+
end
|
1057
|
+
break
|
1058
|
+
end # end sequence
|
1059
|
+
|
1060
|
+
break if _tmp
|
1061
|
+
self.pos = _save
|
1062
|
+
|
1063
|
+
_save2 = self.pos
|
1064
|
+
while true # sequence
|
1065
|
+
_tmp = apply(:_val)
|
1066
|
+
v = @result
|
1067
|
+
unless _tmp
|
1068
|
+
self.pos = _save2
|
1069
|
+
break
|
1070
|
+
end
|
1071
|
+
@result = begin; [v] ; end
|
1072
|
+
_tmp = true
|
1073
|
+
unless _tmp
|
1074
|
+
self.pos = _save2
|
1075
|
+
end
|
1076
|
+
break
|
1077
|
+
end # end sequence
|
1078
|
+
|
1079
|
+
break if _tmp
|
1080
|
+
self.pos = _save
|
1081
|
+
break
|
1082
|
+
end # end choice
|
1083
|
+
|
1084
|
+
set_failed_rule :_vals unless _tmp
|
1085
|
+
return _tmp
|
1086
|
+
end
|
1087
|
+
|
1088
|
+
# amendment = - amending_tag:n - eol contents:c - closing_tag(n) - eol { Element.new(n, :amendment => true).push *c }
|
1089
|
+
def _amendment
|
1090
|
+
|
1091
|
+
_save = self.pos
|
1092
|
+
while true # sequence
|
1093
|
+
_tmp = apply(:__hyphen_)
|
1094
|
+
unless _tmp
|
1095
|
+
self.pos = _save
|
1096
|
+
break
|
1097
|
+
end
|
1098
|
+
_tmp = apply(:_amending_tag)
|
1099
|
+
n = @result
|
1100
|
+
unless _tmp
|
1101
|
+
self.pos = _save
|
1102
|
+
break
|
1103
|
+
end
|
1104
|
+
_tmp = apply(:__hyphen_)
|
1105
|
+
unless _tmp
|
1106
|
+
self.pos = _save
|
1107
|
+
break
|
1108
|
+
end
|
1109
|
+
_tmp = apply(:_eol)
|
1110
|
+
unless _tmp
|
1111
|
+
self.pos = _save
|
1112
|
+
break
|
1113
|
+
end
|
1114
|
+
_tmp = apply(:_contents)
|
1115
|
+
c = @result
|
1116
|
+
unless _tmp
|
1117
|
+
self.pos = _save
|
1118
|
+
break
|
1119
|
+
end
|
1120
|
+
_tmp = apply(:__hyphen_)
|
1121
|
+
unless _tmp
|
1122
|
+
self.pos = _save
|
1123
|
+
break
|
1124
|
+
end
|
1125
|
+
_tmp = apply_with_args(:_closing_tag, n)
|
1126
|
+
unless _tmp
|
1127
|
+
self.pos = _save
|
1128
|
+
break
|
1129
|
+
end
|
1130
|
+
_tmp = apply(:__hyphen_)
|
1131
|
+
unless _tmp
|
1132
|
+
self.pos = _save
|
1133
|
+
break
|
1134
|
+
end
|
1135
|
+
_tmp = apply(:_eol)
|
1136
|
+
unless _tmp
|
1137
|
+
self.pos = _save
|
1138
|
+
break
|
1139
|
+
end
|
1140
|
+
@result = begin; Element.new(n, :amendment => true).push *c ; end
|
1141
|
+
_tmp = true
|
1142
|
+
unless _tmp
|
1143
|
+
self.pos = _save
|
1144
|
+
end
|
1145
|
+
break
|
1146
|
+
end # end sequence
|
1147
|
+
|
1148
|
+
set_failed_rule :_amendment unless _tmp
|
1149
|
+
return _tmp
|
1150
|
+
end
|
1151
|
+
|
1152
|
+
# regular = - opening_tag:n - eol contents:c - closing_tag(n) - eol { Element.new(n).push *c }
|
1153
|
+
def _regular
|
1154
|
+
|
1155
|
+
_save = self.pos
|
1156
|
+
while true # sequence
|
1157
|
+
_tmp = apply(:__hyphen_)
|
1158
|
+
unless _tmp
|
1159
|
+
self.pos = _save
|
1160
|
+
break
|
1161
|
+
end
|
1162
|
+
_tmp = apply(:_opening_tag)
|
1163
|
+
n = @result
|
1164
|
+
unless _tmp
|
1165
|
+
self.pos = _save
|
1166
|
+
break
|
1167
|
+
end
|
1168
|
+
_tmp = apply(:__hyphen_)
|
1169
|
+
unless _tmp
|
1170
|
+
self.pos = _save
|
1171
|
+
break
|
1172
|
+
end
|
1173
|
+
_tmp = apply(:_eol)
|
1174
|
+
unless _tmp
|
1175
|
+
self.pos = _save
|
1176
|
+
break
|
1177
|
+
end
|
1178
|
+
_tmp = apply(:_contents)
|
1179
|
+
c = @result
|
1180
|
+
unless _tmp
|
1181
|
+
self.pos = _save
|
1182
|
+
break
|
1183
|
+
end
|
1184
|
+
_tmp = apply(:__hyphen_)
|
1185
|
+
unless _tmp
|
1186
|
+
self.pos = _save
|
1187
|
+
break
|
1188
|
+
end
|
1189
|
+
_tmp = apply_with_args(:_closing_tag, n)
|
1190
|
+
unless _tmp
|
1191
|
+
self.pos = _save
|
1192
|
+
break
|
1193
|
+
end
|
1194
|
+
_tmp = apply(:__hyphen_)
|
1195
|
+
unless _tmp
|
1196
|
+
self.pos = _save
|
1197
|
+
break
|
1198
|
+
end
|
1199
|
+
_tmp = apply(:_eol)
|
1200
|
+
unless _tmp
|
1201
|
+
self.pos = _save
|
1202
|
+
break
|
1203
|
+
end
|
1204
|
+
@result = begin; Element.new(n).push *c ; end
|
1205
|
+
_tmp = true
|
1206
|
+
unless _tmp
|
1207
|
+
self.pos = _save
|
1208
|
+
end
|
1209
|
+
break
|
1210
|
+
end # end sequence
|
1211
|
+
|
1212
|
+
set_failed_rule :_regular unless _tmp
|
1213
|
+
return _tmp
|
1214
|
+
end
|
1215
|
+
|
1216
|
+
# element = blk_lines (amendment | regular):e blk_lines { e }
|
1217
|
+
def _element
|
1218
|
+
|
1219
|
+
_save = self.pos
|
1220
|
+
while true # sequence
|
1221
|
+
_tmp = apply(:_blk_lines)
|
1222
|
+
unless _tmp
|
1223
|
+
self.pos = _save
|
1224
|
+
break
|
1225
|
+
end
|
1226
|
+
|
1227
|
+
_save1 = self.pos
|
1228
|
+
while true # choice
|
1229
|
+
_tmp = apply(:_amendment)
|
1230
|
+
break if _tmp
|
1231
|
+
self.pos = _save1
|
1232
|
+
_tmp = apply(:_regular)
|
1233
|
+
break if _tmp
|
1234
|
+
self.pos = _save1
|
1235
|
+
break
|
1236
|
+
end # end choice
|
1237
|
+
|
1238
|
+
e = @result
|
1239
|
+
unless _tmp
|
1240
|
+
self.pos = _save
|
1241
|
+
break
|
1242
|
+
end
|
1243
|
+
_tmp = apply(:_blk_lines)
|
1244
|
+
unless _tmp
|
1245
|
+
self.pos = _save
|
1246
|
+
break
|
1247
|
+
end
|
1248
|
+
@result = begin; e ; end
|
1249
|
+
_tmp = true
|
1250
|
+
unless _tmp
|
1251
|
+
self.pos = _save
|
1252
|
+
end
|
1253
|
+
break
|
1254
|
+
end # end sequence
|
1255
|
+
|
1256
|
+
set_failed_rule :_element unless _tmp
|
1257
|
+
return _tmp
|
1258
|
+
end
|
1259
|
+
|
1260
|
+
# amending_tag = "[+" id:n "]" { n }
|
1261
|
+
def _amending_tag
|
1262
|
+
|
1263
|
+
_save = self.pos
|
1264
|
+
while true # sequence
|
1265
|
+
_tmp = match_string("[+")
|
1266
|
+
unless _tmp
|
1267
|
+
self.pos = _save
|
1268
|
+
break
|
1269
|
+
end
|
1270
|
+
_tmp = apply(:_id)
|
1271
|
+
n = @result
|
1272
|
+
unless _tmp
|
1273
|
+
self.pos = _save
|
1274
|
+
break
|
1275
|
+
end
|
1276
|
+
_tmp = match_string("]")
|
1277
|
+
unless _tmp
|
1278
|
+
self.pos = _save
|
1279
|
+
break
|
1280
|
+
end
|
1281
|
+
@result = begin; n ; end
|
1282
|
+
_tmp = true
|
1283
|
+
unless _tmp
|
1284
|
+
self.pos = _save
|
1285
|
+
end
|
1286
|
+
break
|
1287
|
+
end # end sequence
|
1288
|
+
|
1289
|
+
set_failed_rule :_amending_tag unless _tmp
|
1290
|
+
return _tmp
|
1291
|
+
end
|
1292
|
+
|
1293
|
+
# closing_tag = "[/" id:n "]" &{ n == m }
|
1294
|
+
def _closing_tag(m)
|
1295
|
+
|
1296
|
+
_save = self.pos
|
1297
|
+
while true # sequence
|
1298
|
+
_tmp = match_string("[/")
|
1299
|
+
unless _tmp
|
1300
|
+
self.pos = _save
|
1301
|
+
break
|
1302
|
+
end
|
1303
|
+
_tmp = apply(:_id)
|
1304
|
+
n = @result
|
1305
|
+
unless _tmp
|
1306
|
+
self.pos = _save
|
1307
|
+
break
|
1308
|
+
end
|
1309
|
+
_tmp = match_string("]")
|
1310
|
+
unless _tmp
|
1311
|
+
self.pos = _save
|
1312
|
+
break
|
1313
|
+
end
|
1314
|
+
_save1 = self.pos
|
1315
|
+
_tmp = begin; n == m ; end
|
1316
|
+
self.pos = _save1
|
1317
|
+
unless _tmp
|
1318
|
+
self.pos = _save
|
1319
|
+
end
|
1320
|
+
break
|
1321
|
+
end # end sequence
|
1322
|
+
|
1323
|
+
set_failed_rule :_closing_tag unless _tmp
|
1324
|
+
return _tmp
|
1325
|
+
end
|
1326
|
+
|
1327
|
+
# opening_tag = "[" id:n "]" { n }
|
1328
|
+
def _opening_tag
|
1329
|
+
|
1330
|
+
_save = self.pos
|
1331
|
+
while true # sequence
|
1332
|
+
_tmp = match_string("[")
|
1333
|
+
unless _tmp
|
1334
|
+
self.pos = _save
|
1335
|
+
break
|
1336
|
+
end
|
1337
|
+
_tmp = apply(:_id)
|
1338
|
+
n = @result
|
1339
|
+
unless _tmp
|
1340
|
+
self.pos = _save
|
1341
|
+
break
|
1342
|
+
end
|
1343
|
+
_tmp = match_string("]")
|
1344
|
+
unless _tmp
|
1345
|
+
self.pos = _save
|
1346
|
+
break
|
1347
|
+
end
|
1348
|
+
@result = begin; n ; end
|
1349
|
+
_tmp = true
|
1350
|
+
unless _tmp
|
1351
|
+
self.pos = _save
|
1352
|
+
end
|
1353
|
+
break
|
1354
|
+
end # end sequence
|
1355
|
+
|
1356
|
+
set_failed_rule :_opening_tag unless _tmp
|
1357
|
+
return _tmp
|
1358
|
+
end
|
1359
|
+
|
1360
|
+
# eof = !.
|
1361
|
+
def _eof
|
1362
|
+
_save = self.pos
|
1363
|
+
_tmp = get_byte
|
1364
|
+
_tmp = _tmp ? nil : true
|
1365
|
+
self.pos = _save
|
1366
|
+
set_failed_rule :_eof unless _tmp
|
1367
|
+
return _tmp
|
1368
|
+
end
|
1369
|
+
|
1370
|
+
# eol = ("
|
1371
|
+
def _eol
|
1372
|
+
|
1373
|
+
_save = self.pos
|
1374
|
+
while true # choice
|
1375
|
+
_tmp = match_string("\r\n")
|
1376
|
+
break if _tmp
|
1377
|
+
self.pos = _save
|
1378
|
+
_tmp = match_string("\n")
|
1379
|
+
break if _tmp
|
1380
|
+
self.pos = _save
|
1381
|
+
break
|
1382
|
+
end # end choice
|
1383
|
+
|
1384
|
+
set_failed_rule :_eol unless _tmp
|
1385
|
+
return _tmp
|
1386
|
+
end
|
1387
|
+
|
1388
|
+
# sp = (" " | "\t")
|
1389
|
+
def _sp
|
1390
|
+
|
1391
|
+
_save = self.pos
|
1392
|
+
while true # choice
|
1393
|
+
_tmp = match_string(" ")
|
1394
|
+
break if _tmp
|
1395
|
+
self.pos = _save
|
1396
|
+
_tmp = match_string("\t")
|
1397
|
+
break if _tmp
|
1398
|
+
self.pos = _save
|
1399
|
+
break
|
1400
|
+
end # end choice
|
1401
|
+
|
1402
|
+
set_failed_rule :_sp unless _tmp
|
1403
|
+
return _tmp
|
1404
|
+
end
|
1405
|
+
|
1406
|
+
# - = sp*
|
1407
|
+
def __hyphen_
|
1408
|
+
while true
|
1409
|
+
_tmp = apply(:_sp)
|
1410
|
+
break unless _tmp
|
1411
|
+
end
|
1412
|
+
_tmp = true
|
1413
|
+
set_failed_rule :__hyphen_ unless _tmp
|
1414
|
+
return _tmp
|
1415
|
+
end
|
1416
|
+
|
1417
|
+
# sp_lf = (sp | eol)*
|
1418
|
+
def _sp_lf
|
1419
|
+
while true
|
1420
|
+
|
1421
|
+
_save1 = self.pos
|
1422
|
+
while true # choice
|
1423
|
+
_tmp = apply(:_sp)
|
1424
|
+
break if _tmp
|
1425
|
+
self.pos = _save1
|
1426
|
+
_tmp = apply(:_eol)
|
1427
|
+
break if _tmp
|
1428
|
+
self.pos = _save1
|
1429
|
+
break
|
1430
|
+
end # end choice
|
1431
|
+
|
1432
|
+
break unless _tmp
|
1433
|
+
end
|
1434
|
+
_tmp = true
|
1435
|
+
set_failed_rule :_sp_lf unless _tmp
|
1436
|
+
return _tmp
|
1437
|
+
end
|
1438
|
+
|
1439
|
+
# blk_lines = (- eol)*
|
1440
|
+
def _blk_lines
|
1441
|
+
while true
|
1442
|
+
|
1443
|
+
_save1 = self.pos
|
1444
|
+
while true # sequence
|
1445
|
+
_tmp = apply(:__hyphen_)
|
1446
|
+
unless _tmp
|
1447
|
+
self.pos = _save1
|
1448
|
+
break
|
1449
|
+
end
|
1450
|
+
_tmp = apply(:_eol)
|
1451
|
+
unless _tmp
|
1452
|
+
self.pos = _save1
|
1453
|
+
end
|
1454
|
+
break
|
1455
|
+
end # end sequence
|
1456
|
+
|
1457
|
+
break unless _tmp
|
1458
|
+
end
|
1459
|
+
_tmp = true
|
1460
|
+
set_failed_rule :_blk_lines unless _tmp
|
1461
|
+
return _tmp
|
1462
|
+
end
|
1463
|
+
|
1464
|
+
# root = contents:c { Root.new.push *c }
|
1465
|
+
def _root
|
1466
|
+
|
1467
|
+
_save = self.pos
|
1468
|
+
while true # sequence
|
1469
|
+
_tmp = apply(:_contents)
|
1470
|
+
c = @result
|
1471
|
+
unless _tmp
|
1472
|
+
self.pos = _save
|
1473
|
+
break
|
1474
|
+
end
|
1475
|
+
@result = begin; Root.new.push *c ; end
|
1476
|
+
_tmp = true
|
1477
|
+
unless _tmp
|
1478
|
+
self.pos = _save
|
1479
|
+
end
|
1480
|
+
break
|
1481
|
+
end # end sequence
|
1482
|
+
|
1483
|
+
set_failed_rule :_root unless _tmp
|
1484
|
+
return _tmp
|
1485
|
+
end
|
1486
|
+
|
1487
|
+
Rules = {}
|
1488
|
+
Rules[:_id] = rule_info("id", "< /[a-z][a-z_]*/i > { text }")
|
1489
|
+
Rules[:_ids] = rule_info("ids", "(ids:i1 - \",\" - ids:i2 { i1 + i2 } | id:i { [i] })")
|
1490
|
+
Rules[:_item] = rule_info("item", "(attribute | attributes | element)")
|
1491
|
+
Rules[:_items] = rule_info("items", "(items:i1 items:i2 { i1 + i2 } | item:i { (i.is_a? Array) ? i : [i] })")
|
1492
|
+
Rules[:_contents] = rule_info("contents", "items?:i { i.to_a }")
|
1493
|
+
Rules[:_attr] = rule_info("attr", "- id:n - \"=\" - val:v - eol { Attribute.new n, *v }")
|
1494
|
+
Rules[:_multiple_attrs] = rule_info("multiple_attrs", "- ids:n - \"=\" - vals:v - eol { n.reduce(Array.new) do |attrs, name| value = v.shift or [nil] attrs << Attribute.new(name, *value) end }")
|
1495
|
+
Rules[:_attribute] = rule_info("attribute", "blk_lines attr:a blk_lines { a }")
|
1496
|
+
Rules[:_attributes] = rule_info("attributes", "blk_lines multiple_attrs:a blk_lines { a }")
|
1497
|
+
Rules[:_code] = rule_info("code", "< /<<.*?>>/m > { [strip_chars(text, 2), {:code => true}] }")
|
1498
|
+
Rules[:_in_brackets] = rule_info("in_brackets", "< /\\(.*?\\)/m > { [strip_chars(text, 1)] }")
|
1499
|
+
Rules[:_in_quotes] = rule_info("in_quotes", "< /\".*?\"/m > { [strip_chars(text, 1)] }")
|
1500
|
+
Rules[:_raw] = rule_info("raw", "< /.*/ > { [text.strip] }")
|
1501
|
+
Rules[:_escaped] = rule_info("escaped", "(in_quotes:s1 escaped:s2 { s1[0] += '\"' + s2[0] ; s1 } | in_quotes)")
|
1502
|
+
Rules[:_i18n] = rule_info("i18n", "\"_\" - (in_brackets | in_quotes):s { [s[0], {:translatable => true}] }")
|
1503
|
+
Rules[:_val] = rule_info("val", "(val:v1 - \"+\" sp_lf val:v2 { v1[0] += v2[0] ; v1 } | escaped | i18n | code | in_brackets | in_quotes | raw)")
|
1504
|
+
Rules[:_vals] = rule_info("vals", "(vals:v1 - \",\" - vals:v2 { v1 + v2 } | val:v { [v] })")
|
1505
|
+
Rules[:_amendment] = rule_info("amendment", "- amending_tag:n - eol contents:c - closing_tag(n) - eol { Element.new(n, :amendment => true).push *c }")
|
1506
|
+
Rules[:_regular] = rule_info("regular", "- opening_tag:n - eol contents:c - closing_tag(n) - eol { Element.new(n).push *c }")
|
1507
|
+
Rules[:_element] = rule_info("element", "blk_lines (amendment | regular):e blk_lines { e }")
|
1508
|
+
Rules[:_amending_tag] = rule_info("amending_tag", "\"[+\" id:n \"]\" { n }")
|
1509
|
+
Rules[:_closing_tag] = rule_info("closing_tag", "\"[/\" id:n \"]\" &{ n == m }")
|
1510
|
+
Rules[:_opening_tag] = rule_info("opening_tag", "\"[\" id:n \"]\" { n }")
|
1511
|
+
Rules[:_eof] = rule_info("eof", "!.")
|
1512
|
+
Rules[:_eol] = rule_info("eol", "(\"
|
1513
|
+
Rules[:_sp] = rule_info("sp", "(\" \" | \"\\t\")")
|
1514
|
+
Rules[:__hyphen_] = rule_info("-", "sp*")
|
1515
|
+
Rules[:_sp_lf] = rule_info("sp_lf", "(sp | eol)*")
|
1516
|
+
Rules[:_blk_lines] = rule_info("blk_lines", "(- eol)*")
|
1517
|
+
Rules[:_root] = rule_info("root", "contents:c { Root.new.push *c }")
|
1518
|
+
# :startdoc:
|
1519
|
+
end
|
1520
|
+
|
1521
|
+
end
|