Module: Dense::Path::Parser

Includes:
Raabro
Defined in:
lib/dense/parser.rb

Constant Summary collapse

ENCODINGS =
{
'u' => 'UTF-8', 'e' => 'EUC-JP', 's' => 'Windows-31J', 'n' => 'ASCII-8BIT' }
R_ENCODINGS =
ENCODINGS
.inject({}) { |h, (k, v)| h[v] = k; h }

Instance Method Summary collapse

Instance Method Details

#bend(i) ⇒ Object



42
# File 'lib/dense/parser.rb', line 42

def bend(i); str(nil, i, ']'); end

#bindex(i) ⇒ Object



66
67
68
# File 'lib/dense/parser.rb', line 66

def bindex(i)
  alt(:index, i, :dqname, :sqname, :star, :ses, :rxnames, :name, :blank)
end

#bindexes(i) ⇒ Object



69
70
71
# File 'lib/dense/parser.rb', line 69

def bindexes(i)
  jseq(:bindexes, i, :bindex, :comma_or_semicolon)
end

#blank(i) ⇒ Object



44
# File 'lib/dense/parser.rb', line 44

def blank(i); str(:blank, i, ''); end

#bracket_index(i) ⇒ Object



79
# File 'lib/dense/parser.rb', line 79

def bracket_index(i); seq(nil, i, :bstart, :bindexes, :bend); end

#bstart(i) ⇒ Object



43
# File 'lib/dense/parser.rb', line 43

def bstart(i); str(nil, i, '['); end

#comma_or_semicolon(i) ⇒ Object



40
# File 'lib/dense/parser.rb', line 40

def comma_or_semicolon(i); rex(nil, i, / *[,;] */); end

#dot(i) ⇒ Object



39
# File 'lib/dense/parser.rb', line 39

def dot(i); str(nil, i, '.'); end

#dot_then_index(i) ⇒ Object



80
# File 'lib/dense/parser.rb', line 80

def dot_then_index(i); seq(nil, i, :dot, :simple_index); end

#dotdot(i) ⇒ Object



77
# File 'lib/dense/parser.rb', line 77

def dotdot(i); str(:dotdot, i, '.'); end

#dotdotstar(i) ⇒ Object



78
# File 'lib/dense/parser.rb', line 78

def dotdotstar(i); rex(:dotdotstar, i, /(\.\.\*|\.\[\*\])/); end

#dqname(i) ⇒ Object



17
18
19
20
21
22
23
24
25
26
# File 'lib/dense/parser.rb', line 17

def dqname(i)

  rex(:qname, i, %r{
    "(
      \\["\\\/bfnrt] |
      \\u[0-9a-fA-F]{4} |
      [^"\\\b\f\n\r\t]
    )*"
  }x)
end

#escape(i) ⇒ Object



64
# File 'lib/dense/parser.rb', line 64

def escape(i); rex(:esc, i, /\\[.*]/); end

#index(i) ⇒ Object



82
83
84
# File 'lib/dense/parser.rb', line 82

def index(i)
  alt(nil, i, :dot_then_index, :bracket_index, :dotdotstar, :dotdot)
end

#name(i) ⇒ Object



46
# File 'lib/dense/parser.rb', line 46

def name(i); rex(:name, i, /[-+%^<>a-zA-Z0-9_\/\\=?!]+/); end

#off(i) ⇒ Object



47
# File 'lib/dense/parser.rb', line 47

def off(i); rex(:off, i, /-?\d+(?=(\.|\[|\z))/); end

#path(i) ⇒ Object

it starts here



86
# File 'lib/dense/parser.rb', line 86

def path(i); rep(:path, i, :index, 1); end

#rewrite_bindexes(t) ⇒ Object



112
113
114
115
# File 'lib/dense/parser.rb', line 112

def rewrite_bindexes(t);
  indexes = t.subgather.collect { |tt| rewrite(tt) }
  indexes.length == 1 ? indexes[0] : indexes.compact
end

#rewrite_blank(t) ⇒ Object



117
# File 'lib/dense/parser.rb', line 117

def rewrite_blank(t); nil; end

#rewrite_dotdot(t) ⇒ Object



108
# File 'lib/dense/parser.rb', line 108

def rewrite_dotdot(t); :dot; end

#rewrite_dotdotstar(t) ⇒ Object



109
# File 'lib/dense/parser.rb', line 109

def rewrite_dotdotstar(t); :dotstar; end

#rewrite_esc(t) ⇒ Object



106
# File 'lib/dense/parser.rb', line 106

def rewrite_esc(t); t.string[1, 1]; end

#rewrite_index(t) ⇒ Object



111
# File 'lib/dense/parser.rb', line 111

def rewrite_index(t); rewrite(t.sublookup); end

#rewrite_name(t) ⇒ Object



144
# File 'lib/dense/parser.rb', line 144

def rewrite_name(t); t.string; end

#rewrite_off(t) ⇒ Object



110
# File 'lib/dense/parser.rb', line 110

def rewrite_off(t); t.string.to_i; end

#rewrite_path(t) ⇒ Object



146
147
148
149
150
151
152
153
154
155
156
# File 'lib/dense/parser.rb', line 146

def rewrite_path(t)

  t.subgather
    .collect { |tt|
      rewrite(tt) }
    .inject([]) { |a, e| # remove double :dot
      next (a << e) unless a.last == :dot
      a.pop if e == :dotstar
      a << e unless e == :dot
      a }
end

#rewrite_qname(t) ⇒ Object



143
# File 'lib/dense/parser.rb', line 143

def rewrite_qname(t); t.string[1..-2]; end

#rewrite_rxnames(t) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/dense/parser.rb', line 124

def rewrite_rxnames(t)

  m = t.string.match(/\A\/(.+)\/([imxuesn]*)\z/)

  s = m[1]

  e = ENCODINGS[(m[2].match(/[uesn]/) || [])[0]]
  #s = s.force_encoding(e) if e
  s = s.encode(e) if e

  flags = 0
  flags = flags | Regexp::EXTENDED if m[2].index('x')
  flags = flags | Regexp::IGNORECASE if m[2].index('i')
  #flags = flags | Regexp::MULTILINE if m[2].index('m')
  flags = flags | Regexp::FIXEDENCODING if e

  Regexp.new(s, flags)
end

#rewrite_ses(t) ⇒ Object

rewrite parsed tree



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/dense/parser.rb', line 90

def rewrite_ses(t)

  s = t.string

  if (a = s.split(',')).length == 2
    { start: a[0].to_i, count: a[1].to_i }
  else
    a = s.split(':').collect { |e| e.empty? ? nil : e.to_i }
    if a[1] == nil && a[2] == nil
      a[0]
    else
      { start: a[0], end: a[1], step: a[2] }
    end
  end
end

#rewrite_star(t) ⇒ Object



107
# File 'lib/dense/parser.rb', line 107

def rewrite_star(t); :star; end

#rxnames(i) ⇒ Object

piece parsers bottom to top



6
7
8
9
10
11
12
13
14
15
# File 'lib/dense/parser.rb', line 6

def rxnames(i)

  rex(:rxnames, i, %r{
    /(
      \\[\/bfnrt] |
      \\u[0-9a-fA-F]{4} |
      [^/\b\f\n\r\t]
    )*/[imxouesn]*
  }x)
end

#ses(i) ⇒ Object

start:end:step



52
53
54
55
56
57
58
59
60
61
62
# File 'lib/dense/parser.rb', line 52

def ses(i) # start:end:step
  rex(
    :ses,
    i,
    /(
      (-?\d+)?:(-?\d+)?:(-?\d+)? |
      (-?\d+)?:(-?\d+)? |
      (-?\d+)?,(\d+)? |
      -?\d+
    )/x)
end

#simple_index(i) ⇒ Object



73
74
75
# File 'lib/dense/parser.rb', line 73

def simple_index(i)
  alt(:index, i, :off, :escape, :star, :rxnames, :name)
end

#sqname(i) ⇒ Object



28
29
30
31
32
33
34
35
36
37
# File 'lib/dense/parser.rb', line 28

def sqname(i)

  rex(:qname, i, %r{
    '(
      \\['\\\/bfnrt] |
      \\u[0-9a-fA-F]{4} |
      [^'\\\b\f\n\r\t]
    )*'
  }x)
end

#star(i) ⇒ Object

positive lookahead so that “0_1_2” is not parsed as “0” and whatever…



50
# File 'lib/dense/parser.rb', line 50

def star(i); str(:star, i, '*'); end