citrus 1.5.2 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|