Class: Scripref::Parser
- Inherits:
-
StringScanner
- Object
- StringScanner
- Scripref::Parser
- Includes:
- BasicMethods
- Defined in:
- lib/scripref/parser.rb
Constant Summary
Constants included from BasicMethods
Instance Attribute Summary collapse
-
#error ⇒ Object
readonly
Returns the value of attribute error.
Instance Method Summary collapse
- #abbrev2book(str) ⇒ Object
- #abbrev2num(str) ⇒ Object
-
#b1 ⇒ Object
try to parse first book.
-
#b2 ⇒ Object
try to parse second book.
-
#c1 ⇒ Object
try parse first chapter.
-
#c2 ⇒ Object
try to parse second chapter.
-
#cv_sep ⇒ Object
try to parse separator or chapter and verse.
-
#epsilon ⇒ Object
try to parse
end of string
. - #format_error ⇒ Object
- #give_up(msg) ⇒ Object
-
#hyphen ⇒ Object
try to parse hyphen.
- #init_str2book_num ⇒ Object
-
#initialize(*mods) ⇒ Parser
constructor
A new instance of Parser.
- #inspect ⇒ Object
-
#parse(str) ⇒ Object
(also: #<<)
Parsing a string of a scripture reference.
-
#pass_sep ⇒ Object
try to parse separator between passages.
- #push_passage ⇒ Object
-
#start ⇒ Object
start of parsing grammer.
- #str2book_num(str) ⇒ Object
-
#v1 ⇒ Object
try to parse first verse.
-
#v2 ⇒ Object
try to parse second verse.
-
#verse_addon ⇒ Object
try to parse addons for verses.
-
#verse_postfix ⇒ Object
try to parse postfixes for verse.
-
#verse_sep ⇒ Object
try to parse verse separator.
Methods included from BasicMethods
#book_re, #chapter_re, #verse_re
Constructor Details
#initialize(*mods) ⇒ Parser
14 15 16 17 |
# File 'lib/scripref/parser.rb', line 14 def initialize *mods @mods = mods mods.each {|m| extend m} end |
Instance Attribute Details
#error ⇒ Object (readonly)
Returns the value of attribute error.
9 10 11 |
# File 'lib/scripref/parser.rb', line 9 def error @error end |
Instance Method Details
#abbrev2book(str) ⇒ Object
246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'lib/scripref/parser.rb', line 246 def abbrev2book str s = str.strip s.sub! /\.$/, '' @books_str ||= ('#' << book_names.map(&:names).flatten.join('#') << '#') pattern = s.chars.map {|c| Regexp.escape(c) << '[^#]*'}.join re = /(?<=#)#{pattern}(?=#)/ names = @books_str.scan(re) uniq_numbers = names.map {|n| str2book_num(n)}.uniq if uniq_numbers.size != 1 unscan give_up format("Abbreviation %s is ambiguous it matches %s!", s, names.join(', ')) end names.first end |
#abbrev2num(str) ⇒ Object
240 241 242 243 244 |
# File 'lib/scripref/parser.rb', line 240 def abbrev2num str s = str.strip s.sub! /\.$/, '' str2book_num(s) or str2book_num(abbrev2book(s)) end |
#b1 ⇒ Object
try to parse first book
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/scripref/parser.rb', line 35 def b1 s = scan(book_re) or return nil @text << s @b1 = @b2 = abbrev2num(s) @c1 = @v1 = @c2 = @v2 = nil if pass_sep b1 or give_up 'EOS or book expected!' elsif check(Regexp.new(chapter_re.source + cv_sep_re.source)) @c1 = @v1 = nil @c2 = @v2 = nil c1 else if book_has_only_one_chapter?(@b1) @c1 = @c2 = 1 epsilon or (hyphen and b2) or v1 or give_up 'EOS or hyphen and book or verse expected!' else @c1 = @v1 = nil @c2 = @v2 = nil epsilon or (hyphen and b2) or c1 or give_up 'EOS or hyphen and book or chapter expected!' end end end |
#b2 ⇒ Object
try to parse second book
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/scripref/parser.rb', line 108 def b2 s = scan(book_re) or return nil @text << s @b2 = abbrev2num(s) @c2 = @v2 = nil if pass_sep b1 or give_up 'EOS or book expected!' elsif check(Regexp.new(chapter_re.source + cv_sep_re.source)) c2 else if book_has_only_one_chapter?(@b2) @c2 = 1 epsilon or v2 or give_up 'EOS or chapter or verse expected!' else epsilon or c2 or give_up 'EOS or chapter expected!' end end end |
#c1 ⇒ Object
try parse first chapter
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/scripref/parser.rb', line 60 def c1 s = scan(chapter_re) or return nil @text << s @c1 = @c2 = s.to_i @v1 = @v2 = nil if cv_sep v1 or give_up 'Verse expected!' elsif hyphen b2 or c2 or give_up 'Book or chapter expected!' elsif pass_sep b1 or c1 or give_up 'Book or chapter expected!' else epsilon or give_up 'EOS or chapter verse separator or hyphen and book or hyphen and chapter or passage separator and book or passage separator and chapter expected!' end end |
#c2 ⇒ Object
try to parse second chapter
129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/scripref/parser.rb', line 129 def c2 s = scan(chapter_re) or return nil @text << s @c2 = s.to_i if cv_sep v2 or give_up 'Verse expected!' elsif pass_sep b1 or c1 or give_up 'Book or chapter expected!' else epsilon or give_up 'EOS or chapter verse separator expected!' end end |
#cv_sep ⇒ Object
try to parse separator or chapter and verse
172 173 174 175 176 177 178 179 |
# File 'lib/scripref/parser.rb', line 172 def cv_sep if s = scan(cv_sep_re) @text << s s else nil end end |
#epsilon ⇒ Object
try to parse end of string
163 164 165 166 167 168 169 |
# File 'lib/scripref/parser.rb', line 163 def epsilon if eos? push_passage return @result end nil end |
#format_error ⇒ Object
289 290 291 292 293 294 295 |
# File 'lib/scripref/parser.rb', line 289 def format_error if error format("%s\n%s\n%s^", error, string, ' ' * pointer) else '' end end |
#give_up(msg) ⇒ Object
284 285 286 287 |
# File 'lib/scripref/parser.rb', line 284 def give_up msg @error = msg fail ParserError, format_error end |
#hyphen ⇒ Object
try to parse hyphen
182 183 184 185 186 187 188 189 |
# File 'lib/scripref/parser.rb', line 182 def hyphen if s = scan(hyphen_re) @text << s s else nil end end |
#init_str2book_num ⇒ Object
261 262 263 264 265 266 267 268 269 270 271 272 273 |
# File 'lib/scripref/parser.rb', line 261 def init_str2book_num unless @str2book_num @str2book_num = {} book_names.each_with_index do |bn, i| bn.names.each do |n| @str2book_num[n] = i+1 end bn.abbrevs.each do |n| @str2book_num[n] = i+1 end end end end |
#inspect ⇒ Object
280 281 282 |
# File 'lib/scripref/parser.rb', line 280 def inspect "#<#{self.class} #{@mods.inspect}>" end |
#parse(str) ⇒ Object Also known as: <<
Parsing a string of a scripture reference
21 22 23 24 25 26 |
# File 'lib/scripref/parser.rb', line 21 def parse str self.string = str @result = [] @error = nil start end |
#pass_sep ⇒ Object
try to parse separator between passages
192 193 194 195 196 197 198 199 200 |
# File 'lib/scripref/parser.rb', line 192 def pass_sep if s = scan(pass_sep_re) push_passage @result << PassSep.new(s) s else nil end end |
#push_passage ⇒ Object
234 235 236 237 238 |
# File 'lib/scripref/parser.rb', line 234 def push_passage @result << Passage.new(text: @text, b1: @b1, c1: @c1, v1: @v1, b2: @b2, c2: @c2, v2: @v2, a1: @a1, a2: @a2) @text = '' @a1 = @a2 = nil end |
#start ⇒ Object
start of parsing grammer
29 30 31 32 |
# File 'lib/scripref/parser.rb', line 29 def start @text = '' b1 or give_up 'Book expected!' end |
#str2book_num(str) ⇒ Object
275 276 277 278 |
# File 'lib/scripref/parser.rb', line 275 def str2book_num str init_str2book_num @str2book_num[str] end |
#v1 ⇒ Object
try to parse first verse
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/scripref/parser.rb', line 78 def v1 s = scan(verse_re) or return nil @text << s @v1 = @v2 = s.to_i if addon = verse_addon @a1 = addon end if postfix = verse_postfix @v2 = postfix end if hyphen b2 or ( if check(Regexp.new(chapter_re.source + cv_sep_re.source)) c2 else v2 or give_up 'Chapter or verse expected!' end) elsif pass_sep b1 or c1 or give_up 'Book or chapter expected!' elsif verse_sep v1 or give_up 'Verse expected!' else epsilon or give_up 'EOS or passage separator or verse separator or hyphen expected!' end end |
#v2 ⇒ Object
try to parse second verse
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/scripref/parser.rb', line 144 def v2 s = scan(verse_re) or return nil @text << s @v2 = s.to_i if addon = verse_addon @a2 = addon end if verse_sep v1 or give_up 'Verse expected!' elsif pass_sep b1 or c1 or give_up 'Book or chapter expected!' else epsilon or give_up 'EOS or verse separator or passage separator expected!' end end |
#verse_addon ⇒ Object
try to parse addons for verses
214 215 216 217 218 219 220 221 |
# File 'lib/scripref/parser.rb', line 214 def verse_addon if s = scan(verse_addon_re) @text << s s.to_sym else nil end end |
#verse_postfix ⇒ Object
try to parse postfixes for verse
224 225 226 227 228 229 230 231 232 |
# File 'lib/scripref/parser.rb', line 224 def verse_postfix s = (scan(postfix_one_following_verse_re) or scan(postfix_more_following_verses_re)) if s @text << s s.to_sym else nil end end |