Skip to content

Commit c1d2416

Browse files
committed
Merge pull request #55 from codalogic/ruby-abnf-extracter
Ruby ABNF extracter
2 parents 763a1bb + 9e18648 commit c1d2416

File tree

2 files changed

+157
-128
lines changed

2 files changed

+157
-128
lines changed

abnf/make-abnf.py

Lines changed: 0 additions & 128 deletions
This file was deleted.

abnf/make-abnf.rb

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# Copyright (C) 2014,2015 American Registry for Internet Numbers (ARIN)
2+
#
3+
# Permission to use, copy, modify, and/or distribute this software for any
4+
# purpose with or without fee is hereby granted, provided that the above
5+
# copyright notice and this permission notice appear in all copies.
6+
#
7+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8+
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9+
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10+
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11+
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12+
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
13+
# IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14+
15+
# Configuration
16+
$parslet_src_file = "../lib/jcr/parser.rb"
17+
$abnf_out_file = "jcr-abnf.txt"
18+
$margin = 0
19+
$indent = 19
20+
$keyword_indent = 30
21+
22+
# Primary data stores
23+
$mappings = {}
24+
$lines = []
25+
$keywords = {}
26+
27+
def main
28+
read_parslet_def
29+
write_abnf
30+
end
31+
32+
def read_parslet_def
33+
File.foreach( $parslet_src_file ) { |line|
34+
conditionally_grab_mapping( line )
35+
conditionally_grab_abnf( line )
36+
conditionally_grab_keywords( line )
37+
}
38+
end
39+
40+
def conditionally_grab_mapping( line )
41+
# Example haystack: #/ spcCmnt -> sp-cmt
42+
if m = %r|^\s*#/\s*([\w?]+)\s*->\s*(.*)|.match( line )
43+
key, value = m.captures
44+
$mappings[key] = value
45+
end
46+
end
47+
48+
def conditionally_grab_abnf( line )
49+
# Example haystack: #! spcCmnt = spaces / comment
50+
if m = /^\s*#!\s*(.*)/.match( line )
51+
$lines << m[1]
52+
end
53+
end
54+
55+
def conditionally_grab_keywords( line )
56+
# Example haystack: #> jcr-version-kw = "jcr-version"
57+
if m = /^\s*#>\s*([\w_\-]+kw)(\s*=\s*)"([^"]+)"/.match( line )
58+
name, equals, keyword = m.captures
59+
ascii_codes = keyword.chars.map{ |c| "%02X" % c.ord }.join( '.' )
60+
comment_padding = ' ' * [($keyword_indent - 3*keyword.length), 0].max
61+
line = name + equals + '%x' + ascii_codes + comment_padding + ' ; "' + keyword + '"'
62+
$keywords[name] = line
63+
end
64+
end
65+
66+
def write_abnf
67+
File.open( $abnf_out_file, 'w' ) { |fout|
68+
print_captured_abnf( fout )
69+
print_keywords( fout )
70+
print_referenced_rfc5234_rules( fout )
71+
}
72+
end
73+
74+
def print_captured_abnf( fout )
75+
for line in $lines
76+
line = do_name_mappings( line )
77+
pretty_print( line, fout )
78+
end
79+
end
80+
81+
def do_name_mappings( line )
82+
for mapping_from in mapping_keys_sorted_longest_first
83+
line.gsub!( mapping_from, $mappings[mapping_from] )
84+
end
85+
line.gsub!( '_', '-' )
86+
return line
87+
end
88+
89+
def mapping_keys_sorted_longest_first
90+
return $mappings.keys.sort_by { |m| m.length }.reverse
91+
end
92+
93+
def print_keywords( fout )
94+
pretty_print( '', fout )
95+
pretty_print( ';; Keywords', fout )
96+
for kw in $keywords.keys().sort
97+
pretty_print( $keywords[kw], fout )
98+
end
99+
end
100+
101+
def print_referenced_rfc5234_rules( fout )
102+
rfc5234_core_rules = [
103+
'ALPHA = %x41-5A / %x61-7A ; A-Z / a-z',
104+
'CR = %x0D ; carriage return',
105+
'DIGIT = %x30-39 ; 0-9',
106+
# 'DQUOTE = %x22 ; " (Double Quote)',
107+
'HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"',
108+
'HTAB = %x09 ; horizontal tab',
109+
'LF = %x0A ; linefeed',
110+
'SP = %x20 ; space',
111+
'WSP = SP / HTAB ; white space'
112+
]
113+
pretty_print( '', fout )
114+
pretty_print( ';; Referenced RFC 5234 Core Rules', fout )
115+
for rule in rfc5234_core_rules
116+
pretty_print( rule, fout )
117+
end
118+
end
119+
120+
def pretty_print( line, fout )
121+
if is_blank_line?( line )
122+
fout.write( "\n" )
123+
else
124+
fout.write( ' ' * $margin )
125+
if is_block_comment?( line )
126+
fout.write( line + "\n" )
127+
elsif comment = local_comment( line )
128+
fout.write( ' ' * $indent + comment + "\n" )
129+
elsif mapping = abnf_mapping( line )
130+
name, expansion = mapping
131+
equals = ' = '
132+
padding_needed = [ $indent - (name.length + equals.length), 0 ].max
133+
padding = ' ' * padding_needed
134+
fout.write( name + padding + equals + expansion + "\n" )
135+
else
136+
fout.write( ' ' * $indent + line + "\n" ) # A 2nd/3rd expression line
137+
end
138+
end
139+
end
140+
141+
def is_blank_line?( line )
142+
return /^\s*$/.match( line )
143+
end
144+
145+
def is_block_comment?( line )
146+
return /^\s*;;/.match( line )
147+
end
148+
149+
def local_comment( line )
150+
return (m = /^\s*(;.*)/.match( line )) ? m[1] : false
151+
end
152+
153+
def abnf_mapping( line )
154+
return (m = /([\w_\-]+)\s*=\s*(.*)/.match( line )) ? [m[1], m[2]] : false
155+
end
156+
157+
main

0 commit comments

Comments
 (0)