kpeg 0.10.0 → 1.3.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.
- checksums.yaml +7 -0
- data/.hoeignore +12 -0
- data/Gemfile +3 -0
- data/History.txt +14 -0
- data/Manifest.txt +9 -0
- data/README.rdoc +8 -8
- data/Rakefile +2 -0
- data/bin/kpeg +9 -2
- data/examples/lua_string/lua_string.kpeg.rb +0 -2
- data/examples/tiny_markdown/Rakefile +3 -0
- data/examples/tiny_markdown/driver.rb +10 -0
- data/examples/tiny_markdown/node.rb +107 -0
- data/examples/tiny_markdown/sample.md +51 -0
- data/examples/tiny_markdown/tiny_markdown.kpeg +199 -0
- data/examples/tiny_markdown/tiny_markdown.kpeg.rb +3892 -0
- data/kpeg.gemspec +20 -20
- data/lib/kpeg/code_generator.rb +10 -7
- data/lib/kpeg/compiled_parser.rb +17 -17
- data/lib/kpeg/format_parser.kpeg +1 -1
- data/lib/kpeg/format_parser.rb +60 -43
- data/lib/kpeg/grammar.rb +1 -1
- data/lib/kpeg/position.rb +25 -10
- data/lib/kpeg/string_escape.kpeg +1 -0
- data/lib/kpeg/string_escape.rb +69 -37
- data/lib/kpeg.rb +1 -1
- data/test/test_kpeg.rb +1 -1
- data/test/test_kpeg_code_generator.rb +20 -14
- data/test/test_kpeg_compiled_parser.rb +11 -2
- data/test/test_kpeg_format.rb +23 -4
- data/test/test_kpeg_format_parser_round_trip.rb +1 -1
- data/test/test_kpeg_grammar.rb +1 -1
- data/test/test_kpeg_grammar_renderer.rb +1 -1
- data/test/test_kpeg_string_escape.rb +42 -0
- metadata +89 -97
- data/.gemtest +0 -0
data/kpeg.gemspec
CHANGED
@@ -1,42 +1,42 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
# stub: kpeg 1.0.0.20140103162640 ruby lib
|
2
3
|
|
3
4
|
Gem::Specification.new do |s|
|
4
5
|
s.name = "kpeg"
|
5
|
-
s.version = "0.
|
6
|
+
s.version = "1.0.0.20140103162640"
|
6
7
|
|
7
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
-
s.authors = ["
|
9
|
-
s.
|
10
|
-
s.date = "2012-03-07"
|
9
|
+
s.authors = ["Evan Phoenix"]
|
10
|
+
s.date = "2014-01-04"
|
11
11
|
s.description = "KPeg is a simple PEG library for Ruby. It provides an API as well as native\ngrammar to build the grammar.\n\nKPeg strives to provide a simple, powerful API without being too exotic.\n\nKPeg supports direct left recursion of rules via the\n{OMeta memoization}[http://www.vpri.org/pdf/tr2008003_experimenting.pdf] trick."
|
12
|
-
s.email = ["
|
12
|
+
s.email = ["evan@fallingsnow.net"]
|
13
13
|
s.executables = ["kpeg"]
|
14
|
-
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.rdoc"]
|
15
|
-
s.files = [".autotest", "
|
14
|
+
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.rdoc", "examples/phone_number/README.md", "examples/upper/README.md"]
|
15
|
+
s.files = [".autotest", ".travis.yml", "History.txt", "LICENSE", "Manifest.txt", "README.rdoc", "Rakefile", "bin/kpeg", "examples/calculator/calculator.kpeg", "examples/calculator/calculator.rb", "examples/foreign_reference/literals.kpeg", "examples/foreign_reference/matcher.kpeg", "examples/foreign_reference/matcher.rb", "examples/lua_string/driver.rb", "examples/lua_string/lua_string.kpeg", "examples/lua_string/lua_string.kpeg.rb", "examples/phone_number/README.md", "examples/phone_number/phone_number.kpeg", "examples/phone_number/phone_number.rb", "examples/upper/README.md", "examples/upper/upper.kpeg", "examples/upper/upper.rb", "kpeg.gemspec", "lib/hoe/kpeg.rb", "lib/kpeg.rb", "lib/kpeg/code_generator.rb", "lib/kpeg/compiled_parser.rb", "lib/kpeg/format_parser.kpeg", "lib/kpeg/format_parser.rb", "lib/kpeg/grammar.rb", "lib/kpeg/grammar_renderer.rb", "lib/kpeg/match.rb", "lib/kpeg/parser.rb", "lib/kpeg/position.rb", "lib/kpeg/string_escape.kpeg", "lib/kpeg/string_escape.rb", "test/inputs/comments.kpeg", "test/test_kpeg.rb", "test/test_kpeg_code_generator.rb", "test/test_kpeg_compiled_parser.rb", "test/test_kpeg_format.rb", "test/test_kpeg_format_parser_round_trip.rb", "test/test_kpeg_grammar.rb", "test/test_kpeg_grammar_renderer.rb", "vim/syntax_kpeg/ftdetect/kpeg.vim", "vim/syntax_kpeg/syntax/kpeg.vim", "test/test_kpeg_string_escape.rb", ".gemtest"]
|
16
16
|
s.homepage = "https://github.com/evanphx/kpeg"
|
17
|
+
s.licenses = ["MIT"]
|
17
18
|
s.rdoc_options = ["--main", "README.rdoc"]
|
18
19
|
s.require_paths = ["lib"]
|
19
20
|
s.rubyforge_project = "kpeg"
|
20
|
-
s.rubygems_version = "1.
|
21
|
-
s.signing_key = "/Users/drbrain/.gem/gem-private_key.pem"
|
21
|
+
s.rubygems_version = "2.1.10"
|
22
22
|
s.summary = "KPeg is a simple PEG library for Ruby"
|
23
|
-
s.test_files = ["test/
|
23
|
+
s.test_files = ["test/test_kpeg.rb", "test/test_kpeg_code_generator.rb", "test/test_kpeg_compiled_parser.rb", "test/test_kpeg_format.rb", "test/test_kpeg_format_parser_round_trip.rb", "test/test_kpeg_grammar.rb", "test/test_kpeg_grammar_renderer.rb", "test/test_kpeg_string_escape.rb"]
|
24
24
|
|
25
25
|
if s.respond_to? :specification_version then
|
26
|
-
s.specification_version =
|
26
|
+
s.specification_version = 4
|
27
27
|
|
28
28
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
29
|
-
s.add_development_dependency(%q<minitest>, ["~> 2
|
30
|
-
s.add_development_dependency(%q<rdoc>, ["~>
|
31
|
-
s.add_development_dependency(%q<hoe>, ["~>
|
29
|
+
s.add_development_dependency(%q<minitest>, ["~> 5.2"])
|
30
|
+
s.add_development_dependency(%q<rdoc>, ["~> 4.0"])
|
31
|
+
s.add_development_dependency(%q<hoe>, ["~> 3.7"])
|
32
32
|
else
|
33
|
-
s.add_dependency(%q<minitest>, ["~> 2
|
34
|
-
s.add_dependency(%q<rdoc>, ["~>
|
35
|
-
s.add_dependency(%q<hoe>, ["~>
|
33
|
+
s.add_dependency(%q<minitest>, ["~> 5.2"])
|
34
|
+
s.add_dependency(%q<rdoc>, ["~> 4.0"])
|
35
|
+
s.add_dependency(%q<hoe>, ["~> 3.7"])
|
36
36
|
end
|
37
37
|
else
|
38
|
-
s.add_dependency(%q<minitest>, ["~> 2
|
39
|
-
s.add_dependency(%q<rdoc>, ["~>
|
40
|
-
s.add_dependency(%q<hoe>, ["~>
|
38
|
+
s.add_dependency(%q<minitest>, ["~> 5.2"])
|
39
|
+
s.add_dependency(%q<rdoc>, ["~> 4.0"])
|
40
|
+
s.add_dependency(%q<hoe>, ["~> 3.7"])
|
41
41
|
end
|
42
42
|
end
|
data/lib/kpeg/code_generator.rb
CHANGED
@@ -83,11 +83,14 @@ module KPeg
|
|
83
83
|
|
84
84
|
if output_node
|
85
85
|
code << " end\n"
|
86
|
+
code << " module #{root}Construction\n"
|
86
87
|
methods.each do |short, name, attrs|
|
87
|
-
code << "
|
88
|
-
code << "
|
89
|
-
code << "
|
88
|
+
code << " def #{short}(#{attrs.join(', ')})\n"
|
89
|
+
code << " #{root}::#{name}.new(#{attrs.join(', ')})\n"
|
90
|
+
code << " end\n"
|
90
91
|
end
|
92
|
+
code << " end\n"
|
93
|
+
code << " include #{root}Construction\n"
|
91
94
|
end
|
92
95
|
end
|
93
96
|
|
@@ -109,7 +112,7 @@ module KPeg
|
|
109
112
|
# Let default ruby string handling figure it out
|
110
113
|
lang = ""
|
111
114
|
end
|
112
|
-
code << indentify("_tmp = scan(/\\
|
115
|
+
code << indentify("_tmp = scan(/\\G#{op.regexp}/#{lang})\n", indent)
|
113
116
|
when CharRange
|
114
117
|
ss = save()
|
115
118
|
if op.start.bytesize == 1 and op.fin.bytesize == 1
|
@@ -124,7 +127,7 @@ module KPeg
|
|
124
127
|
left = op.start[0]
|
125
128
|
right = op.fin[0]
|
126
129
|
end
|
127
|
-
|
130
|
+
|
128
131
|
code << indentify(" unless _tmp >= #{left} and _tmp <= #{right}\n", indent)
|
129
132
|
code << indentify(" self.pos = #{ss}\n", indent)
|
130
133
|
code << indentify(" _tmp = nil\n", indent)
|
@@ -140,7 +143,7 @@ module KPeg
|
|
140
143
|
code << indentify("while true # choice\n", indent)
|
141
144
|
op.ops.each_with_index do |n,idx|
|
142
145
|
output_op code, n, (indent+1)
|
143
|
-
|
146
|
+
|
144
147
|
code << indentify(" break if _tmp\n", indent)
|
145
148
|
code << indentify(" self.pos = #{ss}\n", indent)
|
146
149
|
if idx == op.ops.size - 1
|
@@ -447,7 +450,7 @@ module KPeg
|
|
447
450
|
cpi = standalone_region("compiled_parser.rb", "INITIALIZE")
|
448
451
|
pp = standalone_region("position.rb")
|
449
452
|
|
450
|
-
cp.gsub!(
|
453
|
+
cp.gsub!(/^\s*include Position/, pp)
|
451
454
|
code << " # :stopdoc:\n"
|
452
455
|
code << cpi << "\n" unless @grammar.variables['custom_initialize']
|
453
456
|
code << cp << "\n"
|
data/lib/kpeg/compiled_parser.rb
CHANGED
@@ -27,12 +27,12 @@ module KPeg
|
|
27
27
|
# Prepares for parsing +str+. If you define a custom initialize you must
|
28
28
|
# call this method before #parse
|
29
29
|
def setup_parser(str, debug=false)
|
30
|
-
|
31
|
-
@pos = 0
|
30
|
+
set_string str, 0
|
32
31
|
@memoizations = Hash.new { |h,k| h[k] = {} }
|
33
32
|
@result = nil
|
34
33
|
@failed_rule = nil
|
35
34
|
@failing_rule_offset = -1
|
35
|
+
@line_offsets = nil
|
36
36
|
|
37
37
|
setup_foreign_grammar
|
38
38
|
end
|
@@ -47,6 +47,13 @@ module KPeg
|
|
47
47
|
@string[start..@pos-1]
|
48
48
|
end
|
49
49
|
|
50
|
+
# Sets the string and current parsing position for the parser.
|
51
|
+
def set_string string, pos
|
52
|
+
@string = string
|
53
|
+
@string_size = string ? string.size : 0
|
54
|
+
@pos = pos
|
55
|
+
end
|
56
|
+
|
50
57
|
def show_pos
|
51
58
|
width = 10
|
52
59
|
if @pos < width
|
@@ -144,28 +151,27 @@ module KPeg
|
|
144
151
|
end
|
145
152
|
|
146
153
|
def scan(reg)
|
147
|
-
if m = reg.match(@string
|
148
|
-
|
149
|
-
@pos += width
|
154
|
+
if m = reg.match(@string, @pos)
|
155
|
+
@pos = m.end(0)
|
150
156
|
return true
|
151
157
|
end
|
152
158
|
|
153
159
|
return nil
|
154
160
|
end
|
155
161
|
|
156
|
-
if "".respond_to? :
|
162
|
+
if "".respond_to? :ord
|
157
163
|
def get_byte
|
158
|
-
if @pos >= @
|
164
|
+
if @pos >= @string_size
|
159
165
|
return nil
|
160
166
|
end
|
161
167
|
|
162
|
-
s = @string
|
168
|
+
s = @string[@pos].ord
|
163
169
|
@pos += 1
|
164
170
|
s
|
165
171
|
end
|
166
172
|
else
|
167
173
|
def get_byte
|
168
|
-
if @pos >= @
|
174
|
+
if @pos >= @string_size
|
169
175
|
return nil
|
170
176
|
end
|
171
177
|
|
@@ -214,8 +220,7 @@ module KPeg
|
|
214
220
|
old_pos = @pos
|
215
221
|
old_string = @string
|
216
222
|
|
217
|
-
|
218
|
-
@string = other.string
|
223
|
+
set_string other.string, other.pos
|
219
224
|
|
220
225
|
begin
|
221
226
|
if val = __send__(rule, *args)
|
@@ -226,8 +231,7 @@ module KPeg
|
|
226
231
|
end
|
227
232
|
val
|
228
233
|
ensure
|
229
|
-
|
230
|
-
@string = old_string
|
234
|
+
set_string old_string, old_pos
|
231
235
|
end
|
232
236
|
end
|
233
237
|
|
@@ -261,8 +265,6 @@ module KPeg
|
|
261
265
|
else
|
262
266
|
return ans
|
263
267
|
end
|
264
|
-
|
265
|
-
return ans
|
266
268
|
end
|
267
269
|
end
|
268
270
|
|
@@ -295,8 +297,6 @@ module KPeg
|
|
295
297
|
else
|
296
298
|
return ans
|
297
299
|
end
|
298
|
-
|
299
|
-
return ans
|
300
300
|
end
|
301
301
|
end
|
302
302
|
|
data/lib/kpeg/format_parser.kpeg
CHANGED
@@ -77,7 +77,7 @@ sgl_escape_quote = "\\'" { "'" }
|
|
77
77
|
| "[" - range_num:e - "]" { [e.to_i, e.to_i] }
|
78
78
|
|
79
79
|
curly_block = curly
|
80
|
-
curly = "{" < (/[^{}"']+/ | string | curly)* > "}" { @g.action(text) }
|
80
|
+
curly = "{" < (spaces | /[^{}"']+/ | string | curly)* > "}" { @g.action(text) }
|
81
81
|
nested_paren = "(" (/[^()"']+/ | string | nested_paren)* ")"
|
82
82
|
|
83
83
|
value = value:v ":" var:n { @g.t(v,n) }
|
data/lib/kpeg/format_parser.rb
CHANGED
@@ -5,12 +5,12 @@ class KPeg::FormatParser
|
|
5
5
|
# Prepares for parsing +str+. If you define a custom initialize you must
|
6
6
|
# call this method before #parse
|
7
7
|
def setup_parser(str, debug=false)
|
8
|
-
|
9
|
-
@pos = 0
|
8
|
+
set_string str, 0
|
10
9
|
@memoizations = Hash.new { |h,k| h[k] = {} }
|
11
10
|
@result = nil
|
12
11
|
@failed_rule = nil
|
13
12
|
@failing_rule_offset = -1
|
13
|
+
@line_offsets = nil
|
14
14
|
|
15
15
|
setup_foreign_grammar
|
16
16
|
end
|
@@ -19,7 +19,6 @@ class KPeg::FormatParser
|
|
19
19
|
attr_reader :failing_rule_offset
|
20
20
|
attr_accessor :result, :pos
|
21
21
|
|
22
|
-
|
23
22
|
def current_column(target=pos)
|
24
23
|
if c = string.rindex("\n", target-1)
|
25
24
|
return target - c - 1
|
@@ -28,17 +27,32 @@ class KPeg::FormatParser
|
|
28
27
|
target + 1
|
29
28
|
end
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
if [].respond_to? :bsearch_index
|
31
|
+
def current_line(target=pos)
|
32
|
+
unless @line_offsets
|
33
|
+
@line_offsets = []
|
34
|
+
total = 0
|
35
|
+
string.each_line do |line|
|
36
|
+
total += line.size
|
37
|
+
@line_offsets << total
|
38
|
+
end
|
39
|
+
end
|
34
40
|
|
35
|
-
|
36
|
-
cur_line += 1
|
37
|
-
cur_offset += line.size
|
38
|
-
return cur_line if cur_offset >= target
|
41
|
+
@line_offsets.bsearch_index {|x| x >= target } + 1 || -1
|
39
42
|
end
|
43
|
+
else
|
44
|
+
def current_line(target=pos)
|
45
|
+
cur_offset = 0
|
46
|
+
cur_line = 0
|
40
47
|
|
41
|
-
|
48
|
+
string.each_line do |line|
|
49
|
+
cur_line += 1
|
50
|
+
cur_offset += line.size
|
51
|
+
return cur_line if cur_offset >= target
|
52
|
+
end
|
53
|
+
|
54
|
+
-1
|
55
|
+
end
|
42
56
|
end
|
43
57
|
|
44
58
|
def lines
|
@@ -53,6 +67,13 @@ class KPeg::FormatParser
|
|
53
67
|
@string[start..@pos-1]
|
54
68
|
end
|
55
69
|
|
70
|
+
# Sets the string and current parsing position for the parser.
|
71
|
+
def set_string string, pos
|
72
|
+
@string = string
|
73
|
+
@string_size = string ? string.size : 0
|
74
|
+
@pos = pos
|
75
|
+
end
|
76
|
+
|
56
77
|
def show_pos
|
57
78
|
width = 10
|
58
79
|
if @pos < width
|
@@ -150,28 +171,27 @@ class KPeg::FormatParser
|
|
150
171
|
end
|
151
172
|
|
152
173
|
def scan(reg)
|
153
|
-
if m = reg.match(@string
|
154
|
-
|
155
|
-
@pos += width
|
174
|
+
if m = reg.match(@string, @pos)
|
175
|
+
@pos = m.end(0)
|
156
176
|
return true
|
157
177
|
end
|
158
178
|
|
159
179
|
return nil
|
160
180
|
end
|
161
181
|
|
162
|
-
if "".respond_to? :
|
182
|
+
if "".respond_to? :ord
|
163
183
|
def get_byte
|
164
|
-
if @pos >= @
|
184
|
+
if @pos >= @string_size
|
165
185
|
return nil
|
166
186
|
end
|
167
187
|
|
168
|
-
s = @string
|
188
|
+
s = @string[@pos].ord
|
169
189
|
@pos += 1
|
170
190
|
s
|
171
191
|
end
|
172
192
|
else
|
173
193
|
def get_byte
|
174
|
-
if @pos >= @
|
194
|
+
if @pos >= @string_size
|
175
195
|
return nil
|
176
196
|
end
|
177
197
|
|
@@ -220,8 +240,7 @@ class KPeg::FormatParser
|
|
220
240
|
old_pos = @pos
|
221
241
|
old_string = @string
|
222
242
|
|
223
|
-
|
224
|
-
@string = other.string
|
243
|
+
set_string other.string, other.pos
|
225
244
|
|
226
245
|
begin
|
227
246
|
if val = __send__(rule, *args)
|
@@ -232,8 +251,7 @@ class KPeg::FormatParser
|
|
232
251
|
end
|
233
252
|
val
|
234
253
|
ensure
|
235
|
-
|
236
|
-
@string = old_string
|
254
|
+
set_string old_string, old_pos
|
237
255
|
end
|
238
256
|
end
|
239
257
|
|
@@ -267,8 +285,6 @@ class KPeg::FormatParser
|
|
267
285
|
else
|
268
286
|
return ans
|
269
287
|
end
|
270
|
-
|
271
|
-
return ans
|
272
288
|
end
|
273
289
|
end
|
274
290
|
|
@@ -301,8 +317,6 @@ class KPeg::FormatParser
|
|
301
317
|
else
|
302
318
|
return ans
|
303
319
|
end
|
304
|
-
|
305
|
-
return ans
|
306
320
|
end
|
307
321
|
end
|
308
322
|
|
@@ -523,7 +537,7 @@ class KPeg::FormatParser
|
|
523
537
|
_tmp = match_string("-")
|
524
538
|
break if _tmp
|
525
539
|
self.pos = _save1
|
526
|
-
_tmp = scan(/\
|
540
|
+
_tmp = scan(/\G(?i-mx:[a-z][\w-]*)/)
|
527
541
|
break if _tmp
|
528
542
|
self.pos = _save1
|
529
543
|
break
|
@@ -554,7 +568,7 @@ class KPeg::FormatParser
|
|
554
568
|
_save = self.pos
|
555
569
|
while true # sequence
|
556
570
|
_text_start = self.pos
|
557
|
-
_tmp = scan(/\
|
571
|
+
_tmp = scan(/\G(?i-mx:[a-z_]\w*)/)
|
558
572
|
if _tmp
|
559
573
|
text = get_text(_text_start)
|
560
574
|
end
|
@@ -818,7 +832,7 @@ class KPeg::FormatParser
|
|
818
832
|
_save1 = self.pos
|
819
833
|
while true # sequence
|
820
834
|
_text_start = self.pos
|
821
|
-
_tmp = scan(/\
|
835
|
+
_tmp = scan(/\G(?-mix:[0-7]{1,3})/)
|
822
836
|
if _tmp
|
823
837
|
text = get_text(_text_start)
|
824
838
|
end
|
@@ -845,7 +859,7 @@ class KPeg::FormatParser
|
|
845
859
|
break
|
846
860
|
end
|
847
861
|
_text_start = self.pos
|
848
|
-
_tmp = scan(/\
|
862
|
+
_tmp = scan(/\G(?i-mx:[a-f\d]{2})/)
|
849
863
|
if _tmp
|
850
864
|
text = get_text(_text_start)
|
851
865
|
end
|
@@ -876,7 +890,7 @@ class KPeg::FormatParser
|
|
876
890
|
_save = self.pos
|
877
891
|
while true # sequence
|
878
892
|
_text_start = self.pos
|
879
|
-
_tmp = scan(/\
|
893
|
+
_tmp = scan(/\G(?-mix:[^\\"]+)/)
|
880
894
|
if _tmp
|
881
895
|
text = get_text(_text_start)
|
882
896
|
end
|
@@ -1014,7 +1028,7 @@ class KPeg::FormatParser
|
|
1014
1028
|
_save = self.pos
|
1015
1029
|
while true # sequence
|
1016
1030
|
_text_start = self.pos
|
1017
|
-
_tmp = scan(/\
|
1031
|
+
_tmp = scan(/\G(?-mix:[^'])/)
|
1018
1032
|
if _tmp
|
1019
1033
|
text = get_text(_text_start)
|
1020
1034
|
end
|
@@ -1139,7 +1153,7 @@ class KPeg::FormatParser
|
|
1139
1153
|
_tmp = match_string("\\/")
|
1140
1154
|
break if _tmp
|
1141
1155
|
self.pos = _save2
|
1142
|
-
_tmp = scan(/\
|
1156
|
+
_tmp = scan(/\G(?-mix:[^\/])/)
|
1143
1157
|
break if _tmp
|
1144
1158
|
self.pos = _save2
|
1145
1159
|
break
|
@@ -1153,7 +1167,7 @@ class KPeg::FormatParser
|
|
1153
1167
|
_tmp = match_string("\\/")
|
1154
1168
|
break if _tmp
|
1155
1169
|
self.pos = _save3
|
1156
|
-
_tmp = scan(/\
|
1170
|
+
_tmp = scan(/\G(?-mix:[^\/])/)
|
1157
1171
|
break if _tmp
|
1158
1172
|
self.pos = _save3
|
1159
1173
|
break
|
@@ -1266,7 +1280,7 @@ class KPeg::FormatParser
|
|
1266
1280
|
_save = self.pos
|
1267
1281
|
while true # sequence
|
1268
1282
|
_text_start = self.pos
|
1269
|
-
_tmp = scan(/\
|
1283
|
+
_tmp = scan(/\G(?i-mx:[a-z\d])/)
|
1270
1284
|
if _tmp
|
1271
1285
|
text = get_text(_text_start)
|
1272
1286
|
end
|
@@ -1336,7 +1350,7 @@ class KPeg::FormatParser
|
|
1336
1350
|
_save = self.pos
|
1337
1351
|
while true # sequence
|
1338
1352
|
_text_start = self.pos
|
1339
|
-
_tmp = scan(/\
|
1353
|
+
_tmp = scan(/\G(?-mix:[1-9]\d*)/)
|
1340
1354
|
if _tmp
|
1341
1355
|
text = get_text(_text_start)
|
1342
1356
|
end
|
@@ -1511,7 +1525,7 @@ class KPeg::FormatParser
|
|
1511
1525
|
return _tmp
|
1512
1526
|
end
|
1513
1527
|
|
1514
|
-
# curly = "{" < (/[^{}"']+/ | string | curly)* > "}" { @g.action(text) }
|
1528
|
+
# curly = "{" < (spaces | /[^{}"']+/ | string | curly)* > "}" { @g.action(text) }
|
1515
1529
|
def _curly
|
1516
1530
|
|
1517
1531
|
_save = self.pos
|
@@ -1526,7 +1540,10 @@ class KPeg::FormatParser
|
|
1526
1540
|
|
1527
1541
|
_save2 = self.pos
|
1528
1542
|
while true # choice
|
1529
|
-
_tmp =
|
1543
|
+
_tmp = apply(:_spaces)
|
1544
|
+
break if _tmp
|
1545
|
+
self.pos = _save2
|
1546
|
+
_tmp = scan(/\G(?-mix:[^{}"']+)/)
|
1530
1547
|
break if _tmp
|
1531
1548
|
self.pos = _save2
|
1532
1549
|
_tmp = apply(:_string)
|
@@ -1579,7 +1596,7 @@ class KPeg::FormatParser
|
|
1579
1596
|
|
1580
1597
|
_save2 = self.pos
|
1581
1598
|
while true # choice
|
1582
|
-
_tmp = scan(/\
|
1599
|
+
_tmp = scan(/\G(?-mix:[^()"']+)/)
|
1583
1600
|
break if _tmp
|
1584
1601
|
self.pos = _save2
|
1585
1602
|
_tmp = apply(:_string)
|
@@ -2616,7 +2633,7 @@ class KPeg::FormatParser
|
|
2616
2633
|
break
|
2617
2634
|
end
|
2618
2635
|
_text_start = self.pos
|
2619
|
-
_tmp = scan(/\
|
2636
|
+
_tmp = scan(/\G(?-mix:[:\w]+)/)
|
2620
2637
|
if _tmp
|
2621
2638
|
text = get_text(_text_start)
|
2622
2639
|
end
|
@@ -2914,7 +2931,7 @@ class KPeg::FormatParser
|
|
2914
2931
|
_save = self.pos
|
2915
2932
|
while true # sequence
|
2916
2933
|
_text_start = self.pos
|
2917
|
-
_tmp = scan(/\
|
2934
|
+
_tmp = scan(/\G(?-mix:[A-Z]\w*)/)
|
2918
2935
|
if _tmp
|
2919
2936
|
text = get_text(_text_start)
|
2920
2937
|
end
|
@@ -2940,7 +2957,7 @@ class KPeg::FormatParser
|
|
2940
2957
|
_save = self.pos
|
2941
2958
|
while true # sequence
|
2942
2959
|
_text_start = self.pos
|
2943
|
-
_tmp = scan(/\
|
2960
|
+
_tmp = scan(/\G(?i-mx:[a-z_]\w*)/)
|
2944
2961
|
if _tmp
|
2945
2962
|
text = get_text(_text_start)
|
2946
2963
|
end
|
@@ -3157,7 +3174,7 @@ class KPeg::FormatParser
|
|
3157
3174
|
Rules[:_range_elem] = rule_info("range_elem", "< (range_num | kleene) > { text }")
|
3158
3175
|
Rules[:_mult_range] = rule_info("mult_range", "(\"[\" - range_elem:l - \",\" - range_elem:r - \"]\" { [l == \"*\" ? nil : l.to_i, r == \"*\" ? nil : r.to_i] } | \"[\" - range_num:e - \"]\" { [e.to_i, e.to_i] })")
|
3159
3176
|
Rules[:_curly_block] = rule_info("curly_block", "curly")
|
3160
|
-
Rules[:_curly] = rule_info("curly", "\"{\" < (/[^{}\"']+/ | string | curly)* > \"}\" { @g.action(text) }")
|
3177
|
+
Rules[:_curly] = rule_info("curly", "\"{\" < (spaces | /[^{}\"']+/ | string | curly)* > \"}\" { @g.action(text) }")
|
3161
3178
|
Rules[:_nested_paren] = rule_info("nested_paren", "\"(\" (/[^()\"']+/ | string | nested_paren)* \")\"")
|
3162
3179
|
Rules[:_value] = rule_info("value", "(value:v \":\" var:n { @g.t(v,n) } | value:v \"?\" { @g.maybe(v) } | value:v \"+\" { @g.many(v) } | value:v \"*\" { @g.kleene(v) } | value:v mult_range:r { @g.multiple(v, *r) } | \"&\" value:v { @g.andp(v) } | \"!\" value:v { @g.notp(v) } | \"(\" - expression:o - \")\" { o } | \"@<\" - expression:o - \">\" { @g.bounds(o) } | \"<\" - expression:o - \">\" { @g.collect(o) } | curly_block | \"~\" method:m < nested_paren? > { @g.action(\"\#{m}\#{text}\") } | \".\" { @g.dot } | \"@\" var:name < nested_paren? > !(- \"=\") { @g.invoke(name, text.empty? ? nil : text) } | \"^\" var:name < nested_paren? > { @g.foreign_invoke(\"parent\", name, text) } | \"%\" var:gram \".\" var:name < nested_paren? > { @g.foreign_invoke(gram, name, text) } | var:name < nested_paren? > !(- \"=\") { @g.ref(name, nil, text.empty? ? nil : text) } | char_range | regexp | string)")
|
3163
3180
|
Rules[:_spaces] = rule_info("spaces", "(space | comment)+")
|
data/lib/kpeg/grammar.rb
CHANGED
@@ -834,7 +834,7 @@ module KPeg
|
|
834
834
|
# Invoke a rule defined on a foreign grammar
|
835
835
|
# == Parameters:
|
836
836
|
# gram::
|
837
|
-
# The name of the grammar that the rule will be reference from
|
837
|
+
# The name of the grammar that the rule will be reference from
|
838
838
|
# name::
|
839
839
|
# The name of the rule that will be invoked
|
840
840
|
# args::
|
data/lib/kpeg/position.rb
CHANGED
@@ -10,17 +10,32 @@ module KPeg
|
|
10
10
|
target + 1
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
13
|
+
if [].respond_to? :bsearch_index
|
14
|
+
def current_line(target=pos)
|
15
|
+
unless @line_offsets
|
16
|
+
@line_offsets = []
|
17
|
+
total = 0
|
18
|
+
string.each_line do |line|
|
19
|
+
total += line.size
|
20
|
+
@line_offsets << total
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
@line_offsets.bsearch_index {|x| x >= target } + 1 || -1
|
25
|
+
end
|
26
|
+
else
|
27
|
+
def current_line(target=pos)
|
28
|
+
cur_offset = 0
|
29
|
+
cur_line = 0
|
30
|
+
|
31
|
+
string.each_line do |line|
|
32
|
+
cur_line += 1
|
33
|
+
cur_offset += line.size
|
34
|
+
return cur_line if cur_offset >= target
|
35
|
+
end
|
36
|
+
|
37
|
+
-1
|
21
38
|
end
|
22
|
-
|
23
|
-
-1
|
24
39
|
end
|
25
40
|
|
26
41
|
def lines
|