abnf-parser 0.8.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/lib/abnf/parser.rb +23 -25
  3. data/lib/abnf/parser/common.rb +63 -0
  4. data/lib/abnf/parser/compiler.rb +73 -33
  5. data/lib/abnf/parser/compiler/alternation.rb +54 -0
  6. data/lib/abnf/parser/compiler/concatenation.rb +55 -0
  7. data/lib/abnf/parser/compiler/element.rb +87 -0
  8. data/lib/abnf/parser/compiler/group.rb +19 -0
  9. data/lib/abnf/parser/compiler/option.rb +19 -0
  10. data/lib/abnf/parser/compiler/repetition.rb +50 -0
  11. data/lib/abnf/parser/compiler/rule_builder.rb +32 -0
  12. data/lib/abnf/parser/compiler/rule_list.rb +67 -0
  13. data/lib/abnf/parser/compiler/token.rb +34 -0
  14. data/lib/abnf/parser/compiler/tokenizer.rb +95 -0
  15. data/lib/abnf/parser/controls.rb +5 -3
  16. data/lib/abnf/parser/controls/abnf.rb +237 -0
  17. data/lib/abnf/parser/controls/compiler/tokens.rb +97 -0
  18. data/lib/abnf/parser/controls/nodes.rb +113 -0
  19. data/lib/abnf/parser/controls/rule_lists.rb +63 -0
  20. data/lib/abnf/parser/controls/rule_lists/multiples_of_three.rb +146 -0
  21. data/lib/abnf/parser/controls/rules.rb +40 -17
  22. data/lib/abnf/parser/{errors.rb → error.rb} +0 -2
  23. data/lib/abnf/parser/node.rb +138 -0
  24. data/lib/abnf/parser/rule_list.rb +50 -11
  25. data/lib/abnf/parser/rules/alternation.rb +38 -0
  26. data/lib/abnf/parser/rules/concatenation.rb +36 -0
  27. data/lib/abnf/parser/rules/prose_val.rb +18 -0
  28. data/lib/abnf/parser/rules/reference.rb +22 -0
  29. data/lib/abnf/parser/rules/regexp_pattern.rb +35 -0
  30. data/lib/abnf/parser/rules/repetition.rb +46 -0
  31. data/lib/abnf/parser/rules/terminal.rb +63 -0
  32. metadata +31 -31
  33. data/lib/abnf/parser/ast.rb +0 -67
  34. data/lib/abnf/parser/controls/ast.rb +0 -28
  35. data/lib/abnf/parser/controls/grammar.rb +0 -32
  36. data/lib/abnf/parser/controls/text_stream.rb +0 -15
  37. data/lib/abnf/parser/grammar.rb +0 -17
  38. data/lib/abnf/parser/grammar/alternative.rb +0 -27
  39. data/lib/abnf/parser/grammar/char_val.rb +0 -15
  40. data/lib/abnf/parser/grammar/concatenation.rb +0 -21
  41. data/lib/abnf/parser/grammar/element.rb +0 -57
  42. data/lib/abnf/parser/grammar/num_val.rb +0 -72
  43. data/lib/abnf/parser/grammar/prose_val.rb +0 -15
  44. data/lib/abnf/parser/grammar/repetition.rb +0 -58
  45. data/lib/abnf/parser/grammar/rule.rb +0 -31
  46. data/lib/abnf/parser/grammar/rulename.rb +0 -15
  47. data/lib/abnf/parser/rule.rb +0 -10
  48. data/lib/abnf/parser/rule/alternative.rb +0 -43
  49. data/lib/abnf/parser/rule/concatenation.rb +0 -29
  50. data/lib/abnf/parser/rule/none.rb +0 -17
  51. data/lib/abnf/parser/rule/optional.rb +0 -24
  52. data/lib/abnf/parser/rule/reference.rb +0 -19
  53. data/lib/abnf/parser/rule/repetition.rb +0 -41
  54. data/lib/abnf/parser/rule/terminal_value.rb +0 -32
  55. data/lib/abnf/parser/rule/value_range.rb +0 -33
  56. data/lib/abnf/parser/rule_list/entry.rb +0 -21
  57. data/lib/abnf/parser/text_stream.rb +0 -67
@@ -0,0 +1,19 @@
1
+ module ABNF
2
+ module Parser
3
+ class Compiler
4
+ class Group < RuleBuilder
5
+ attr_accessor :rule
6
+
7
+ def group_stop _
8
+ compiler.pop rule
9
+ end
10
+
11
+ def start_rule token
12
+ compiler.push Alternation do |rule|
13
+ self.rule = rule
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module ABNF
2
+ module Parser
3
+ class Compiler
4
+ class Option < RuleBuilder
5
+ attr_accessor :rule
6
+
7
+ def option_stop _
8
+ compiler.pop rule
9
+ end
10
+
11
+ def start_rule token
12
+ compiler.push Alternation do |rule|
13
+ self.rule = rule
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,50 @@
1
+ module ABNF
2
+ module Parser
3
+ class Compiler
4
+ class Repetition < RuleBuilder
5
+ attr_writer :abnf
6
+ attr_accessor :element
7
+ attr_accessor :range
8
+
9
+ def abnf
10
+ @abnf ||= ''
11
+ end
12
+
13
+ def finished element
14
+ abnf << element.abnf
15
+
16
+ if range
17
+ rule = Rules::Repetition.new element, range, abnf
18
+ else
19
+ rule = element
20
+ end
21
+
22
+ compiler.pop rule
23
+ end
24
+
25
+ def repeat_exact token
26
+ number = token.lexeme.to_i
27
+
28
+ self.abnf = token.abnf
29
+ self.range = (number..number)
30
+ end
31
+
32
+ def repeat_range token
33
+ minimum, maximum = token.lexeme.split '*'
34
+
35
+ if minimum then minimum = minimum.to_i else minimum = 0 end
36
+ if maximum then maximum = maximum.to_i else maximum = Float::INFINITY end
37
+
38
+ self.abnf = token.abnf
39
+ self.range = (minimum..maximum)
40
+ end
41
+
42
+ def start_rule token
43
+ compiler.push Element do |element|
44
+ finished element
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,32 @@
1
+ module ABNF
2
+ module Parser
3
+ class Compiler
4
+ class RuleBuilder
5
+ attr_reader :compiler
6
+
7
+ def initialize compiler
8
+ @compiler = compiler
9
+ end
10
+
11
+ def call token
12
+ send token.underscore_type, token
13
+ end
14
+
15
+ def start_rule token
16
+ fail
17
+ end
18
+
19
+ %i(
20
+ prose_val hex_val_range hex_val_sequence dec_val_range
21
+ dec_val_sequence bin_val_range bin_val_sequence char_val group_start
22
+ option_start repeat_range repeat_exact rulename
23
+ ).each do |token_type|
24
+ define_method token_type do |token|
25
+ start_rule token
26
+ compiler.handle token
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,67 @@
1
+ module ABNF
2
+ module Parser
3
+ class Compiler
4
+ class RuleList < RuleBuilder
5
+ attr_accessor :rulename
6
+
7
+ def c_nl token
8
+ end
9
+
10
+ def coerce_alternation rule
11
+ if rule.is_a? Rules::Alternation
12
+ rule
13
+ else
14
+ Rules::Alternation.new [rule], rule.abnf
15
+ end
16
+ end
17
+
18
+ def handle_rule name, rule
19
+ actual_rule = rule.inner_rule
20
+
21
+ if rule.operator == '=/'
22
+ original_rule = coerce_alternation rule_list[name]
23
+ new_rule = coerce_alternation actual_rule
24
+
25
+ alternatives = original_rule.alternatives + new_rule.alternatives
26
+ abnf = alternatives.map &:abnf
27
+ abnf *= ' / '
28
+ actual_rule = Rules::Alternation.new alternatives, abnf
29
+ end
30
+
31
+ rule_list[name] = actual_rule
32
+ end
33
+
34
+ def rule_list
35
+ compiler.rule_list
36
+ end
37
+
38
+ def rulename token
39
+ rulename = token.lexeme
40
+
41
+ compiler.push Rule do |rule|
42
+ handle_rule rulename, rule
43
+ end
44
+ end
45
+
46
+ class Rule < RuleBuilder
47
+ attr_accessor :operator
48
+ attr_accessor :inner_rule
49
+
50
+ def c_wsp _
51
+ end
52
+
53
+ def defined_as token
54
+ self.operator = token.lexeme
55
+ end
56
+
57
+ def start_rule token
58
+ compiler.push Alternation do |rule|
59
+ self.inner_rule = rule
60
+ compiler.pop self
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,34 @@
1
+ module ABNF
2
+ module Parser
3
+ class Compiler
4
+ class Token
5
+ attr_reader :abnf
6
+ attr_reader :type
7
+
8
+ def initialize type, abnf=nil
9
+ @abnf = abnf
10
+ @type = type
11
+ end
12
+
13
+ def == other_token
14
+ return false unless other_token.respond_to? :abnf
15
+ return false unless other_token.respond_to? :type
16
+
17
+ self.abnf == other_token.abnf and self.type == other_token.type
18
+ end
19
+
20
+ def lexeme
21
+ abnf
22
+ end
23
+
24
+ def inspect
25
+ "(#{type} #{abnf.inspect})"
26
+ end
27
+
28
+ def underscore_type
29
+ @underscore_type ||= type.downcase.gsub('-', '_')
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,95 @@
1
+ module ABNF
2
+ module Parser
3
+ class Compiler
4
+ class Tokenizer
5
+ C_NL = "(?:;[[:graph:][:blank:]]*)?\\r\\n".freeze
6
+ C_WSP = '(?:(?:#{C_NL})?[[:blank:]])'.freeze
7
+
8
+ attr_reader :abnf
9
+
10
+ def initialize abnf
11
+ @abnf = abnf
12
+ end
13
+
14
+ def self.build abnf
15
+ new abnf.dup
16
+ end
17
+
18
+ def self.call abnf
19
+ instance = build abnf
20
+ instance.()
21
+ end
22
+
23
+ def apply regexp
24
+ match_data = regexp.match abnf
25
+ return if match_data.nil? or not match_data.pre_match.empty?
26
+ abnf.slice! 0, match_data.to_s.size
27
+ match_data
28
+ end
29
+
30
+ def call &block
31
+ tokens = []
32
+
33
+ each do |token|
34
+ tokens << token
35
+ end
36
+
37
+ tokens
38
+ end
39
+
40
+ def each &block
41
+ until abnf.empty?
42
+ length = abnf.bytesize
43
+
44
+ token = self.next
45
+ block.(token) if block
46
+
47
+ fail "Parse error" unless abnf.bytesize < length
48
+ end
49
+ end
50
+
51
+ def next
52
+ possible_tokens.each do |type, regexp|
53
+ match_data = apply regexp
54
+ next unless match_data
55
+
56
+ token = Token.new type, match_data.to_s
57
+ return token
58
+ end
59
+
60
+ nil
61
+ end
62
+
63
+ def possible_tokens
64
+ @@possible_tokens ||= {
65
+ 'prose-val'.freeze => %r{\A<[\x20-\x3D\x3F-\x7E]*>}n,
66
+ 'hex-val-RANGE'.freeze => %r{\A%x[[:xdigit:]]+-[[:xdigit:]]+}n,
67
+ 'hex-val-SEQUENCE'.freeze => %r{\A%x[[:xdigit:]]+(?:\.[[:xdigit:]]+)*}n,
68
+ 'dec-val-RANGE'.freeze => %r{\A%d[[:digit:]]+-[[:digit:]]+}n,
69
+ 'dec-val-SEQUENCE'.freeze => %r{\A%d[[:digit:]]+(?:\.[[:digit:]]+)*}n,
70
+ 'bin-val-RANGE'.freeze => %r{\A%b[01]+-[01]+}n,
71
+ 'bin-val-SEQUENCE'.freeze => %r{\A%b[01]+(?:\.[01]+)*}n,
72
+ 'char-val'.freeze => %r{\A"[\x20-\x21\x23-\x7E]*"}n,
73
+ 'option-START'.freeze => %r{\A\[#{C_WSP}*}n,
74
+ 'option-STOP'.freeze => %r{\A#{C_WSP}*\]}n,
75
+ 'group-START'.freeze => %r{\A\(#{C_WSP}*}n,
76
+ 'group-STOP'.freeze => %r{\A#{C_WSP}*\)}n,
77
+ 'repeat-RANGE'.freeze => %r{\A[[:digit:]]*\*[[:digit:]]*}n,
78
+ 'repeat-EXACT'.freeze => %r{\A[[:digit:]]+}n,
79
+ 'alternation-SLASH'.freeze => %r{\A#{C_WSP}*/#{C_WSP}*}n,
80
+ 'defined-as'.freeze => %r{\A#{C_WSP}*=/?#{C_WSP}*}n,
81
+ 'rulename'.freeze => %r{\A[[:alpha:]][-[:alnum:]]*}n,
82
+ 'c-wsp'.freeze => %r{\A(?:(?:#{C_NL})?[[:blank:]])+}n,
83
+ 'c-nl'.freeze => %r{\A#{C_NL}}n,
84
+ }
85
+ end
86
+
87
+ def to_enum
88
+ Enumerator::Lazy.new self do |yielder, token|
89
+ yielder << token
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -1,4 +1,6 @@
1
- require 'abnf/parser/controls/ast'
2
- require 'abnf/parser/controls/grammar'
1
+ require 'abnf/parser/controls/abnf'
2
+ require 'abnf/parser/controls/nodes'
3
+ require 'abnf/parser/controls/rule_lists'
4
+ require 'abnf/parser/controls/rule_lists/multiples_of_three'
3
5
  require 'abnf/parser/controls/rules'
4
- require 'abnf/parser/controls/text_stream'
6
+ require 'abnf/parser/controls/compiler/tokens'
@@ -0,0 +1,237 @@
1
+ module ABNF
2
+ module Parser
3
+ module Controls
4
+ module ABNF
5
+ extend self
6
+
7
+ def alternation
8
+ %{#{ABNF.foo} / #{ABNF.bar} / #{ABNF.baz}}
9
+ end
10
+
11
+ def bar
12
+ '%x62.61.72'
13
+ end
14
+
15
+ def baz
16
+ '%x62.61.7A'
17
+ end
18
+
19
+ def concatenation
20
+ %{"[" #{foo} "]"}
21
+ end
22
+
23
+ def foo
24
+ '%x66.6F.6F'
25
+ end
26
+ alias_method :terminal, :foo
27
+
28
+ def foobar
29
+ '%x66.6F.6F.62.61.72'
30
+ end
31
+
32
+ def example
33
+ '(1*ALPHA "-" 1*ALPHA) / "~"'
34
+ end
35
+ alias_method :regexp_pattern, :example
36
+
37
+ def recursion
38
+ <<-ABNF
39
+ s0 = n0 s0 / n1 s2 / n2 s1 / ""\r
40
+ s1 = n0 s1 / n1 s0 / n2 s2\r
41
+ s2 = n0 s2 / n1 s1 / n2 s0\r
42
+ n0 = "0" / "3" / "6" / "9"\r
43
+ n1 = "1" / "4" / "7"\r
44
+ n2 = "2" / "5" / "8"\r
45
+ ABNF
46
+ end
47
+
48
+ def rfc5234
49
+ @rfc5234 ||= <<-ABNF
50
+ rulelist = 1*( rule / (*c-wsp c-nl) )\r
51
+ \r
52
+ rule = rulename defined-as elements c-nl\r
53
+ ; continues if next line starts\r
54
+ ; with white space\r
55
+ \r
56
+ rulename = ALPHA *(ALPHA / DIGIT / "-")\r
57
+ \r
58
+ defined-as = *c-wsp ("=" / "=/") *c-wsp\r
59
+ ; basic rules definition and\r
60
+ ; incremental alternatives\r
61
+ \r
62
+ elements = alternation *c-wsp\r
63
+ \r
64
+ c-wsp = WSP / (c-nl WSP)\r
65
+ \r
66
+ c-nl = comment / CRLF\r
67
+ ; comment or newline\r
68
+ \r
69
+ comment = ";" *(WSP / VCHAR) CRLF\r
70
+ \r
71
+ alternation = concatenation\r
72
+ *(*c-wsp "/" *c-wsp concatenation)\r
73
+ \r
74
+ concatenation = repetition *(1*c-wsp repetition)\r
75
+ \r
76
+ repetition = [repeat] element\r
77
+ \r
78
+ repeat = 1*DIGIT / (*DIGIT "*" *DIGIT)\r
79
+ \r
80
+ element = rulename / group / option /\r
81
+ char-val / num-val / prose-val\r
82
+ \r
83
+ group = "(" *c-wsp alternation *c-wsp ")"\r
84
+ \r
85
+ option = "[" *c-wsp alternation *c-wsp "]"\r
86
+ \r
87
+ char-val = DQUOTE *(%x20-21 / %x23-7E) DQUOTE\r
88
+ ; quoted string of SP and VCHAR\r
89
+ ; without DQUOTE\r
90
+ \r
91
+ num-val = "%" (bin-val / dec-val / hex-val)\r
92
+ \r
93
+ bin-val = "b" 1*BIT\r
94
+ [ 1*("." 1*BIT) / ("-" 1*BIT) ]\r
95
+ ; series of concatenated bit values\r
96
+ ; or single ONEOF range\r
97
+ \r
98
+ dec-val = "d" 1*DIGIT\r
99
+ [ 1*("." 1*DIGIT) / ("-" 1*DIGIT) ]\r
100
+ \r
101
+ hex-val = "x" 1*HEXDIG\r
102
+ [ 1*("." 1*HEXDIG) / ("-" 1*HEXDIG) ]\r
103
+ \r
104
+ prose-val = "<" *(%x20-3D / %x3F-7E) ">"\r
105
+ ; bracketed string of SP and VCHAR\r
106
+ ; without angles\r
107
+ ; prose description, to be used as\r
108
+ ; last resort\r
109
+ ABNF
110
+ end
111
+
112
+ def rfc7230
113
+ @rfc7230 ||= <<-ABNF
114
+ BWS = OWS\r
115
+ \r
116
+ Connection = *( "," OWS ) connection-option *( OWS "," [ OWS\r
117
+ connection-option ] )\r
118
+ \r
119
+ Content-Length = 1*DIGIT\r
120
+ \r
121
+ HTTP-message = start-line *( header-field CRLF ) CRLF [ message-body\r
122
+ ]\r
123
+ HTTP-name = %x48.54.54.50 ; HTTP\r
124
+ HTTP-version = HTTP-name "/" DIGIT "." DIGIT\r
125
+ Host = uri-host [ ":" port ]\r
126
+ \r
127
+ OWS = *( SP / HTAB )\r
128
+ \r
129
+ RWS = 1*( SP / HTAB )\r
130
+ \r
131
+ TE = [ ( "," / t-codings ) *( OWS "," [ OWS t-codings ] ) ]\r
132
+ Trailer = *( "," OWS ) field-name *( OWS "," [ OWS field-name ] )\r
133
+ Transfer-Encoding = *( "," OWS ) transfer-coding *( OWS "," [ OWS\r
134
+ transfer-coding ] )\r
135
+ \r
136
+ URI-reference = <URI-reference, see [RFC3986], Section 4.1>\r
137
+ Upgrade = *( "," OWS ) protocol *( OWS "," [ OWS protocol ] )\r
138
+ \r
139
+ Via = *( "," OWS ) ( received-protocol RWS received-by [ RWS comment\r
140
+ ] ) *( OWS "," [ OWS ( received-protocol RWS received-by [ RWS\r
141
+ comment ] ) ] )\r
142
+ \r
143
+ absolute-URI = <absolute-URI, see [RFC3986], Section 4.3>\r
144
+ absolute-form = absolute-URI\r
145
+ absolute-path = 1*( "/" segment )\r
146
+ asterisk-form = "*"\r
147
+ authority = <authority, see [RFC3986], Section 3.2>\r
148
+ authority-form = authority\r
149
+ \r
150
+ chunk = chunk-size [ chunk-ext ] CRLF chunk-data CRLF\r
151
+ chunk-data = 1*OCTET\r
152
+ chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-val ] )\r
153
+ chunk-ext-name = token\r
154
+ chunk-ext-val = token / quoted-string\r
155
+ chunk-size = 1*HEXDIG\r
156
+ chunked-body = *chunk last-chunk trailer-part CRLF\r
157
+ comment = "(" *( ctext / quoted-pair / comment ) ")"\r
158
+ connection-option = token\r
159
+ ctext = HTAB / SP / %x21-27 ; '!'-'''\r
160
+ / %x2A-5B ; '*'-'['\r
161
+ / %x5D-7E ; ']'-'~'\r
162
+ / obs-text\r
163
+ \r
164
+ field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]\r
165
+ field-name = token\r
166
+ field-value = *( field-content / obs-fold )\r
167
+ field-vchar = VCHAR / obs-text\r
168
+ fragment = <fragment, see [RFC3986], Section 3.5>\r
169
+ \r
170
+ header-field = field-name ":" OWS field-value OWS\r
171
+ http-URI = "http://" authority path-abempty [ "?" query ] [ "#"\r
172
+ fragment ]\r
173
+ https-URI = "https://" authority path-abempty [ "?" query ] [ "#"\r
174
+ fragment ]\r
175
+ \r
176
+ last-chunk = 1*"0" [ chunk-ext ] CRLF\r
177
+ \r
178
+ message-body = *OCTET\r
179
+ method = token\r
180
+ \r
181
+ obs-fold = CRLF 1*( SP / HTAB )\r
182
+ obs-text = %x80-FF\r
183
+ origin-form = absolute-path [ "?" query ]\r
184
+ \r
185
+ partial-URI = relative-part [ "?" query ]\r
186
+ path-abempty = <path-abempty, see [RFC3986], Section 3.3>\r
187
+ port = <port, see [RFC3986], Section 3.2.3>\r
188
+ protocol = protocol-name [ "/" protocol-version ]\r
189
+ protocol-name = token\r
190
+ protocol-version = token\r
191
+ pseudonym = token\r
192
+ \r
193
+ qdtext = HTAB / SP / "!" / %x23-5B ; '#'-'['\r
194
+ / %x5D-7E ; ']'-'~'\r
195
+ / obs-text\r
196
+ query = <query, see [RFC3986], Section 3.4>\r
197
+ quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )\r
198
+ \r
199
+ quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE\r
200
+ \r
201
+ rank = ( "0" [ "." *3DIGIT ] ) / ( "1" [ "." *3"0" ] )\r
202
+ reason-phrase = *( HTAB / SP / VCHAR / obs-text )\r
203
+ received-by = ( uri-host [ ":" port ] ) / pseudonym\r
204
+ received-protocol = [ protocol-name "/" ] protocol-version\r
205
+ relative-part = <relative-part, see [RFC3986], Section 4.2>\r
206
+ request-line = method SP request-target SP HTTP-version CRLF\r
207
+ request-target = origin-form / absolute-form / authority-form /\r
208
+ asterisk-form\r
209
+ \r
210
+ scheme = <scheme, see [RFC3986], Section 3.1>\r
211
+ segment = <segment, see [RFC3986], Section 3.3>\r
212
+ start-line = request-line / status-line\r
213
+ status-code = 3DIGIT\r
214
+ status-line = HTTP-version SP status-code SP reason-phrase CRLF\r
215
+ \r
216
+ t-codings = "trailers" / ( transfer-coding [ t-ranking ] )\r
217
+ t-ranking = OWS ";" OWS "q=" rank\r
218
+ tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /\r
219
+ "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA\r
220
+ token = 1*tchar\r
221
+ trailer-part = *( header-field CRLF )\r
222
+ transfer-coding = "chunked" / "compress" / "deflate" / "gzip" /\r
223
+ transfer-extension\r
224
+ transfer-extension = token *( OWS ";" OWS transfer-parameter )\r
225
+ transfer-parameter = token BWS "=" BWS ( token / quoted-string )\r
226
+ \r
227
+ uri-host = <host, see [RFC3986], Section 3.2.2>\r
228
+ ABNF
229
+ end
230
+
231
+ def rule
232
+ "some-rule = #{foo}\r\n"
233
+ end
234
+ end
235
+ end
236
+ end
237
+ end