Class: IREGEXP

Inherits:
Object
  • Object
show all
Defined in:
lib/iregexp.rb,
lib/writer/iregexp-writer.rb

Defined Under Namespace

Classes: ParseError

Constant Summary collapse

DATA_DIR =
Pathname.new(__FILE__) + "../../data/"
SAFE_FN =
/\A[-._a-zA-Z0-9]+\z/
TNR_MAP =
{"\t" => "\\t", "\n" => "\\n", "\r" => "\\r"}
CC_ESC_CHARS =
/\A[-\[\\\]]\z/
SEQ_ESC_CHARS =
/\A[()*+.?\[\\\]{|}]\z/
@@parser =
IREGEXPGRAMMARParser.new

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ast_) ⇒ IREGEXP

Returns a new instance of IREGEXP.



35
36
37
38
# File 'lib/iregexp.rb', line 35

def initialize(ast_)
  @ast = ast_
  @tree = ast.ast
end

Instance Attribute Details

#astObject

Returns the value of attribute ast.



34
35
36
# File 'lib/iregexp.rb', line 34

def ast
  @ast
end

#directivesObject

Returns the value of attribute directives.



34
35
36
# File 'lib/iregexp.rb', line 34

def directives
  @directives
end

#treeObject

Returns the value of attribute tree.



34
35
36
# File 'lib/iregexp.rb', line 34

def tree
  @tree
end

Class Method Details

.from_iregexp(s) ⇒ Object



24
25
26
27
28
29
30
31
32
# File 'lib/iregexp.rb', line 24

def self.from_iregexp(s)
  ast = @@parser.parse s
  if !ast
    fail ParseError.new(self.reason(@@parser, s))
  end
  ret = IREGEXP.new(ast)

  ret
end

.reason(parser, s) ⇒ Object



11
12
13
14
15
16
17
18
19
20
# File 'lib/iregexp.rb', line 11

def self.reason(parser, s)
  reason = [parser.failure_reason]
  parser.failure_reason =~ /^(Expected .+) after/m
  reason = ["#{$1.gsub("\n", '<<<NEWLINE>>>')}:"] if $1
  if line = s.lines.to_a[parser.failure_line - 1]
    reason << line
    reason << "#{'~' * (parser.failure_column - 1)}^"
  end
  reason.join("\n").gsub(/[\u0000-\u0009\u000b-\u001f\u007f]/) {|c| "\\u%04x" % c.ord}
end

Instance Method Details

#prec_check(inner, targetprec, prec, options) ⇒ Object

precedence: 0: | alt 1: seq 2: … occ dot pos neg - p P



10
11
12
13
14
15
16
17
# File 'lib/writer/iregexp-writer.rb', line 10

def prec_check(inner, targetprec, prec, options)
  lp, rp = options[:paren]
  if targetprec > prec
    "#{lp||"("}#{inner}#{rp||")"}"
  else
    inner
  end
end

#to_jsObject



88
89
90
# File 'lib/writer/iregexp-writer.rb', line 88

def to_js
  "^#{write_rhs(self.tree, 1, {paren: ["(?:", ")"], dot: "[^\\n\\r]"})}$"
end

#to_pcreObject



80
81
82
# File 'lib/writer/iregexp-writer.rb', line 80

def to_pcre
  "\\A#{write_rhs(self.tree, 1, {paren: ["(?:", ")"]})}\\z"
end

#to_regexpObject



84
85
86
# File 'lib/writer/iregexp-writer.rb', line 84

def to_regexp
  /#{to_pcre}/
end

#to_sObject



76
77
78
# File 'lib/writer/iregexp-writer.rb', line 76

def to_s
  write_rhs(self.tree)
end

#write_charclass(pn, chars) ⇒ Object



33
34
35
36
37
38
39
40
41
# File 'lib/writer/iregexp-writer.rb', line 33

def write_charclass(pn, chars)
  "[#{"^" if pn == "neg"}#{chars.map {|ch|
      case ch
        in String;              write_escape(ch, CC_ESC_CHARS)
        in ["-", l, r];         "#{write_escape(l, CC_ESC_CHARS)}-#{write_escape(r, CC_ESC_CHARS)}"
        in ["p"|"P", _cat];     write_rhs(ch)
      end
   }.join}]"
end

#write_escape(ch, esc, map = TNR_MAP) ⇒ Object



21
22
23
24
25
26
27
28
29
# File 'lib/writer/iregexp-writer.rb', line 21

def write_escape(ch, esc, map = TNR_MAP)
  if c1 = map[ch]
    c1
  elsif ch =~ esc
    "\\#{ch}"
  else
    ch
  end
end

#write_rhs(v, targetprec = 0, options = {}) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/writer/iregexp-writer.rb', line 45

def write_rhs(v, targetprec = 0, options = {})
  #    warn "** v = #{v.inspect}"
  prec, ret =
  case v
  in ["pos" | "neg", *chars]
    [2, write_charclass(v[0], chars)]
  in ["alt", *atoms]
    [0, atoms.map{write_rhs(_1, 1, options)}.join("|")]
  in ["seq", *atoms]
    [1, atoms.map{write_rhs(_1, 1, options)}.join]
  in ["rep", s, e, atom]
    occur = case [s, e]
            in [0, false];       "*"
            in [1, false];       "+"
            in [Integer, false]; "{#{s},}"
            in [0, 1];           "?"
            in [1, 1];           ""
            in [^s, ^s];         "{#{s}}"
            else;                "{#{s},#{e}}"
            end
    [1, "#{write_rhs(atom, 2, options)}#{occur}"]
  in ["dot"]
    [2, options[:dot] || "."]
  in ["p" | "P", cat]
    [2, "\\#{v[0]}{#{cat}}"]
  in String
    [2, write_escape(v, SEQ_ESC_CHARS)]                    # XXX esc!
  end
  prec_check(ret, targetprec, prec, options)
end