Skip to content

Instantly share code, notes, and snippets.

@mat813
Created April 24, 2012 15:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mat813/2480722 to your computer and use it in GitHub Desktop.
Save mat813/2480722 to your computer and use it in GitHub Desktop.
simple named.conf parsing
require 'ip'
grammar BindConf
include IP
rule entries
(zone / key / server)* {
%w(zone key server).each do |i|
module_eval <<-eot, __FILE__, __LINE__+1
def each_#{i}(&block)
elements.each {|e| yield(e.content) if e.extension_modules.include?(BindConf::#{i.capitalize}0)}
end
eot
end
include Enumerable
def each(&block)
elements.each {|e| yield(e.content)}
end
def content
elements.map {|e| e.content}
end
}
end
rule server
'server' SPACES server:CIDR SPACE '{' SPACE
c:server_content
'}' SEMICOLON {
def content
[:server, server.content, c.content]
end
}
end
rule server_content
(server_keys)+ {
def content
Hash[elements.map(&:content)]
end
}
end
rule server_keys
'keys' SPACE '{' SPACE keys:(string SEMICOLON)* '}' SEMICOLON {
def content
[:keys, keys.elements.map {|e| e.string.content}]
end
}
end
rule key
'key' SPACES key:string SPACE '{' SPACE
c:key_content
'}' SEMICOLON {
def content
[:key, key.content, c.content]
end
}
end
rule key_content
(key_algorighm / key_secret)+ {
def content
Hash[elements.map(&:content)]
end
}
end
rule key_algorighm
'algorithm' SPACE a:string SEMICOLON {
def content
[:algorithm, a.content]
end
}
end
rule key_secret
'secret' SPACES s:string SEMICOLON {
def content
[:secret, s.content]
end
}
end
rule zone
'zone' SPACES zone:string SPACE '{' SPACE
c:zone_content
'}' SEMICOLON {
def content
[:zone, zone.content, c.content]
end
}
end
rule zone_content
(
zone_type
/ zone_notify
/ zone_file
/ zone_masters
)* {
def content
Hash[elements.map(&:content)]
end
}
end
rule zone_notify
'notify' SPACES yn:('yes' / 'no') SEMICOLON {
def content
[:notify, yn.text_value == 'yes']
end
}
end
rule zone_file
'file' SPACES f:string SEMICOLON {
def content
[:file, f.content]
end
}
end
rule zone_type
'type' SPACES t:('master' / 'slave') SEMICOLON {
def content
[:type, t.text_value]
end
}
end
rule zone_masters
'masters' SPACE '{' SPACE masters:(IP SEMICOLON)+ '}' SEMICOLON {
def content
[:masters, masters.elements.map {|e| e.IP.content}]
end
}
end
rule CIDR
(IPv4address / IPv6address) ('/' [0-9]+)? {
require 'ipaddr'
def content
IPAddr.new(text_value)
end
}
end
rule IP
(IPv4address / IPv6address) {
require 'ipaddr'
def content
IPAddr.new(text_value)
end
}
end
# content is taken care of by each string type.
rule string
unquoted_string / quoted_string
end
rule unquoted_string
(![ \t\r\n;"}] .)+ {
def content
text_value
end
}
end
rule quoted_string
'"' s:('\"' / !'"' .)* '"' {
def content
s.text_value
end
}
end
rule nsemicolon
SPACE (!';' .)
end
rule SEMICOLON
SPACE ';' SPACE
end
rule SPACES
[ \t\n\r]+
end
rule SPACE
[ \t\n\r]*
end
end
#!/usr/bin/env tt
#
# Author:: Iñaki Baz Castillo <ibc@aliax.net>
# Copyright:: 2008 Iñaki Baz Castillo
# License:: Public Domain
#
# ABNF syntax for IPv4 and IPv6 is defined in Appendix A of RFC 3986:
# http://tools.ietf.org/html/rfc3986#appendix-A
grammar IP
rule IPv4address
DIGIT DIGIT? DIGIT? '.' DIGIT DIGIT? DIGIT? '.' DIGIT DIGIT? DIGIT? '.' DIGIT DIGIT? DIGIT?
end
rule IPv6address
( h16 ':' h16 ':' h16 ':' h16 ':' h16 ':' h16 ':' ls32 )
/ ( '::' h16 ':' h16 ':' h16 ':' h16 ':' h16 ':' ls32 )
/ ( h16? '::' h16 ':' h16 ':' h16 ':' h16 ':' ls32 )
/ ( ( '::' / h16 '::' / h16 ':' h16 '::' ) h16 ':' h16 ':' h16 ':' ls32 )
/ ( ( '::' / h16 '::' / h16 ':' h16 '::' / h16 ':' h16 ':' h16 '::' ) h16 ':' h16 ':' ls32 )
/ ( ( '::' / h16 '::' / h16 ':' h16 '::' / h16 ':' h16 ':' h16 '::' / h16 ':' h16 ':' h16 ':' h16 '::' ) h16 ':' ls32 )
/ ( ( '::' / h16 '::' / h16 ':' h16 '::' / h16 ':' h16 ':' h16 '::' / h16 ':' h16 ':' h16 ':' h16 '::' / h16 ':' h16 ':' h16 ':' h16 ':' h16 '::' ) ls32 )
/ ( ( '::' / h16 '::' / h16 ':' h16 '::' / h16 ':' h16 ':' h16 '::' / h16 ':' h16 ':' h16 ':' h16 '::' / h16 ':' h16 ':' h16 ':' h16 ':' h16 '::' / h16 ':' h16 ':' h16 ':' h16 ':' h16 ':' h16 '::' ) h16 )
/ ( '::' / h16 '::' / h16 ':' h16 '::' / h16 ':' h16 ':' h16 '::' / h16 ':' h16 ':' h16 ':' h16 '::' / h16 ':' h16 ':' h16 ':' h16 ':' h16 '::' / h16 ':' h16 ':' h16 ':' h16 ':' h16 ':' h16 '::' / h16 ':' h16 ':' h16 ':' h16 ':' h16 ':' h16 ':' h16 '::' )
end
rule h16
HEXDIG HEXDIG? HEXDIG? HEXDIG?
end
rule ls32
( h16 ":" h16 ) / IPv4address
end
rule HEXDIG
[\x30-\x39a-fA-F]
end
rule DIGIT
[\x30-\x39]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment