Class: Bind9mgr::Parser
- Inherits:
-
Object
- Object
- Bind9mgr::Parser
- Defined in:
- lib/parser.rb
Overview
SOA, MX, TXT, SRV - are different
Instance Attribute Summary collapse
-
#result ⇒ Object
we can set appropriate Zone instance here.
-
#state ⇒ Object
readonly
Returns the value of attribute state.
Instance Method Summary collapse
-
#initialize ⇒ Parser
constructor
A new instance of Parser.
- #parse(str) ⇒ Object
Constructor Details
#initialize ⇒ Parser
Returns a new instance of Parser.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/parser.rb', line 9 def initialize @state = :start @result = Zone.new @SHARED_RULES = { :txt => Proc.new{ |t| t == 'TXT' ? update_last_rr(nil, nil, nil, t, nil) : false }, :mx => Proc.new{ |t| t == 'MX' ? update_last_rr(nil, nil, nil, t, nil) : false }, :srv => Proc.new{ |t| t == 'SRV' ? update_last_rr(nil, nil, nil, t, nil) : false } } @STATE_RULES = # [current_state, target_state, proc to perform(token will be passe in) [ [:start, :origin, Proc.new{ |t| t == '$ORIGIN' }], [:start, :ttl, Proc.new{ |t| t == '$TTL' }], [:origin, :last_token_in_a_row, Proc.new{ |t| set_origin t }], [:ttl, :last_token_in_a_row, Proc.new{ |t| set_ttl t }], [:last_token_in_a_row, :start, Proc.new{ |t| t == "\n" ? true : false }], [:owner, :rttl, Proc.new{ |t| t.match(/^\d+$/) ? update_last_rr(nil, t, nil, nil, nil) : false }], [:owner, :klass, Proc.new{ |t| KLASSES.include?(t) ? update_last_rr(nil, nil, t, nil, nil) : false }], [:owner, :type, Proc.new{ |t| TYPES.include?(t) ? update_last_rr(nil, nil, nil, t, nil) : false }], [:owner, :mx, @SHARED_RULES[:mx]], [:owner, :srv, @SHARED_RULES[:srv]], [:owner, :txt, @SHARED_RULES[:txt]], [:rttl, :klass, Proc.new{ |t| KLASSES.include?(t) ? update_last_rr(nil, nil, t, nil, nil) : false }], [:rttl, :txt, @SHARED_RULES[:txt]], [:rttl, :srv, @SHARED_RULES[:srv]], [:klass, :mx, @SHARED_RULES[:mx]], [:klass, :txt, @SHARED_RULES[:txt]], [:klass, :srv, @SHARED_RULES[:srv]], [:klass, :type, Proc.new{ |t| TYPES.include?(t) ? update_last_rr(nil, nil, nil, t, nil) : false }], [:klass, :soa, Proc.new{ |t| t == 'SOA' ? update_last_rr(nil, nil, nil, t, nil) : false }], [:type, :last_token_in_a_row, Proc.new{ |t| update_last_rr(nil, nil, nil, nil, t) }], [:start, :type, Proc.new{ |t| TYPES.include?(t) ? add_rr(nil, nil, nil, t, nil) : false }], [:start, :klass, Proc.new{ |t| KLASSES.include?(t) ? add_rr(nil, nil, t, nil, nil) : false }], [:start, :rttl, Proc.new{ |t| (t.match(/^\d+$/) && !@tokens.first.match(/^\d+$/) ) ? add_rr(nil, t, nil, nil, nil) : false }], [:start, :srv, @SHARED_RULES[:srv]], [:start, :txt, @SHARED_RULES[:txt]], [:start, :owner, Proc.new{ |t| add_rr(t, nil, nil, nil, nil) }], [:soa, :last_token_in_a_row, Proc.new{ |t| rdata = [t] + @tokens.shift(@tokens.index(')')) rdata.select!{|tt| tt != "\n" } raise ParserError, "Zone parsing error: parentices expected in SOA record.\n#{@content}" if (rdata[2] != '(') || (@tokens.first != ')') rdata.delete_at(2) @result.[:support_email] = rdata[1] @result.[:serial] = rdata[2] @result.[:refresh] = rdata[3] @result.[:retry] = rdata[4] @result.[:expiry] = rdata[5] @result.[:default_ttl] = rdata[6] update_last_rr(nil, nil, nil, nil, rdata) @tokens.shift }], [:mx, :last_token_in_a_row, Proc.new{ |t| update_last_rr(nil, nil, nil, nil, [t] + [@tokens.shift]) }], [:srv, :last_token_in_a_row, Proc.new{ |t| update_last_rr(nil, nil, nil, nil, [t] + [@tokens.shift(3)]) }], [:txt, :last_token_in_a_row, Proc.new{ |t| update_last_rr(nil, nil, nil, nil, ([t] + [@tokens.shift(@tokens.index("\n"))]).join(" ")) }] # '\t' symbol is lost here! may be a BUG ] end |
Instance Attribute Details
#result ⇒ Object
we can set appropriate Zone instance here
7 8 9 |
# File 'lib/parser.rb', line 7 def result @result end |
#state ⇒ Object (readonly)
Returns the value of attribute state.
6 7 8 |
# File 'lib/parser.rb', line 6 def state @state end |
Instance Method Details
#parse(str) ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/parser.rb', line 67 def parse str @content = str # for debugging @tokens = tokenize( str ) # puts @tokens.inspect cntr = 0 while @tokens.size > 0 token = @tokens.shift # puts "state: #{@state}, token: #{token}" possible_edges = @STATE_RULES.select{|arr|arr[0] == @state } raise( ParserError, "no possible_edges. cur_state: #{@state}" ) if possible_edges.count < 1 flag = false while ( possible_edges.count > 0 ) && flag == false current_edge = possible_edges.shift flag = current_edge[2].call(token) # ( puts " succ: #{@state} -> #{current_edge[1]}"; @state = current_edge[1] ) if flag # ( puts " fail: #{@state} -> #{current_edge[1]}" ) unless flag @state = current_edge[1] if flag end raise( ParserError, "no successful rules found. cur_state: #{@state}, token: #{token}, next tokens: #{@tokens.inspect}" ) unless flag cntr += 1 end cntr # returning performed rules count. just for fun end |