Class: RegexpTree

Inherits:
Object
  • Object
show all
Defined in:
lib/regexptree.rb

Direct Known Subclasses

Alt, Elt, Rep, Seq

Defined Under Namespace

Classes: Alt, CharClass, Elt, Paren, Rep, Seq, Special

Constant Summary collapse

EmptySet =
Alt.new([])
EmptySequence =
Seq.new([])

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.alt(*rs) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/regexptree.rb', line 139

def RegexpTree.alt(*rs)
  rs2 = []
  rs.each {|r|
    if r.empty_set?
      next
    elsif Alt === r
      rs2.concat r.rs
    elsif CharClass === r
      if CharClass === rs2.last
 rs2[-1] = CharClass.new(rs2.last.natset + r.natset)
	else
 rs2 << r
	end
    else
      rs2 << r
    end
  }
  case rs2.length
  when 0; EmptySet
  when 1; rs2.first
  else; Alt.new(rs2)
  end
end

.backref(n) ⇒ Object



465
# File 'lib/regexptree.rb', line 465

def RegexpTree.backref(n) Special.new("\\#{n}") end

.charclass(natset) ⇒ Object



346
347
348
349
350
351
352
# File 'lib/regexptree.rb', line 346

def RegexpTree.charclass(natset)
  if natset.empty?
    EmptySet
  else
    CharClass.new(natset)
  end
end

.inherited(c) ⇒ Object



63
64
65
66
67
# File 'lib/regexptree.rb', line 63

def RegexpTree.inherited(c)
  return if c.superclass != RegexpTree
  c.const_set(:Prec, @curr_prec)
  @curr_prec += 1
end

.linebegObject



457
# File 'lib/regexptree.rb', line 457

def RegexpTree.linebeg() Special.new('^') end

.lineendObject



458
# File 'lib/regexptree.rb', line 458

def RegexpTree.lineend() Special.new('$') end

.non_word_boundaryObject



463
# File 'lib/regexptree.rb', line 463

def RegexpTree.non_word_boundary() Special.new('\B') end

.previous_matchObject



464
# File 'lib/regexptree.rb', line 464

def RegexpTree.previous_match() Special.new('\G') end

.rep(r, m = 0, n = nil, greedy = true) ⇒ Object



280
281
282
283
284
285
286
287
288
# File 'lib/regexptree.rb', line 280

def RegexpTree.rep(r, m=0, n=nil, greedy=true)
  return EmptySequence if m == 0 && n == 0
  return r if m == 1 && n == 1
  return EmptySequence if r.empty_sequence?
  if r.empty_set?
    return m == 0 ? EmptySequence : EmptySet
  end
  Rep.new(r, m, n, greedy)
end

.seq(*rs) ⇒ Object



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/regexptree.rb', line 205

def RegexpTree.seq(*rs)
  rs2 = []
  rs.each {|r|
    if r.empty_sequence?
	next
    elsif Seq === r
	rs2.concat r.rs
    elsif r.empty_set?
      return EmptySet
    else
      rs2 << r
    end
  }
  case rs2.length
  when 0; EmptySequence
  when 1; rs2.first
  else; Seq.new(rs2)
  end
end

.str(str) ⇒ Object

def RegexpTree.comment(str) … end # (?#…)



523
524
525
526
527
528
529
# File 'lib/regexptree.rb', line 523

def RegexpTree.str(str)
  ccs = []
  str.each_byte {|ch|
    ccs << CharClass.new(NatSet.new(ch))
  }
  seq(*ccs)
end

.strbegObject



459
# File 'lib/regexptree.rb', line 459

def RegexpTree.strbeg() Special.new('\A') end

.strendObject



460
# File 'lib/regexptree.rb', line 460

def RegexpTree.strend() Special.new('\z') end

.strlineendObject



461
# File 'lib/regexptree.rb', line 461

def RegexpTree.strlineend() Special.new('\Z') end

.word_boundaryObject



462
# File 'lib/regexptree.rb', line 462

def RegexpTree.word_boundary() Special.new('\b') end

Instance Method Details

#*(n) ⇒ Object



259
260
261
262
263
264
265
266
267
268
# File 'lib/regexptree.rb', line 259

def *(n)
  case n
  when Integer
    RegexpTree.rep(self, n, n)
  when Range
    RegexpTree.rep(self, n.first, n.last - (n.exclude_end? ? 1 : 0))
  else
    raise TypeError.new("Integer or Range expected: #{n}")
  end
end

#+(other) ⇒ Object



202
203
204
# File 'lib/regexptree.rb', line 202

def +(other)
  RegexpTree.seq(self, other)
end

#closure(greedy = true) ⇒ Object



274
# File 'lib/regexptree.rb', line 274

def closure(greedy=true) RegexpTree.rep(self, 0, nil, greedy) end

#empty_sequence?Boolean

Returns:

  • (Boolean)


132
133
134
# File 'lib/regexptree.rb', line 132

def empty_sequence?
  false
end

#empty_set?Boolean

Returns:

  • (Boolean)


128
129
130
# File 'lib/regexptree.rb', line 128

def empty_set?
  false
end

#groupObject



488
# File 'lib/regexptree.rb', line 488

def group() Paren.new(self, '') end

#inspectObject



85
86
87
88
89
90
91
92
93
94
95
# File 'lib/regexptree.rb', line 85

def inspect
  case_insensitive = case_insensitive? ? "i" : ""
  r = PrettyPrint.singleline_format('') {|out|
 (case_insensitive ? self.downcase : self).pretty_format(out)
	}
  if %r{/} =~ r
    "%r{#{r}}#{case_insensitive}"
  else
    "%r/#{r}/#{case_insensitive}"
  end
end

#lookaheadObject



490
# File 'lib/regexptree.rb', line 490

def lookahead() Paren.new(self, '?=') end

#negative_lookaheadObject



491
# File 'lib/regexptree.rb', line 491

def negative_lookahead() Paren.new(self, '?!') end

#nongreedy_closureObject



269
# File 'lib/regexptree.rb', line 269

def nongreedy_closure() RegexpTree.rep(self, 0, nil, false) end

#nongreedy_ntimes(m, n = m) ⇒ Object



272
# File 'lib/regexptree.rb', line 272

def nongreedy_ntimes(m, n=m) RegexpTree.rep(self, m, n, false) end

#nongreedy_optionalObject



271
# File 'lib/regexptree.rb', line 271

def nongreedy_optional() RegexpTree.rep(self, 0, 1, false) end

#nongreedy_positive_closureObject



270
# File 'lib/regexptree.rb', line 270

def nongreedy_positive_closure() RegexpTree.rep(self, 1, nil, false) end

#nongreedy_rep(m = 0, n = nil) ⇒ Object



273
# File 'lib/regexptree.rb', line 273

def nongreedy_rep(m=0, n=nil) RegexpTree.rep(self, m, n, false) end

#ntimes(m, n = m, greedy = true) ⇒ Object



277
# File 'lib/regexptree.rb', line 277

def ntimes(m, n=m, greedy=true) RegexpTree.rep(self, m, n, greedy) end

#optional(greedy = true) ⇒ Object



276
# File 'lib/regexptree.rb', line 276

def optional(greedy=true) RegexpTree.rep(self, 0, 1, greedy) end

#parenObject



489
# File 'lib/regexptree.rb', line 489

def paren() Paren.new(self) end

#parenthesize(target) ⇒ Object



69
70
71
72
73
74
75
# File 'lib/regexptree.rb', line 69

def parenthesize(target)
  if target::Prec <= self.class::Prec
    self
  else
    Paren.new(self)
  end
end

#positive_closure(greedy = true) ⇒ Object



275
# File 'lib/regexptree.rb', line 275

def positive_closure(greedy=true) RegexpTree.rep(self, 1, nil, greedy) end

#pretty_print(pp) ⇒ Object



77
78
79
80
81
82
83
# File 'lib/regexptree.rb', line 77

def pretty_print(pp)
  case_insensitive = case_insensitive?
  pp.group(3, '%r{', '}x') {
    (case_insensitive ? self.downcase : self).pretty_format(pp)
  }
  pp.text 'i' if case_insensitive
end

#regexp(anchored = false) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/regexptree.rb', line 97

def regexp(anchored=false)
  if case_insensitive?
    r = downcase
    opt = Regexp::IGNORECASE
  else
    r = self
    opt = 0
  end
  r = RegexpTree.seq(RegexpTree.strbeg, r, RegexpTree.strend) if anchored
  Regexp.compile(
    PrettyPrint.singleline_format('') {|out|
	r.pretty_format(out)
    },
    opt)
end

#rep(m = 0, n = nil, greedy = true) ⇒ Object



278
# File 'lib/regexptree.rb', line 278

def rep(m=0, n=nil, greedy=true) RegexpTree.rep(self, m, n, greedy) end

#to_sObject



113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/regexptree.rb', line 113

def to_s
  PrettyPrint.singleline_format('') {|out|
    # x flag is not required because all whitespaces are escaped.
    if case_insensitive?
	out.text '(?i-m:'
	downcase.pretty_format(out)
	out.text ')'
    else
	out.text '(?-im:'
	pretty_format(out)
	out.text ')'
    end
  }
end

#|(other) ⇒ Object



136
137
138
# File 'lib/regexptree.rb', line 136

def |(other)
  RegexpTree.alt(self, other)
end