citrus 1.5.2 → 1.6.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/benchmark/seqpar.rb +3 -2
- data/lib/citrus.rb +20 -30
- data/test/file_test.rb +0 -8
- data/test/grammar_test.rb +2 -3
- metadata +3 -3
data/benchmark/seqpar.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
$LOAD_PATH << File.expand_path('../../lib', __FILE__)
|
2
|
+
|
1
3
|
# Benchmarking written by Bernard Lambeau and Jason Garber of the Treetop
|
2
4
|
# project.
|
3
5
|
#
|
@@ -7,8 +9,7 @@
|
|
7
9
|
# 3. Make your modifications to the Citrus code
|
8
10
|
# 4. Run ruby seqpar.rb
|
9
11
|
# 5. Run gnuplot seqpar.gnuplot
|
10
|
-
|
11
|
-
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
12
|
+
|
12
13
|
require 'citrus'
|
13
14
|
require 'benchmark'
|
14
15
|
|
data/lib/citrus.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
#
|
5
5
|
# http://mjijackson.com/citrus
|
6
6
|
module Citrus
|
7
|
-
VERSION = [1,
|
7
|
+
VERSION = [1, 6, 0]
|
8
8
|
|
9
9
|
Infinity = 1.0 / 0
|
10
10
|
|
@@ -166,7 +166,7 @@ module Citrus
|
|
166
166
|
|
167
167
|
rules[sym] || super_rule(sym)
|
168
168
|
rescue => e
|
169
|
-
raise
|
169
|
+
raise 'Cannot create rule "%s": %s' % [name, e.message]
|
170
170
|
end
|
171
171
|
|
172
172
|
# Gets/sets the +name+ of the root rule of this grammar. If no root rule is
|
@@ -250,40 +250,30 @@ module Citrus
|
|
250
250
|
# description of available parse options.
|
251
251
|
def parse(string, options={})
|
252
252
|
opts = default_parse_options.merge(options)
|
253
|
-
|
254
|
-
raise "No root rule specified" unless opts[:root]
|
253
|
+
raise 'No root rule specified' unless opts[:root]
|
255
254
|
|
256
255
|
root_rule = rule(opts[:root])
|
257
|
-
raise
|
258
|
-
|
259
|
-
input = Input.new(string, opts[:enable_memo])
|
260
|
-
match = input.match(root_rule, opts[:offset])
|
256
|
+
raise 'No rule named "%s"' % root unless root_rule
|
261
257
|
|
262
|
-
|
263
|
-
|
264
|
-
end
|
265
|
-
|
266
|
-
match
|
258
|
+
input = Input.new(string, opts[:memoize])
|
259
|
+
input.match(root_rule, opts[:offset]) or raise ParseError.new(input)
|
267
260
|
end
|
268
261
|
|
269
262
|
# The default set of options that is used in #parse. The options hash may
|
270
263
|
# have any of the following keys:
|
271
264
|
#
|
272
|
-
# offset::
|
273
|
-
# root::
|
274
|
-
#
|
275
|
-
#
|
276
|
-
#
|
277
|
-
#
|
278
|
-
#
|
279
|
-
#
|
280
|
-
# significantly more in terms of time and memory required.
|
281
|
-
# Defaults to +false+.
|
265
|
+
# offset:: The offset at which the parse should start. Defaults to 0.
|
266
|
+
# root:: The name of the root rule to use for the parse. Defaults
|
267
|
+
# to the name supplied by calling #root.
|
268
|
+
# memoize:: If this is +true+ the matches generated during a parse are
|
269
|
+
# memoized. This technique (also known as Packrat parsing)
|
270
|
+
# guarantees parsers will operate in linear time but costs
|
271
|
+
# significantly more in terms of time and memory required.
|
272
|
+
# Defaults to +false+.
|
282
273
|
def default_parse_options
|
283
|
-
{ :offset
|
284
|
-
:root
|
285
|
-
:
|
286
|
-
:enable_memo => false
|
274
|
+
{ :offset => 0,
|
275
|
+
:root => root,
|
276
|
+
:memoize => false
|
287
277
|
}
|
288
278
|
end
|
289
279
|
end
|
@@ -291,12 +281,12 @@ module Citrus
|
|
291
281
|
# This class represents the core of the parsing algorithm. It wraps the input
|
292
282
|
# string and serves matches to all nonterminals.
|
293
283
|
class Input
|
294
|
-
# Takes the input +string+ that is to be parsed. If +
|
284
|
+
# Takes the input +string+ that is to be parsed. If +memoize+ is +true+
|
295
285
|
# a cache is created that holds references to already generated matches.
|
296
|
-
def initialize(string,
|
286
|
+
def initialize(string, memoize=false)
|
297
287
|
@string = string
|
298
288
|
@max_offset = 0
|
299
|
-
if
|
289
|
+
if memoize
|
300
290
|
@cache = {}
|
301
291
|
@cache_hits = 0
|
302
292
|
end
|
data/test/file_test.rb
CHANGED
@@ -347,10 +347,6 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
347
347
|
match = grammar.parse('some_rule ')
|
348
348
|
assert(match)
|
349
349
|
assert('some_rule', match.value)
|
350
|
-
|
351
|
-
assert_raise ParseError do
|
352
|
-
match = grammar.parse('some_rule1')
|
353
|
-
end
|
354
350
|
end
|
355
351
|
|
356
352
|
def test_terminal
|
@@ -674,10 +670,6 @@ class CitrusFileTest < Test::Unit::TestCase
|
|
674
670
|
match = grammar.parse('# A comment.')
|
675
671
|
assert(match)
|
676
672
|
assert_equal('# A comment.', match.text)
|
677
|
-
|
678
|
-
assert_raise ParseError do
|
679
|
-
match = grammar.parse("# A comment.\n")
|
680
|
-
end
|
681
673
|
end
|
682
674
|
|
683
675
|
end
|
data/test/grammar_test.rb
CHANGED
@@ -70,9 +70,8 @@ class GrammarTest < Test::Unit::TestCase
|
|
70
70
|
grammar = Grammar.new {
|
71
71
|
rule(:num) { all(1, 2, 3) }
|
72
72
|
}
|
73
|
-
|
74
|
-
|
75
|
-
end
|
73
|
+
match = grammar.parse('1234')
|
74
|
+
assert(match)
|
76
75
|
end
|
77
76
|
|
78
77
|
def test_parse_sequence_short
|