biodiversity 0.5.14

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/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
6
+ *.swp
7
+ *.swo
8
+ biodiversity*.gem
9
+ *json
10
+ *xml
11
+ tmp
12
+ .DS_Store
13
+ spec/parser/test_data_new.txt
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Dmitry Mozzherin
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,44 @@
1
+ = Biodiversity
2
+
3
+ Parses species scientific name and breaks it into elements.
4
+
5
+ == Installation
6
+
7
+ To install gem you need RubyGems >= 1.2.0
8
+
9
+ $ gem sources -a http://gems.github.com (you only have to do this once)
10
+ $ sudo gem install dimus-biodiversity
11
+
12
+ == Example usage
13
+
14
+ You can parse file with species names from command line. File should contain one scientific name per line
15
+
16
+ nnparser file_with_names
17
+
18
+ You can use it as a library
19
+
20
+ require 'biodiversity'
21
+
22
+ parser = ScientificNameParser.new
23
+
24
+ # to parse a scientific name into a ruby hash
25
+ parser.parse("Plantago major")
26
+
27
+ #to get json representation
28
+ parser.parse("Plantago").to_json
29
+ #or
30
+ parser.parse("Plantago")
31
+ parser.all_json
32
+
33
+ # to clean name up
34
+ parser.parse(" Plantago major ")[:scientificName][:normalized]
35
+
36
+ # to get only cleaned up latin part of the name
37
+ parser.parse("Pseudocercospora dendrobii (H.C. Burnett) U. Braun & Crous 2003")[:scientificName][:canonical]
38
+
39
+ # to get detailed information about elements of the name
40
+ parser.parse("Pseudocercospora dendrobii (H.C. Burnett 1883) U. Braun & Crous 2003")[:scientificName][:details]
41
+
42
+ # to resolve lsid and get back RDF file
43
+ LsidResolver.resolve("urn:lsid:ubio.org:classificationbank:2232671")
44
+
data/Rakefile ADDED
@@ -0,0 +1,43 @@
1
+ dir = File.dirname(__FILE__)
2
+ require 'rubygems'
3
+ require 'rake'
4
+ #$LOAD_PATH.unshift(File.join(dir, 'vendor', 'rspec', 'lib'))
5
+ require 'spec/rake/spectask'
6
+
7
+ #Gem::manage_gems
8
+ #require 'rake/gempackagetask'
9
+
10
+ task :default => :spec
11
+
12
+ Spec::Rake::SpecTask.new do |t|
13
+ t.pattern = 'spec/**/*spec.rb'
14
+ end
15
+
16
+
17
+ begin
18
+ require 'jeweler'
19
+ Jeweler::Tasks.new do |gem|
20
+ gem.name = "biodiversity"
21
+ gem.summary = 'Parser of scientific names'
22
+ gem.description = 'Tools for biodiversity informatics'
23
+ gem.email = "dmozzherin@gmail.com"
24
+ gem.homepage = "http://github.com/dimus/biodiversity"
25
+ gem.authors = ["Dmitry Mozzherin"]
26
+ gem.has_rdoc = false
27
+ gem.bindir = 'bin'
28
+ gem.executables = ['nnparse']
29
+ gem.add_dependency('treetop')
30
+ gem.add_dependency('json') if RUBY_VERSION.split(".")[0..1].join('').to_i < 19
31
+ gem.add_development_dependency "rspec"
32
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
33
+ end
34
+ rescue LoadError
35
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
36
+ end
37
+
38
+ task :tt do
39
+ system("tt #{dir}/lib/biodiversity/parser/scientific_name_clean.treetop")
40
+ system("tt #{dir}/lib/biodiversity/parser/scientific_name_dirty.treetop")
41
+ system("tt #{dir}/lib/biodiversity/parser/scientific_name_canonical.treetop")
42
+ end
43
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.5.14
data/bin/nnparse ADDED
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ gem 'dimus-biodiversity' rescue gem 'biodiversity' rescue nil
4
+
5
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
6
+ require 'biodiversity'
7
+ require 'json'
8
+
9
+
10
+ if ARGV.empty?
11
+ puts "Usage:\n\nnnparse file_with_scientific_names [output_file]\n\ndefault output_file is parsed.json\n\n"
12
+ exit
13
+ end
14
+
15
+ input = ARGV[0]
16
+ output = ARGV[1] || 'parsed.json'
17
+
18
+ ruby_min_version = RUBY_VERSION.split(".")[0..1].join('').to_i
19
+
20
+ p = ScientificNameParser.new
21
+ o = open(output, 'w')
22
+ count = 0
23
+ puts 'Parsing...'
24
+ IO.foreach(input) do |line|
25
+ count += 1
26
+ puts("%s lines parsed" % count) if count % 10000 == 0
27
+ name = line.gsub(/^[\d]*\s*/, '').strip
28
+ begin
29
+ if ruby_min_version < 19
30
+ old_kcode = $KCODE
31
+ $KCODE = 'NONE'
32
+ end
33
+ p.parse(name)
34
+ parsed_data = p.parsed.all_json rescue {'parsed' => false, 'verbatim' => name, 'error' => 'Parser error'}.to_json
35
+ if ruby_min_version < 19
36
+ $KCODE = old_kcode
37
+ end
38
+ rescue
39
+ parsed_data = {'parsed' => false, 'verbatim' => name, 'error' => 'Parser error'}.to_json
40
+ end
41
+ o.write parsed_data + "\n"
42
+ end
43
+
data/bin/parserver ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'socket'
4
+ require 'biodiversity' # Get sockets from stdlib
5
+ parser = ScientificNameParser.new
6
+ server = TCPServer.open(4334) # Socket to listen on port 4334
7
+ loop do # Servers run forever
8
+ client = server.accept # Wait for a client to connect
9
+ while a = client.readline
10
+ client.close if ['end','exit','q', '.'].include? a.strip
11
+ client.puts parser.parse(a).to_json
12
+ end
13
+ end
14
+
@@ -0,0 +1,88 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{biodiversity}
8
+ s.version = "0.5.14"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Dmitry Mozzherin"]
12
+ s.date = %q{2010-03-19}
13
+ s.default_executable = %q{nnparse}
14
+ s.description = %q{Tools for biodiversity informatics}
15
+ s.email = %q{dmozzherin@gmail.com}
16
+ s.executables = ["nnparse"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.rdoc"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ ".gitignore",
24
+ "LICENSE",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "bin/nnparse",
29
+ "bin/parserver",
30
+ "biodiversity.gemspec",
31
+ "conf/environment.rb",
32
+ "lib/biodiversity.rb",
33
+ "lib/biodiversity/guid.rb",
34
+ "lib/biodiversity/guid/lsid.rb",
35
+ "lib/biodiversity/parser.rb",
36
+ "lib/biodiversity/parser/scientific_name_canonical.rb",
37
+ "lib/biodiversity/parser/scientific_name_canonical.treetop",
38
+ "lib/biodiversity/parser/scientific_name_clean.rb",
39
+ "lib/biodiversity/parser/scientific_name_clean.treetop",
40
+ "lib/biodiversity/parser/scientific_name_dirty.rb",
41
+ "lib/biodiversity/parser/scientific_name_dirty.treetop",
42
+ "pkg/.gitignore",
43
+ "spec/biodiversity_spec.rb",
44
+ "spec/guid/lsid.spec.rb",
45
+ "spec/parser/scientific_name.spec.rb",
46
+ "spec/parser/scientific_name_canonical.spec.rb",
47
+ "spec/parser/scientific_name_clean.spec.rb",
48
+ "spec/parser/scientific_name_dirty.spec.rb",
49
+ "spec/parser/spec_helper.rb",
50
+ "spec/parser/test_data.txt",
51
+ "spec/spec_helper.rb"
52
+ ]
53
+ s.homepage = %q{http://github.com/dimus/biodiversity}
54
+ s.rdoc_options = ["--charset=UTF-8"]
55
+ s.require_paths = ["lib"]
56
+ s.rubygems_version = %q{1.3.6}
57
+ s.summary = %q{Parser of scientific names}
58
+ s.test_files = [
59
+ "spec/biodiversity_spec.rb",
60
+ "spec/guid/lsid.spec.rb",
61
+ "spec/parser/scientific_name.spec.rb",
62
+ "spec/parser/scientific_name_canonical.spec.rb",
63
+ "spec/parser/scientific_name_clean.spec.rb",
64
+ "spec/parser/scientific_name_dirty.spec.rb",
65
+ "spec/parser/spec_helper.rb",
66
+ "spec/spec_helper.rb"
67
+ ]
68
+
69
+ if s.respond_to? :specification_version then
70
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
71
+ s.specification_version = 3
72
+
73
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
74
+ s.add_runtime_dependency(%q<treetop>, [">= 0"])
75
+ s.add_runtime_dependency(%q<json>, [">= 0"])
76
+ s.add_development_dependency(%q<rspec>, [">= 0"])
77
+ else
78
+ s.add_dependency(%q<treetop>, [">= 0"])
79
+ s.add_dependency(%q<json>, [">= 0"])
80
+ s.add_dependency(%q<rspec>, [">= 0"])
81
+ end
82
+ else
83
+ s.add_dependency(%q<treetop>, [">= 0"])
84
+ s.add_dependency(%q<json>, [">= 0"])
85
+ s.add_dependency(%q<rspec>, [">= 0"])
86
+ end
87
+ end
88
+
@@ -0,0 +1,3 @@
1
+
2
+ #Constants
3
+ LSID_RESOLVER_URL = "http://lsid.tdwg.org/"
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'treetop'
3
+
4
+ dir = File.dirname(__FILE__)
5
+
6
+ BIODIVERSITY_ROOT = File.join(dir, 'biodiversity')
7
+ require File.join(dir, "/../conf/environment")
8
+ require File.join(BIODIVERSITY_ROOT, "parser")
9
+ require File.join(BIODIVERSITY_ROOT, "guid")
@@ -0,0 +1,2 @@
1
+ dir = File.dirname(__FILE__)
2
+ require File.join(dir, *%w[guid lsid])
@@ -0,0 +1,18 @@
1
+ require 'open-uri'
2
+
3
+ class LsidResolver
4
+ def self.resolve(lsid)
5
+ http_get_rdf(lsid)
6
+ end
7
+
8
+ protected
9
+ def self.http_get_rdf(lsid)
10
+ rdf = ''
11
+ open(LSID_RESOLVER_URL + lsid) do |f|
12
+ f.each do |line|
13
+ rdf += line if !line.strip.blank?
14
+ end
15
+ end
16
+ rdf
17
+ end
18
+ end
@@ -0,0 +1,57 @@
1
+ # encoding: UTF-8
2
+ dir = File.dirname(__FILE__)
3
+ require File.join(dir, *%w[parser scientific_name_clean])
4
+ require File.join(dir, *%w[parser scientific_name_dirty])
5
+ require File.join(dir, *%w[parser scientific_name_canonical])
6
+ require 'rubygems'
7
+ require 'json'
8
+
9
+ class ScientificNameParser
10
+
11
+ def initialize
12
+ @verbatim = ''
13
+ @clean = ScientificNameCleanParser.new
14
+ @dirty = ScientificNameDirtyParser.new
15
+ @canonical = ScientificNameCanonicalParser.new
16
+ @parsed = nil
17
+ end
18
+
19
+ def parsed
20
+ @parsed
21
+ end
22
+
23
+ def parse(a_string)
24
+ @verbatim = a_string
25
+ @parsed = @clean.parse(a_string) || @dirty.parse(a_string) || @canonical.parse(a_string) || {:verbatim => a_string}
26
+ def @parsed.all
27
+ parsed = self.class != Hash
28
+ res = {:parsed => parsed}
29
+ if parsed
30
+ hybrid = self.hybrid rescue false
31
+ res.merge!({
32
+ :verbatim => self.text_value,
33
+ :normalized => self.value,
34
+ :canonical => self.canonical,
35
+ :hybrid => hybrid,
36
+ :details => self.details,
37
+ :positions => self.pos
38
+ })
39
+ else
40
+ res.merge!(self)
41
+ end
42
+ res = {:scientificName => res}
43
+ res
44
+ end
45
+
46
+ def @parsed.pos_json
47
+ self.pos.to_json rescue ''
48
+ end
49
+
50
+ def @parsed.all_json
51
+ self.all.to_json rescue ''
52
+ end
53
+
54
+ @parsed.all
55
+ end
56
+ end
57
+
@@ -0,0 +1,462 @@
1
+ # encoding: UTF-8
2
+ module ScientificNameCanonical
3
+ include Treetop::Runtime
4
+
5
+ def root
6
+ @root || :root
7
+ end
8
+
9
+ include ScientificNameClean
10
+
11
+ include ScientificNameDirty
12
+
13
+ module Root0
14
+ def hybrid
15
+ false
16
+ end
17
+
18
+ def details
19
+ [super]
20
+ end
21
+ end
22
+
23
+ module Root1
24
+ def hybrid
25
+ false
26
+ end
27
+
28
+ def details
29
+ [super]
30
+ end
31
+ end
32
+
33
+ def _nt_root
34
+ start_index = index
35
+ if node_cache[:root].has_key?(index)
36
+ cached = node_cache[:root][index]
37
+ @index = cached.interval.end if cached
38
+ return cached
39
+ end
40
+
41
+ i0 = index
42
+ r1 = _nt_multinomial_with_garbage
43
+ r1.extend(Root0)
44
+ if r1
45
+ r0 = r1
46
+ else
47
+ r2 = _nt_uninomial_with_garbage
48
+ r2.extend(Root1)
49
+ if r2
50
+ r0 = r2
51
+ else
52
+ @index = i0
53
+ r0 = nil
54
+ end
55
+ end
56
+
57
+ node_cache[:root][start_index] = r0
58
+
59
+ r0
60
+ end
61
+
62
+ module MultinomialWithGarbage0
63
+ def a
64
+ elements[0]
65
+ end
66
+
67
+ def space
68
+ elements[1]
69
+ end
70
+
71
+ def b
72
+ elements[2]
73
+ end
74
+
75
+ def space
76
+ elements[3]
77
+ end
78
+
79
+ def c
80
+ elements[4]
81
+ end
82
+
83
+ def garbage
84
+ elements[5]
85
+ end
86
+ end
87
+
88
+ module MultinomialWithGarbage1
89
+ def value
90
+ a.value + " " + b.value + " " + c.value
91
+ end
92
+
93
+ def canonical
94
+ a.canonical + " " + b.canonical + " " + c.canonical
95
+ end
96
+
97
+ def pos
98
+ a.pos.merge(b.pos).merge(c.pos)
99
+ end
100
+
101
+ def details
102
+ a.details.merge(b.details).merge(c.details)
103
+ end
104
+ end
105
+
106
+ module MultinomialWithGarbage2
107
+ def a
108
+ elements[0]
109
+ end
110
+
111
+ def space
112
+ elements[1]
113
+ end
114
+
115
+ def b
116
+ elements[2]
117
+ end
118
+
119
+ def garbage
120
+ elements[3]
121
+ end
122
+ end
123
+
124
+ module MultinomialWithGarbage3
125
+ def value
126
+ a.value + " " + b.value
127
+ end
128
+
129
+ def canonical
130
+ a.canonical + " " + b.canonical
131
+ end
132
+
133
+ def pos
134
+ a.pos.merge(b.pos)
135
+ end
136
+
137
+ def details
138
+ a.details.merge(b.details)
139
+ end
140
+ end
141
+
142
+ module MultinomialWithGarbage4
143
+ def a
144
+ elements[0]
145
+ end
146
+
147
+ def space
148
+ elements[1]
149
+ end
150
+
151
+ def b
152
+ elements[2]
153
+ end
154
+
155
+ def garbage
156
+ elements[3]
157
+ end
158
+ end
159
+
160
+ module MultinomialWithGarbage5
161
+ def value
162
+ a.value + " " + b.value
163
+ end
164
+
165
+ def canonical
166
+ a.canonical + " " + b.canonical
167
+ end
168
+
169
+ def pos
170
+ a.pos.merge(b.pos)
171
+ end
172
+
173
+ def details
174
+ a.details.merge(b.details)
175
+ end
176
+ end
177
+
178
+ def _nt_multinomial_with_garbage
179
+ start_index = index
180
+ if node_cache[:multinomial_with_garbage].has_key?(index)
181
+ cached = node_cache[:multinomial_with_garbage][index]
182
+ @index = cached.interval.end if cached
183
+ return cached
184
+ end
185
+
186
+ i0 = index
187
+ i1, s1 = index, []
188
+ r2 = _nt_genus
189
+ s1 << r2
190
+ if r2
191
+ r3 = _nt_space
192
+ s1 << r3
193
+ if r3
194
+ r4 = _nt_subgenus
195
+ s1 << r4
196
+ if r4
197
+ r5 = _nt_space
198
+ s1 << r5
199
+ if r5
200
+ r6 = _nt_species
201
+ s1 << r6
202
+ if r6
203
+ r7 = _nt_garbage
204
+ s1 << r7
205
+ end
206
+ end
207
+ end
208
+ end
209
+ end
210
+ if s1.last
211
+ r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
212
+ r1.extend(MultinomialWithGarbage0)
213
+ r1.extend(MultinomialWithGarbage1)
214
+ else
215
+ @index = i1
216
+ r1 = nil
217
+ end
218
+ if r1
219
+ r0 = r1
220
+ else
221
+ i8, s8 = index, []
222
+ r9 = _nt_genus
223
+ s8 << r9
224
+ if r9
225
+ r10 = _nt_space
226
+ s8 << r10
227
+ if r10
228
+ r11 = _nt_subgenus
229
+ s8 << r11
230
+ if r11
231
+ r12 = _nt_garbage
232
+ s8 << r12
233
+ end
234
+ end
235
+ end
236
+ if s8.last
237
+ r8 = instantiate_node(SyntaxNode,input, i8...index, s8)
238
+ r8.extend(MultinomialWithGarbage2)
239
+ r8.extend(MultinomialWithGarbage3)
240
+ else
241
+ @index = i8
242
+ r8 = nil
243
+ end
244
+ if r8
245
+ r0 = r8
246
+ else
247
+ i13, s13 = index, []
248
+ r14 = _nt_genus
249
+ s13 << r14
250
+ if r14
251
+ r15 = _nt_space
252
+ s13 << r15
253
+ if r15
254
+ r16 = _nt_species
255
+ s13 << r16
256
+ if r16
257
+ r17 = _nt_garbage
258
+ s13 << r17
259
+ end
260
+ end
261
+ end
262
+ if s13.last
263
+ r13 = instantiate_node(SyntaxNode,input, i13...index, s13)
264
+ r13.extend(MultinomialWithGarbage4)
265
+ r13.extend(MultinomialWithGarbage5)
266
+ else
267
+ @index = i13
268
+ r13 = nil
269
+ end
270
+ if r13
271
+ r0 = r13
272
+ else
273
+ @index = i0
274
+ r0 = nil
275
+ end
276
+ end
277
+ end
278
+
279
+ node_cache[:multinomial_with_garbage][start_index] = r0
280
+
281
+ r0
282
+ end
283
+
284
+ module UninomialWithGarbage0
285
+ def a
286
+ elements[0]
287
+ end
288
+
289
+ def b
290
+ elements[1]
291
+ end
292
+ end
293
+
294
+ module UninomialWithGarbage1
295
+ def value
296
+ a.value
297
+ end
298
+
299
+ def canonical
300
+ a.canonical
301
+ end
302
+
303
+ def pos
304
+ a.pos
305
+ end
306
+
307
+ def details
308
+ {:uninomial => a.details[:uninomial]}
309
+ end
310
+ end
311
+
312
+ def _nt_uninomial_with_garbage
313
+ start_index = index
314
+ if node_cache[:uninomial_with_garbage].has_key?(index)
315
+ cached = node_cache[:uninomial_with_garbage][index]
316
+ @index = cached.interval.end if cached
317
+ return cached
318
+ end
319
+
320
+ i0, s0 = index, []
321
+ r1 = _nt_uninomial_epitheton
322
+ s0 << r1
323
+ if r1
324
+ r2 = _nt_garbage
325
+ s0 << r2
326
+ end
327
+ if s0.last
328
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
329
+ r0.extend(UninomialWithGarbage0)
330
+ r0.extend(UninomialWithGarbage1)
331
+ else
332
+ @index = i0
333
+ r0 = nil
334
+ end
335
+
336
+ node_cache[:uninomial_with_garbage][start_index] = r0
337
+
338
+ r0
339
+ end
340
+
341
+ module Garbage0
342
+ def space
343
+ elements[0]
344
+ end
345
+
346
+ def space
347
+ elements[2]
348
+ end
349
+
350
+ end
351
+
352
+ module Garbage1
353
+ def space_hard
354
+ elements[0]
355
+ end
356
+
357
+ end
358
+
359
+ def _nt_garbage
360
+ start_index = index
361
+ if node_cache[:garbage].has_key?(index)
362
+ cached = node_cache[:garbage][index]
363
+ @index = cached.interval.end if cached
364
+ return cached
365
+ end
366
+
367
+ i0 = index
368
+ i1, s1 = index, []
369
+ r2 = _nt_space
370
+ s1 << r2
371
+ if r2
372
+ if has_terminal?('\G["\',.]', true, index)
373
+ r3 = instantiate_node(SyntaxNode,input, index...(index + 1))
374
+ @index += 1
375
+ else
376
+ r3 = nil
377
+ end
378
+ s1 << r3
379
+ if r3
380
+ r4 = _nt_space
381
+ s1 << r4
382
+ if r4
383
+ s5, i5 = [], index
384
+ loop do
385
+ if has_terminal?('\G[^щ]', true, index)
386
+ r6 = instantiate_node(SyntaxNode,input, index...(index + 1))
387
+ @index += 1
388
+ else
389
+ r6 = nil
390
+ end
391
+ if r6
392
+ s5 << r6
393
+ else
394
+ break
395
+ end
396
+ end
397
+ r5 = instantiate_node(SyntaxNode,input, i5...index, s5)
398
+ s1 << r5
399
+ end
400
+ end
401
+ end
402
+ if s1.last
403
+ r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
404
+ r1.extend(Garbage0)
405
+ else
406
+ @index = i1
407
+ r1 = nil
408
+ end
409
+ if r1
410
+ r0 = r1
411
+ else
412
+ i7, s7 = index, []
413
+ r8 = _nt_space_hard
414
+ s7 << r8
415
+ if r8
416
+ s9, i9 = [], index
417
+ loop do
418
+ if has_terminal?('\G[^ш]', true, index)
419
+ r10 = instantiate_node(SyntaxNode,input, index...(index + 1))
420
+ @index += 1
421
+ else
422
+ r10 = nil
423
+ end
424
+ if r10
425
+ s9 << r10
426
+ else
427
+ break
428
+ end
429
+ end
430
+ if s9.empty?
431
+ @index = i9
432
+ r9 = nil
433
+ else
434
+ r9 = instantiate_node(SyntaxNode,input, i9...index, s9)
435
+ end
436
+ s7 << r9
437
+ end
438
+ if s7.last
439
+ r7 = instantiate_node(SyntaxNode,input, i7...index, s7)
440
+ r7.extend(Garbage1)
441
+ else
442
+ @index = i7
443
+ r7 = nil
444
+ end
445
+ if r7
446
+ r0 = r7
447
+ else
448
+ @index = i0
449
+ r0 = nil
450
+ end
451
+ end
452
+
453
+ node_cache[:garbage][start_index] = r0
454
+
455
+ r0
456
+ end
457
+
458
+ end
459
+
460
+ class ScientificNameCanonicalParser < Treetop::Runtime::CompiledParser
461
+ include ScientificNameCanonical
462
+ end