ebnf 2.1.2 → 2.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f58817e075b6100c10ce82eb2da850a71aa9ff76c8d1c359d819720c89477564
4
- data.tar.gz: 67fb9fc3ae589ae8ab49fef81a5703958635e7b3f8169ccc8df2d17e57c62074
3
+ metadata.gz: d3b1d692ce9936bb68c8c89722a06b90b7cfd6c42231ff57d49780a98214a325
4
+ data.tar.gz: da6430584d824a1d070d364879c17b0b3b0bd8c9b32b44af841cd039e153e7f6
5
5
  SHA512:
6
- metadata.gz: 13874b6745062e294d15176bba4c482ccdc32974a2733429cb1bc23eb87f608ae6e2deeba4e972bdf236629783c3443d7c8461c90e0db4fc6ef6b39d2564582c
7
- data.tar.gz: 172c8fa0efc03357f845cabff8d06fb11260cd271cb5a084350f8f432beef8d560cc285cef6ab87f4526d5331d8c4c433ae2b9536e108d2a4e0a7bd522a3292b
6
+ metadata.gz: 4e0bacbdef9b82ecca13fca9babcf8fe643acb3afaad077b05aebfc237f542859a1e6bea67e6b2e776c2e81b51dd7900cd24e39d9712582de6959d5e65ecfa42
7
+ data.tar.gz: 3001f1864c2cf8fade2856fb7d3383f4b1ac8519d2914e54cc55b8a461f6f208d41c3fa35539367bad104a74068cc868220255ce933f301894530eacb0abf51e
data/README.md CHANGED
@@ -3,8 +3,9 @@
3
3
  [EBNF][] parser and generic parser generator.
4
4
 
5
5
  [![Gem Version](https://badge.fury.io/rb/ebnf.png)](https://badge.fury.io/rb/ebnf)
6
- [![Build Status](https://secure.travis-ci.org/dryruby/ebnf.png?branch=master)](https://travis-ci.org/dryruby/ebnf)
7
- [![Coverage Status](https://coveralls.io/repos/dryruby/ebnf/badge.svg)](https://coveralls.io/r/dryruby/ebnf)
6
+ [![Build Status](https://github.com/dryruby/ebnf/workflows/CI/badge.svg?branch=develop)](https://github.com/dryruby/ebnf/actions?query=workflow%3ACI)
7
+ [![Coverage Status](https://coveralls.io/repos/dryruby/ebnf/badge.svg?branch=develop)](https://coveralls.io/r/dryruby/ebnf?branch=develop)
8
+ [![Gitter chat](https://badges.gitter.im/ruby-rdf/rdf.png)](https://gitter.im/ruby-rdf/rdf)
8
9
 
9
10
  ## Description
10
11
  This is a [Ruby][] implementation of an [EBNF][] and [BNF][] parser and parser generator.
@@ -92,7 +93,7 @@ Inevitably while implementing a parser for some specific grammar, a developer wi
92
93
 
93
94
  The {EBNF::Writer} class can be used to write parsed grammars out, either as formatted text, or HTML. Because grammars are written from the Abstract Syntax Tree, represented as [S-Expressions][S-Expression], this provides a means of transforming between grammar formats (e.g., W3C [EBNF][] to [ABNF][]), although with some potential loss in semantic fidelity (case-insensitive string matching vs. case-sensitive matching).
94
95
 
95
- The formatted HTML results are designed to be appropriate for including in specifications.
96
+ The formatted HTML results are designed to be appropriate for including in specifications. If the [Nokogumbo](https://rubygems.org/gems/nokogumbo) gem list available, the resulting HTML encoded grammar will also be validated.
96
97
 
97
98
  ### Parser Errors
98
99
  On a parsing failure, and exception is raised with information that may be useful in determining the source of the error.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.1.2
1
+ 2.1.3
data/bin/ebnf CHANGED
@@ -34,7 +34,7 @@ OPT_ARGS = [
34
34
  ["--prefix", "-p", GetoptLong::REQUIRED_ARGUMENT,"Prefix to use when generating Turtle"],
35
35
  ["--progress", "-v", GetoptLong::NO_ARGUMENT, "Detail on execution"],
36
36
  ["--renumber", GetoptLong::NO_ARGUMENT, "Renumber parsed reules"],
37
- ["--validate", GetoptLong::NO_ARGUMENT, "Validate grammar"],
37
+ ["--validate", GetoptLong::NO_ARGUMENT, "Validate grammar and any generated HTML"],
38
38
  ["--help", "-?", GetoptLong::NO_ARGUMENT, "This message"]
39
39
  ]
40
40
  def usage
@@ -67,7 +67,7 @@ opts.each do |opt, arg|
67
67
  end
68
68
  options[:format] = arg.to_sym
69
69
  when '--format'
70
- unless %w(abnf abnfh ebnf html isoebnf isoebnfh rb sxp).include?(arg)
70
+ unless %w(abnf abnfh ebnf html isoebnf isoebnfh rb sxp ttl).include?(arg)
71
71
  STDERR.puts("unrecognized output format #{arg}")
72
72
  usage
73
73
  end
@@ -99,11 +99,11 @@ ebnf.renumber! if options[:renumber]
99
99
 
100
100
  res = case options[:output_format]
101
101
  when :abnf then ebnf.to_s(format: :abnf)
102
- when :abnfh then ebnf.to_html(format: :abnf)
102
+ when :abnfh then ebnf.to_html(format: :abnf, validate: options[:validate])
103
103
  when :ebnf then ebnf.to_s
104
- when :html then ebnf.to_html
104
+ when :html then ebnf.to_html(validate: options[:validate])
105
105
  when :isoebnf then ebnf.to_s(format: :isoebnf)
106
- when :isoebnfh then ebnf.to_html(format: :isoebnf)
106
+ when :isoebnfh then ebnf.to_html(format: :isoebnf, validate: options[:validate])
107
107
  when :sxp then ebnf.to_sxp
108
108
  when :ttl then ebnf.to_ttl(options[:prefix], options[:namespace])
109
109
  when :rb then ebnf.to_ruby(out, grammarFile: ARGV[0], **options)
data/etc/doap.ttl CHANGED
@@ -12,7 +12,7 @@
12
12
  doap:name "ebnf" ;
13
13
  doap:homepage <https://github.com/dryruby/ebnf> ;
14
14
  doap:license <https://unlicense.org/1.0/> ;
15
- doap:shortdesc "EBNF parser and parser generator"@en ;
15
+ doap:shortdesc "EBNF parser and parser generator in Ruby."@en ;
16
16
  doap:description "EBNF is a Ruby parser for W3C EBNF and a parser generator for PEG and LL(1). Also includes parsing modes for ISO EBNF and ABNF."@en ;
17
17
  doap:created "2011-08-29"^^xsd:date ;
18
18
  doap:programming-language "Ruby" ;
@@ -34,7 +34,4 @@
34
34
  doap:maintainer <https://greggkellogg.net/foaf#me> ;
35
35
  doap:documenter <https://greggkellogg.net/foaf#me> ;
36
36
  foaf:maker <https://greggkellogg.net/foaf#me> ;
37
- dc:title "ebnf" ;
38
- dc:description "EBNF is a Ruby parser for W3C EBNF and a parser generator for PEG and LL(1). Also includes parsing modes for ISO EBNF and ABNF."@en ;
39
- dc:date "2011-08-29"^^xsd:date ;
40
37
  dc:creator <https://greggkellogg.net/foaf#me> .
data/etc/ebnf.html CHANGED
@@ -11,7 +11,7 @@
11
11
  <td>[2]</td>
12
12
  <td><code>declaration</code></td>
13
13
  <td>::=</td>
14
- <td>"@terminals" <code>|</code> <a href="#grammar-production-pass">pass</a></td>
14
+ <td>&quot;@terminals&quot; <code>|</code> <a href="#grammar-production-pass">pass</a></td>
15
15
  </tr>
16
16
  <tr id="grammar-production-rule">
17
17
  <td>[3]</td>
@@ -53,61 +53,24 @@
53
53
  <td>[9]</td>
54
54
  <td><code>primary</code></td>
55
55
  <td>::=</td>
56
- <td><a href="#grammar-production-HEX">HEX</a></td>
57
- </tr>
58
- <tr>
59
- <td>[9]</td>
60
- <td><code></code></td>
61
- <td>|</td>
62
- <td><a href="#grammar-production-SYMBOL">SYMBOL</a></td>
63
- </tr>
64
- <tr>
65
- <td>[9]</td>
66
- <td><code></code></td>
67
- <td>|</td>
68
- <td><a href="#grammar-production-O_RANGE">O_RANGE</a></td>
69
- </tr>
70
- <tr>
71
- <td>[9]</td>
72
- <td><code></code></td>
73
- <td>|</td>
74
- <td><a href="#grammar-production-RANGE">RANGE</a></td>
75
- </tr>
76
- <tr>
77
- <td>[9]</td>
78
- <td><code></code></td>
79
- <td>|</td>
80
- <td><a href="#grammar-production-STRING1">STRING1</a></td>
81
- </tr>
82
- <tr>
83
- <td>[9]</td>
84
- <td><code></code></td>
85
- <td>|</td>
86
- <td><a href="#grammar-production-STRING2">STRING2</a></td>
87
- </tr>
88
- <tr>
89
- <td>[9]</td>
90
- <td><code></code></td>
91
- <td>|</td>
92
- <td><code>(</code> "<code class="grammar-literal">(</code>" <a href="#grammar-production-expression">expression</a> "<code class="grammar-literal">)</code>"<code>)</code> </td>
56
+ <td><a href="#grammar-production-HEX">HEX</a> <code>|</code> <a href="#grammar-production-SYMBOL">SYMBOL</a> <code>|</code> <a href="#grammar-production-O_RANGE">O_RANGE</a> <code>|</code> <a href="#grammar-production-RANGE">RANGE</a> <code>|</code> <a href="#grammar-production-STRING1">STRING1</a> <code>|</code> <a href="#grammar-production-STRING2">STRING2</a> <code>|</code> <code>(</code> "<code class="grammar-literal">(</code>" <a href="#grammar-production-expression">expression</a> "<code class="grammar-literal">)</code>"<code>)</code> </td>
93
57
  </tr>
94
58
  <tr id="grammar-production-pass">
95
59
  <td>[10]</td>
96
60
  <td><code>pass</code></td>
97
61
  <td>::=</td>
98
- <td>"@pass" <a href="#grammar-production-expression">expression</a></td>
62
+ <td>&quot;@pass&quot; <a href="#grammar-production-expression">expression</a></td>
99
63
  </tr>
100
- <tr id="grammar-production-">
101
- <td>@terminals</td>
102
- <td><code></code></td>
64
+ <tr>
65
+ <td colspan=2>@terminals</td>
103
66
  <td></td>
104
- <td><strong>Productions for terminals</strong></td>
67
+ <td><strong># Productions for terminals</strong></td>
105
68
  </tr>
106
69
  <tr id="grammar-production-LHS">
107
70
  <td>[11]</td>
108
71
  <td><code>LHS</code></td>
109
72
  <td>::=</td>
110
- <td><code>(</code> "<code class="grammar-literal">[</code>" <a href="#grammar-production-SYMBOL">SYMBOL</a> "<code class="grammar-literal">]</code>" <code class="grammar-char-escape"><abbr title="space">#x20</abbr></code><code>+</code> <code>)</code> <code>?</code> <a href="#grammar-production-SYMBOL">SYMBOL</a> <code class="grammar-char-escape"><abbr title="space">#x20</abbr></code><code>*</code> "::="</td>
73
+ <td><code>(</code> "<code class="grammar-literal">[</code>" <a href="#grammar-production-SYMBOL">SYMBOL</a> "<code class="grammar-literal">]</code>" <code class="grammar-char-escape"><abbr title="space">#x20</abbr></code><code>+</code> <code>)</code> <code>?</code> <a href="#grammar-production-SYMBOL">SYMBOL</a> <code class="grammar-char-escape"><abbr title="space">#x20</abbr></code><code>*</code> &quot;::=&quot;</td>
111
74
  </tr>
112
75
  <tr id="grammar-production-SYMBOL">
113
76
  <td>[12]</td>
@@ -119,91 +82,37 @@
119
82
  <td>[13]</td>
120
83
  <td><code>HEX</code></td>
121
84
  <td>::=</td>
122
- <td>"#x" <code>(</code> <code>[</code> <code class="grammar-literal">a-f</code><code>]</code> <code>|</code> <code>[</code> <code class="grammar-literal">A-F</code><code>]</code> <code>|</code> <code>[</code> <code class="grammar-literal">0-9</code><code>]</code> <code>)</code> <code>+</code> </td>
85
+ <td>&quot;#x&quot; <code>(</code> <code>[</code> <code class="grammar-literal">a-f</code><code>]</code> <code>|</code> <code>[</code> <code class="grammar-literal">A-F</code><code>]</code> <code>|</code> <code>[</code> <code class="grammar-literal">0-9</code><code>]</code> <code>)</code> <code>+</code> </td>
123
86
  </tr>
124
87
  <tr id="grammar-production-RANGE">
125
88
  <td>[14]</td>
126
89
  <td><code>RANGE</code></td>
127
90
  <td>::=</td>
128
- <td>"<code class="grammar-literal">[</code>"</td>
129
- </tr>
130
- <tr id="grammar-production-">
131
- <td>[14]</td>
132
- <td><code></code></td>
133
- <td></td>
134
- <td><code>(</code> <code>(</code> <a href="#grammar-production-R_CHAR">R_CHAR</a> "<code class="grammar-literal">-</code>" <a href="#grammar-production-R_CHAR">R_CHAR</a><code>)</code><code>(</code> <a href="#grammar-production-HEX">HEX</a> "<code class="grammar-literal">-</code>" <a href="#grammar-production-HEX">HEX</a><code>)</code> <code>|</code> <a href="#grammar-production-R_CHAR">R_CHAR</a> <code>|</code> <a href="#grammar-production-HEX">HEX</a><code>)</code> <code>+</code></td>
135
- </tr>
136
- <tr id="grammar-production-">
137
- <td>[14]</td>
138
- <td><code></code></td>
139
- <td></td>
140
- <td>"<code class="grammar-literal">-</code>"<code>?</code></td>
141
- </tr>
142
- <tr id="grammar-production-">
143
- <td>[14]</td>
144
- <td><code></code></td>
145
- <td></td>
146
- <td><code>(</code> "<code class="grammar-literal">]</code>" <code>-</code> <a href="#grammar-production-LHS">LHS</a><code>)</code> </td>
91
+ <td>"<code class="grammar-literal">[</code>" <code>(</code> <code>(</code> <a href="#grammar-production-R_CHAR">R_CHAR</a> "<code class="grammar-literal">-</code>" <a href="#grammar-production-R_CHAR">R_CHAR</a><code>)</code> <code>|</code> <code>(</code> <a href="#grammar-production-HEX">HEX</a> "<code class="grammar-literal">-</code>" <a href="#grammar-production-HEX">HEX</a><code>)</code> <code>|</code> <a href="#grammar-production-R_CHAR">R_CHAR</a> <code>|</code> <a href="#grammar-production-HEX">HEX</a><code>)</code> <code>+</code> "<code class="grammar-literal">-</code>"<code>?</code> <code>(</code> "<code class="grammar-literal">]</code>" <code>-</code> <a href="#grammar-production-LHS">LHS</a><code>)</code> </td>
147
92
  </tr>
148
93
  <tr id="grammar-production-O_RANGE">
149
94
  <td>[15]</td>
150
95
  <td><code>O_RANGE</code></td>
151
96
  <td>::=</td>
152
- <td>"[^"</td>
153
- </tr>
154
- <tr id="grammar-production-">
155
- <td>[15]</td>
156
- <td><code></code></td>
157
- <td></td>
158
- <td><code>(</code> <code>(</code> <a href="#grammar-production-R_CHAR">R_CHAR</a> "<code class="grammar-literal">-</code>" <a href="#grammar-production-R_CHAR">R_CHAR</a><code>)</code><code>(</code> <a href="#grammar-production-HEX">HEX</a> "<code class="grammar-literal">-</code>" <a href="#grammar-production-HEX">HEX</a><code>)</code> <code>|</code> <a href="#grammar-production-R_CHAR">R_CHAR</a> <code>|</code> <a href="#grammar-production-HEX">HEX</a><code>)</code> <code>+</code></td>
159
- </tr>
160
- <tr id="grammar-production-">
161
- <td>[15]</td>
162
- <td><code></code></td>
163
- <td></td>
164
- <td>"<code class="grammar-literal">-</code>"<code>?</code></td>
165
- </tr>
166
- <tr id="grammar-production-">
167
- <td>[15]</td>
168
- <td><code></code></td>
169
- <td></td>
170
- <td>"<code class="grammar-literal">]</code>"</td>
97
+ <td>&quot;[^&quot; <code>(</code> <code>(</code> <a href="#grammar-production-R_CHAR">R_CHAR</a> "<code class="grammar-literal">-</code>" <a href="#grammar-production-R_CHAR">R_CHAR</a><code>)</code> <code>|</code> <code>(</code> <a href="#grammar-production-HEX">HEX</a> "<code class="grammar-literal">-</code>" <a href="#grammar-production-HEX">HEX</a><code>)</code> <code>|</code> <a href="#grammar-production-R_CHAR">R_CHAR</a> <code>|</code> <a href="#grammar-production-HEX">HEX</a><code>)</code> <code>+</code> "<code class="grammar-literal">-</code>"<code>?</code> "<code class="grammar-literal">]</code>"</td>
171
98
  </tr>
172
99
  <tr id="grammar-production-STRING1">
173
100
  <td>[16]</td>
174
101
  <td><code>STRING1</code></td>
175
102
  <td>::=</td>
176
- <td>'<code class="grammar-literal">"</code>' <code>(</code> <a href="#grammar-production-CHAR">CHAR</a> <code>-</code> '<code class="grammar-literal">"</code>'<code>)</code> <code>*</code> '<code class="grammar-literal">"</code>'</td>
103
+ <td>'<code class="grammar-literal">&quot;</code>' <code>(</code> <a href="#grammar-production-CHAR">CHAR</a> <code>-</code> '<code class="grammar-literal">&quot;</code>'<code>)</code> <code>*</code> '<code class="grammar-literal">&quot;</code>'</td>
177
104
  </tr>
178
105
  <tr id="grammar-production-STRING2">
179
106
  <td>[17]</td>
180
107
  <td><code>STRING2</code></td>
181
108
  <td>::=</td>
182
- <td>"<code class="grammar-literal">'</code>" <code>(</code> <a href="#grammar-production-CHAR">CHAR</a> <code>-</code> "<code class="grammar-literal">'</code>"<code>)</code> <code>*</code> "<code class="grammar-literal">'</code>"</td>
109
+ <td>"<code class="grammar-literal">&apos;</code>" <code>(</code> <a href="#grammar-production-CHAR">CHAR</a> <code>-</code> "<code class="grammar-literal">&apos;</code>"<code>)</code> <code>*</code> "<code class="grammar-literal">&apos;</code>"</td>
183
110
  </tr>
184
111
  <tr id="grammar-production-CHAR">
185
112
  <td>[18]</td>
186
113
  <td><code>CHAR</code></td>
187
114
  <td>::=</td>
188
- <td><code>[</code> <code class="grammar-char-escape"><abbr title="horizontal tab">#x09</abbr></code><code class="grammar-char-escape"><abbr title="new line">#x0A</abbr></code><code class="grammar-char-escape"><abbr title="carriage return">#x0D</abbr></code><code>]</code></td>
189
- </tr>
190
- <tr>
191
- <td>[18]</td>
192
- <td><code></code></td>
193
- <td>|</td>
194
- <td><code>[</code> <code class="grammar-char-escape"><abbr title="space">#x20</abbr></code><code class="grammar-literal">-</code><code class="grammar-char-escape"><abbr title="unicode '퟿'">#xD7FF</abbr></code><code>]</code></td>
195
- </tr>
196
- <tr>
197
- <td>[18]</td>
198
- <td><code></code></td>
199
- <td>|</td>
200
- <td><code>[</code> <code class="grammar-char-escape"><abbr title="unicode ''">#xE000</abbr></code><code class="grammar-literal">-</code><code class="grammar-char-escape"><abbr title="unicode '�'">#xFFFD</abbr></code><code>]</code></td>
201
- </tr>
202
- <tr>
203
- <td>[18]</td>
204
- <td><code></code></td>
205
- <td>|</td>
206
- <td><code>[</code> <code class="grammar-char-escape"><abbr title="unicode '𐀀'">#x00010000</abbr></code><code class="grammar-literal">-</code><code class="grammar-char-escape"><abbr title="unicode '􏿿'">#x0010FFFF</abbr></code><code>]</code> </td>
115
+ <td><code>[</code> <code class="grammar-char-escape"><abbr title="horizontal tab">#x09</abbr></code><code class="grammar-char-escape"><abbr title="new line">#x0A</abbr></code><code class="grammar-char-escape"><abbr title="carriage return">#x0D</abbr></code><code>]</code> <code>|</code> <code>[</code> <code class="grammar-char-escape"><abbr title="space">#x20</abbr></code><code class="grammar-literal">-</code><code class="grammar-char-escape"><abbr title="unicode 'Reserved'">#xD7FF</abbr></code><code>]</code> <code>|</code> <code>[</code> <code class="grammar-char-escape"><abbr title="unicode 'Private-use'">#xE000</abbr></code><code class="grammar-literal">-</code><code class="grammar-char-escape"><abbr title="unicode 'Graphic'">#xFFFD</abbr></code><code>]</code> <code>|</code> <code>[</code> <code class="grammar-char-escape"><abbr title="unicode 'Graphic'">#x00010000</abbr></code><code class="grammar-literal">-</code><code class="grammar-char-escape"><abbr title="unicode 'Noncharacter'">#x0010FFFF</abbr></code><code>]</code> </td>
207
116
  </tr>
208
117
  <tr id="grammar-production-R_CHAR">
209
118
  <td>[19]</td>
@@ -224,28 +133,24 @@
224
133
  <td><code>[</code> <code class="grammar-char-escape"><abbr title="horizontal tab">#x09</abbr></code><code class="grammar-char-escape"><abbr title="new line">#x0A</abbr></code><code class="grammar-char-escape"><abbr title="carriage return">#x0D</abbr></code><code class="grammar-char-escape"><abbr title="space">#x20</abbr></code><code>]</code></td>
225
134
  </tr>
226
135
  <tr>
227
- <td>[21]</td>
228
- <td><code></code></td>
136
+ <td colspan=2></td>
229
137
  <td>|</td>
230
- <td><code>(</code> <code>(</code> <code>(</code> "<code class="grammar-literal">#</code>" <code>-</code> "#x"<code>)</code> <code>|</code> "//"<code>)</code> <code>[</code> <code class="grammar-literal">^</code><code class="grammar-char-escape"><abbr title="new line">#x0A</abbr></code><code class="grammar-char-escape"><abbr title="carriage return">#x0D</abbr></code><code>]</code> <code>*</code> <code>)</code></td>
138
+ <td><code>(</code> <code>(</code> <code>(</code> "<code class="grammar-literal">#</code>" <code>-</code> &quot;#x&quot;<code>)</code> <code>|</code> &quot;//&quot;<code>)</code> <code>[</code> <code class="grammar-literal">^</code><code class="grammar-char-escape"><abbr title="new line">#x0A</abbr></code><code class="grammar-char-escape"><abbr title="carriage return">#x0D</abbr></code><code>]</code> <code>*</code> <code>)</code></td>
231
139
  </tr>
232
140
  <tr>
233
- <td>[21]</td>
234
- <td><code></code></td>
141
+ <td colspan=2></td>
235
142
  <td>|</td>
236
- <td><code>(</code> "/*" <code>(</code> <code>(</code> "<code class="grammar-literal">*</code>" <code>[</code> <code class="grammar-literal">^/</code><code>]</code> <code>)</code> <code>?</code> <code>|</code> <code>[</code> <code class="grammar-literal">^*</code><code>]</code> <code>)</code> <code>*</code> "*/"<code>)</code></td>
143
+ <td><code>(</code> &quot;/*&quot; <code>(</code> <code>(</code> "<code class="grammar-literal">*</code>" <code>[</code> <code class="grammar-literal">^/</code><code>]</code> <code>)</code> <code>?</code> <code>|</code> <code>[</code> <code class="grammar-literal">^*</code><code>]</code> <code>)</code> <code>*</code> &quot;*/&quot;<code>)</code></td>
237
144
  </tr>
238
145
  <tr>
239
- <td>[21]</td>
240
- <td><code></code></td>
146
+ <td colspan=2></td>
241
147
  <td>|</td>
242
- <td><code>(</code> "(*" <code>(</code> <code>(</code> "<code class="grammar-literal">*</code>" <code>[</code> <code class="grammar-literal">^)</code><code>]</code> <code>)</code> <code>?</code> <code>|</code> <code>[</code> <code class="grammar-literal">^*</code><code>]</code> <code>)</code> <code>*</code> "*)"<code>)</code> </td>
148
+ <td><code>(</code> &quot;(*&quot; <code>(</code> <code>(</code> "<code class="grammar-literal">*</code>" <code>[</code> <code class="grammar-literal">^)</code><code>]</code> <code>)</code> <code>?</code> <code>|</code> <code>[</code> <code class="grammar-literal">^*</code><code>]</code> <code>)</code> <code>*</code> &quot;*)&quot;<code>)</code> </td>
243
149
  </tr>
244
- <tr id="grammar-production-">
245
- <td>@pass</td>
246
- <td><code></code></td>
247
- <td></td>
150
+ <tr>
151
+ <td colspan=2>@pass</td>
248
152
  <td></td>
153
+ <td><a href="#grammar-production-PASS">PASS</a></td>
249
154
  </tr>
250
155
  </tbody>
251
156
  </table>
data/etc/ebnf.ll1.rb CHANGED
@@ -1,4 +1,4 @@
1
- # This file is automatically generated by ebnf version 2.0.0
1
+ # This file is automatically generated by ebnf version 2.1.2
2
2
  # Derived from etc/ebnf.ebnf
3
3
  module Meta
4
4
  START = :ebnf
data/etc/ebnf.peg.rb CHANGED
@@ -1,4 +1,4 @@
1
- # This file is automatically generated by ebnf version 2.0.0
1
+ # This file is automatically generated by ebnf version 2.1.2
2
2
  # Derived from etc/ebnf.ebnf
3
3
  module EBNFMeta
4
4
  RULES = [
data/lib/ebnf/base.rb CHANGED
@@ -220,9 +220,10 @@ module EBNF
220
220
  # Output formatted EBNF as HTML
221
221
  #
222
222
  # @param [:abnf, :ebnf, :isoebnf] format (:ebnf)
223
+ # @param [Boolean] validate (false) validate generated HTML.
223
224
  # @return [String]
224
- def to_html(format: :ebnf)
225
- Writer.html(*ast, format: format)
225
+ def to_html(format: :ebnf, validate: false)
226
+ Writer.html(*ast, format: format, validate: validate)
226
227
  end
227
228
 
228
229
  ##
data/lib/ebnf/writer.rb CHANGED
@@ -2,6 +2,7 @@
2
2
  require 'rdf'
3
3
  require 'strscan' unless defined?(StringScanner)
4
4
  require "ostruct"
5
+ require 'unicode/types'
5
6
 
6
7
  ##
7
8
  # Serialize ruleset back to EBNF
@@ -86,22 +87,23 @@ module EBNF
86
87
  #
87
88
  # @param [Array<Rule>] rules
88
89
  # @param [:abnf, :ebnf, :isoebnf] format (:ebnf)
90
+ # @param [Boolean] validate (false) validate generated HTML.
89
91
  # @return [Object]
90
- def self.html(*rules, format: :ebnf)
92
+ def self.html(*rules, format: :ebnf, validate: false)
91
93
  require 'stringio' unless defined?(StringIO)
92
94
  buf = StringIO.new
93
- Writer.new(rules, out: buf, html: true, format: format)
95
+ Writer.new(rules, out: buf, html: true, format: format, validate: validate)
94
96
  buf.string
95
97
  end
96
98
 
97
99
  ##
98
100
  # @param [Array<Rule>] rules
101
+ # @param [:abnf, :ebnf, :isoebnf] format (:ebnf)
102
+ # @param [Boolean] html (false) generate HTML output
103
+ # @param [Boolean] validate (false) validate generated HTML.
99
104
  # @param [Hash{Symbol => Object}] options
100
105
  # @param [#write] out ($stdout)
101
- # @param [:abnf, :ebnf, :isoebnf] format (:ebnf)
102
- # @option options [Symbol] format
103
- # @option options [Boolean] html (false)
104
- def initialize(rules, out: $stdout, html: false, format: :ebnf, **options)
106
+ def initialize(rules, out: $stdout, html: false, format: :ebnf, validate: false, **options)
105
107
  @options = options.merge(html: html)
106
108
  return if rules.empty?
107
109
 
@@ -174,7 +176,22 @@ module EBNF
174
176
  end
175
177
  end
176
178
  end.flatten
177
- out.write eruby.evaluate(format: format, rules: formatted_rules)
179
+
180
+ html_result = eruby.evaluate(format: format, rules: formatted_rules)
181
+
182
+ if validate
183
+ begin
184
+ require 'nokogumbo'
185
+ # Validate the output HTML
186
+ doc = Nokogiri::HTML5("<!DOCTYPE html>" + html_result, max_errors: 10)
187
+ raise EncodingError, "Errors found in generated HTML:\n " +
188
+ doc.errors.map(&:to_s).join("\n ") unless doc.errors.empty?
189
+ rescue LoadError
190
+ # Skip
191
+ end
192
+ end
193
+
194
+ out.write html_result
178
195
  return
179
196
  rescue LoadError
180
197
  $stderr.puts "Generating HTML requires erubis and htmlentities gems to be loaded"
@@ -347,16 +364,20 @@ module EBNF
347
364
  end
348
365
  char = fmt % u.ord
349
366
  if @options[:html]
350
- if u.ord <= 0x20
351
- char = %(<abbr title="#{ASCII_ESCAPE_NAMES[u.ord]}">#{@coder.encode char}</abbr>)
367
+ char = if u.ord <= 0x20
368
+ %(<abbr title="#{ASCII_ESCAPE_NAMES[u.ord]}">#{@coder.encode char}</abbr>)
369
+ elsif u.ord == 0x22
370
+ %(<abbr title="quot">>&quot;</abbr>)
352
371
  elsif u.ord < 0x7F
353
- char = %(<abbr title="ascii '#{@coder.encode u}'">#{@coder.encode char}</abbr>)
372
+ %(<abbr title="ascii '#{@coder.encode u}'">#{@coder.encode char}</abbr>)
354
373
  elsif u.ord == 0x7F
355
- char = %(<abbr title="delete">#{@coder.encode char}</abbr>)
374
+ %(<abbr title="delete">#{@coder.encode char}</abbr>)
356
375
  elsif u.ord <= 0xFF
357
- char = %(<abbr title="extended ascii '#{u}'">#{char}</abbr>)
376
+ %(<abbr title="extended ascii '#{@coder.encode char}'">#{char}</abbr>)
377
+ elsif (%w(Control Private-use Surrogate Noncharacter Reserved) - ::Unicode::Types.of(u)).empty?
378
+ %(<abbr title="unicode '#{u}'">#{char}</abbr>)
358
379
  else
359
- char = %(<abbr title="unicode '#{u}'">#{char}</abbr>)
380
+ %(<abbr title="unicode '#{::Unicode::Types.of(u).first}'">#{char}</abbr>)
360
381
  end
361
382
  %(<code class="grammar-char-escape">#{char}</code>)
362
383
  else
@@ -455,7 +476,7 @@ module EBNF
455
476
  # Format a single-character string, prefering hex for non-main ASCII
456
477
  def format_abnf_char(c)
457
478
  if /[\x20-\x21\x23-\x7E]/.match?(c)
458
- c.inspect
479
+ @options[:html] ? %("<code class="grammar-literal">#{@coder.encode c}</code>") : c.inspect
459
480
  else
460
481
  escape_abnf_hex(c)
461
482
  end
@@ -536,14 +557,16 @@ module EBNF
536
557
  if @options[:html]
537
558
  if u.ord <= 0x20
538
559
  char = %(<abbr title="#{ASCII_ESCAPE_NAMES[u.ord]}">#{@coder.encode char}</abbr>)
539
- elsif u.ord <= 0x7F
560
+ elsif u.ord == 0x22
561
+ %(<abbr title="quot">>&quot;</abbr>)
562
+ elsif u.ord < 0x7F
540
563
  char = %(<abbr title="ascii '#{u}'">#{@coder.encode char}</abbr>)
541
564
  elsif u.ord == 0x7F
542
565
  char = %(<abbr title="delete">#{@coder.encode char}</abbr>)
543
566
  elsif u.ord <= 0xFF
544
567
  char = %(<abbr title="extended ascii '#{u}'">#{char}</abbr>)
545
568
  else
546
- char = %(<abbr title="unicode '#{u}'">#{char}</abbr>)
569
+ char = %(<abbr title="unicode '#{u.unicode_normaliz}'">#{char}</abbr>)
547
570
  end
548
571
  %(<code class="grammar-char-escape">#{char}</code>)
549
572
  else
@@ -686,7 +709,7 @@ module EBNF
686
709
  <table class="grammar">
687
710
  <tbody id="grammar-productions" class="<%= @format %>">
688
711
  <% for rule in @rules %>
689
- <tr<%= %{ id="grammar-production-#{rule.sym}"} unless %w(=/ |).include?(rule.assign)%>>
712
+ <tr<%= %{ id="grammar-production-#{rule.sym}"} unless %w(=/ |).include?(rule.assign) || rule.sym.nil?%>>
690
713
  <% if rule.id %>
691
714
  <td<%= " colspan=2" unless rule.sym %>><%= rule.id %></td>
692
715
  <% end %>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ebnf
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.2
4
+ version: 2.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregg Kellogg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-25 00:00:00.000000000 Z
11
+ date: 2021-04-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sxp
@@ -66,6 +66,34 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '4.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: unicode-types
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.6'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.6'
83
+ - !ruby/object:Gem::Dependency
84
+ name: amazing_print
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.2'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.2'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: rdf-spec
71
99
  requirement: !ruby/object:Gem::Requirement
@@ -128,14 +156,14 @@ dependencies:
128
156
  requirements:
129
157
  - - "~>"
130
158
  - !ruby/object:Gem::Version
131
- version: '3.9'
159
+ version: '3.10'
132
160
  type: :development
133
161
  prerelease: false
134
162
  version_requirements: !ruby/object:Gem::Requirement
135
163
  requirements:
136
164
  - - "~>"
137
165
  - !ruby/object:Gem::Version
138
- version: '3.9'
166
+ version: '3.10'
139
167
  - !ruby/object:Gem::Dependency
140
168
  name: rspec-its
141
169
  requirement: !ruby/object:Gem::Requirement
@@ -261,8 +289,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
261
289
  - !ruby/object:Gem::Version
262
290
  version: '0'
263
291
  requirements: []
264
- rubygems_version: 3.1.4
292
+ rubygems_version: 3.2.3
265
293
  signing_key:
266
294
  specification_version: 4
267
- summary: EBNF parser and parser generator.
295
+ summary: EBNF parser and parser generator in Ruby.
268
296
  test_files: []