ebnf 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +81 -36
- data/VERSION +1 -1
- data/bin/ebnf +34 -18
- data/etc/abnf-core.ebnf +52 -0
- data/etc/abnf.abnf +121 -0
- data/etc/abnf.ebnf +124 -0
- data/etc/abnf.sxp +45 -0
- data/etc/ebnf.ebnf +19 -25
- data/etc/ebnf.html +251 -206
- data/etc/ebnf.ll1.rb +27 -103
- data/etc/ebnf.ll1.sxp +105 -102
- data/etc/ebnf.peg.rb +54 -62
- data/etc/ebnf.peg.sxp +53 -62
- data/etc/ebnf.sxp +22 -19
- data/etc/iso-ebnf.ebnf +140 -0
- data/etc/iso-ebnf.isoebnf +138 -0
- data/etc/iso-ebnf.sxp +65 -0
- data/etc/sparql.ebnf +4 -4
- data/etc/sparql.sxp +8 -7
- data/etc/turtle.ebnf +3 -3
- data/etc/turtle.sxp +22 -20
- data/lib/ebnf.rb +3 -0
- data/lib/ebnf/abnf.rb +301 -0
- data/lib/ebnf/abnf/core.rb +23 -0
- data/lib/ebnf/abnf/meta.rb +111 -0
- data/lib/ebnf/base.rb +87 -44
- data/lib/ebnf/ebnf/meta.rb +90 -0
- data/lib/ebnf/isoebnf.rb +229 -0
- data/lib/ebnf/isoebnf/meta.rb +75 -0
- data/lib/ebnf/ll1.rb +4 -7
- data/lib/ebnf/ll1/parser.rb +12 -4
- data/lib/ebnf/native.rb +320 -0
- data/lib/ebnf/parser.rb +285 -302
- data/lib/ebnf/peg.rb +1 -1
- data/lib/ebnf/peg/parser.rb +24 -5
- data/lib/ebnf/peg/rule.rb +77 -58
- data/lib/ebnf/rule.rb +352 -121
- data/lib/ebnf/terminals.rb +13 -10
- data/lib/ebnf/writer.rb +550 -78
- metadata +48 -6
@@ -0,0 +1,23 @@
|
|
1
|
+
# This file is automatically generated by ebnf version 2.0.0
|
2
|
+
# Derived from etc/abnf-core.ebnf
|
3
|
+
module ABNFCore
|
4
|
+
RULES = [
|
5
|
+
EBNF::Rule.new(:ALPHA, nil, [:range, "#x41-#x5A#x61-#x7A"], kind: :terminal),
|
6
|
+
EBNF::Rule.new(:BIT, nil, [:alt, "0", "1"], kind: :terminal),
|
7
|
+
EBNF::Rule.new(:CHAR, nil, [:range, "#x01-#x7F"], kind: :terminal),
|
8
|
+
EBNF::Rule.new(:CR, nil, [:hex, "#x0D"], kind: :terminal),
|
9
|
+
EBNF::Rule.new(:CRLF, nil, [:seq, [:opt, :CR], :LF], kind: :terminal),
|
10
|
+
EBNF::Rule.new(:CTL, nil, [:alt, [:range, "#x00-#x1F"], [:hex, "#x7F"]], kind: :terminal),
|
11
|
+
EBNF::Rule.new(:DIGIT, nil, [:range, "#x30-#x39"], kind: :terminal),
|
12
|
+
EBNF::Rule.new(:DQUOTE, nil, [:hex, "#x22"], kind: :terminal),
|
13
|
+
EBNF::Rule.new(:HEXDIG, nil, [:alt, :DIGIT, [:range, "A-F"]], kind: :terminal),
|
14
|
+
EBNF::Rule.new(:HTAB, nil, [:hex, "#x09"], kind: :terminal),
|
15
|
+
EBNF::Rule.new(:LF, nil, [:hex, "#x0A"], kind: :terminal),
|
16
|
+
EBNF::Rule.new(:LWSP, nil, [:star, [:alt, :WSP, [:seq, :CRLF, :WSP]]], kind: :terminal),
|
17
|
+
EBNF::Rule.new(:OCTET, nil, [:range, "#x00-#xFF"], kind: :terminal),
|
18
|
+
EBNF::Rule.new(:SP, nil, [:hex, "#x20"], kind: :terminal),
|
19
|
+
EBNF::Rule.new(:VCHAR, nil, [:range, "#x21-#x7E"], kind: :terminal),
|
20
|
+
EBNF::Rule.new(:WSP, nil, [:alt, :SP, :HTAB], kind: :terminal),
|
21
|
+
]
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# This file is automatically generated by ebnf version 2.0.0
|
2
|
+
# Derived from abnf.ebnf
|
3
|
+
module ABNFMeta
|
4
|
+
RULES = [
|
5
|
+
EBNF::Rule.new(:rulelist, nil, [:plus, :_rulelist_1]).extend(EBNF::PEG::Rule),
|
6
|
+
EBNF::Rule.new(:_rulelist_1, nil, [:alt, :rule, :_rulelist_2]).extend(EBNF::PEG::Rule),
|
7
|
+
EBNF::Rule.new(:_rulelist_2, nil, [:seq, :_rulelist_3, :c_nl]).extend(EBNF::PEG::Rule),
|
8
|
+
EBNF::Rule.new(:_rulelist_3, nil, [:star, :c_wsp]).extend(EBNF::PEG::Rule),
|
9
|
+
EBNF::Rule.new(:rule, nil, [:seq, :rulename, :defined_as, :elements, :c_nl]).extend(EBNF::PEG::Rule),
|
10
|
+
EBNF::Rule.new(:elements, nil, [:seq, :alternation, :_elements_1]).extend(EBNF::PEG::Rule),
|
11
|
+
EBNF::Rule.new(:_elements_1, nil, [:star, :c_wsp]).extend(EBNF::PEG::Rule),
|
12
|
+
EBNF::Rule.new(:alternation, nil, [:seq, :concatenation, :_alternation_1]).extend(EBNF::PEG::Rule),
|
13
|
+
EBNF::Rule.new(:_alternation_1, nil, [:star, :_alternation_2]).extend(EBNF::PEG::Rule),
|
14
|
+
EBNF::Rule.new(:_alternation_2, nil, [:seq, :_alternation_3, "/", :_alternation_4, :concatenation]).extend(EBNF::PEG::Rule),
|
15
|
+
EBNF::Rule.new(:_alternation_3, nil, [:star, :c_wsp]).extend(EBNF::PEG::Rule),
|
16
|
+
EBNF::Rule.new(:_alternation_4, nil, [:star, :c_wsp]).extend(EBNF::PEG::Rule),
|
17
|
+
EBNF::Rule.new(:concatenation, nil, [:seq, :repetition, :_concatenation_1]).extend(EBNF::PEG::Rule),
|
18
|
+
EBNF::Rule.new(:_concatenation_1, nil, [:star, :_concatenation_2]).extend(EBNF::PEG::Rule),
|
19
|
+
EBNF::Rule.new(:_concatenation_2, nil, [:seq, :_concatenation_3, :repetition]).extend(EBNF::PEG::Rule),
|
20
|
+
EBNF::Rule.new(:_concatenation_3, nil, [:plus, :c_wsp]).extend(EBNF::PEG::Rule),
|
21
|
+
EBNF::Rule.new(:repetition, nil, [:seq, :_repetition_1, :element]).extend(EBNF::PEG::Rule),
|
22
|
+
EBNF::Rule.new(:_repetition_1, nil, [:opt, :repeat]).extend(EBNF::PEG::Rule),
|
23
|
+
EBNF::Rule.new(:repeat, nil, [:alt, :_repeat_1, :_repeat_2]).extend(EBNF::PEG::Rule),
|
24
|
+
EBNF::Rule.new(:_repeat_1, nil, [:seq, :_repeat_3, "*", :_repeat_4]).extend(EBNF::PEG::Rule),
|
25
|
+
EBNF::Rule.new(:_repeat_3, nil, [:star, :DIGIT]).extend(EBNF::PEG::Rule),
|
26
|
+
EBNF::Rule.new(:_repeat_4, nil, [:star, :DIGIT]).extend(EBNF::PEG::Rule),
|
27
|
+
EBNF::Rule.new(:_repeat_2, nil, [:plus, :DIGIT]).extend(EBNF::PEG::Rule),
|
28
|
+
EBNF::Rule.new(:element, nil, [:alt, :rulename, :group, :option, :char_val, :num_val, :prose_val]).extend(EBNF::PEG::Rule),
|
29
|
+
EBNF::Rule.new(:group, nil, [:seq, "(", :_group_1, :alternation, :_group_2, ")"]).extend(EBNF::PEG::Rule),
|
30
|
+
EBNF::Rule.new(:_group_1, nil, [:star, :c_wsp]).extend(EBNF::PEG::Rule),
|
31
|
+
EBNF::Rule.new(:_group_2, nil, [:star, :c_wsp]).extend(EBNF::PEG::Rule),
|
32
|
+
EBNF::Rule.new(:option, nil, [:seq, "[", :_option_1, :alternation, :_option_2, "]"]).extend(EBNF::PEG::Rule),
|
33
|
+
EBNF::Rule.new(:_option_1, nil, [:star, :c_wsp]).extend(EBNF::PEG::Rule),
|
34
|
+
EBNF::Rule.new(:_option_2, nil, [:star, :c_wsp]).extend(EBNF::PEG::Rule),
|
35
|
+
EBNF::Rule.new(:char_val, nil, [:alt, :case_insensitive_string, :case_sensitive_string]).extend(EBNF::PEG::Rule),
|
36
|
+
EBNF::Rule.new(:case_insensitive_string, nil, [:seq, :_case_insensitive_string_1, :quoted_string]).extend(EBNF::PEG::Rule),
|
37
|
+
EBNF::Rule.new(:_case_insensitive_string_1, nil, [:opt, "%i"]).extend(EBNF::PEG::Rule),
|
38
|
+
EBNF::Rule.new(:case_sensitive_string, nil, [:seq, "%s", :quoted_string]).extend(EBNF::PEG::Rule),
|
39
|
+
EBNF::Rule.new(:num_val, nil, [:seq, "%", :_num_val_1]).extend(EBNF::PEG::Rule),
|
40
|
+
EBNF::Rule.new(:_num_val_1, nil, [:alt, :bin_val, :dec_val, :hex_val]).extend(EBNF::PEG::Rule),
|
41
|
+
EBNF::Rule.new(:rulename, nil, [:seq, :ALPHA, :_rulename_1], kind: :terminal).extend(EBNF::PEG::Rule),
|
42
|
+
EBNF::Rule.new(:_rulename_1, nil, [:star, :_rulename_2]).extend(EBNF::PEG::Rule),
|
43
|
+
EBNF::Rule.new(:_rulename_2, nil, [:alt, :ALPHA, :DIGIT, "-"]).extend(EBNF::PEG::Rule),
|
44
|
+
EBNF::Rule.new(:defined_as, nil, [:seq, :_defined_as_1, :_defined_as_2, :_defined_as_3], kind: :terminal).extend(EBNF::PEG::Rule),
|
45
|
+
EBNF::Rule.new(:_defined_as_1, nil, [:star, :c_wsp]).extend(EBNF::PEG::Rule),
|
46
|
+
EBNF::Rule.new(:_defined_as_2, nil, [:alt, "=", "=/"]).extend(EBNF::PEG::Rule),
|
47
|
+
EBNF::Rule.new(:_defined_as_3, nil, [:star, :c_wsp]).extend(EBNF::PEG::Rule),
|
48
|
+
EBNF::Rule.new(:c_wsp, nil, [:alt, :WSP, :_c_wsp_1], kind: :terminal).extend(EBNF::PEG::Rule),
|
49
|
+
EBNF::Rule.new(:_c_wsp_1, nil, [:seq, :c_nl, :WSP]).extend(EBNF::PEG::Rule),
|
50
|
+
EBNF::Rule.new(:c_nl, nil, [:alt, :COMMENT, :CRLF], kind: :terminal).extend(EBNF::PEG::Rule),
|
51
|
+
EBNF::Rule.new(:comment, nil, [:seq, ";", :_comment_1, :CRLF], kind: :terminal).extend(EBNF::PEG::Rule),
|
52
|
+
EBNF::Rule.new(:_comment_1, nil, [:star, :_comment_2]).extend(EBNF::PEG::Rule),
|
53
|
+
EBNF::Rule.new(:_comment_2, nil, [:alt, :WSP, :VCHAR]).extend(EBNF::PEG::Rule),
|
54
|
+
EBNF::Rule.new(:quoted_string, nil, [:seq, :DQUOTE, :_quoted_string_1, :DQUOTE], kind: :terminal).extend(EBNF::PEG::Rule),
|
55
|
+
EBNF::Rule.new(:_quoted_string_1, nil, [:star, :_quoted_string_2]).extend(EBNF::PEG::Rule),
|
56
|
+
EBNF::Rule.new(:_quoted_string_2, nil, [:range, "#x20-#x21#x23-#x7E"], kind: :terminal).extend(EBNF::PEG::Rule),
|
57
|
+
EBNF::Rule.new(:bin_val, nil, [:seq, "b", :_bin_val_1, :_bin_val_2], kind: :terminal).extend(EBNF::PEG::Rule),
|
58
|
+
EBNF::Rule.new(:_bin_val_1, nil, [:plus, :BIT]).extend(EBNF::PEG::Rule),
|
59
|
+
EBNF::Rule.new(:_bin_val_2, nil, [:opt, :_bin_val_3]).extend(EBNF::PEG::Rule),
|
60
|
+
EBNF::Rule.new(:_bin_val_3, nil, [:alt, :_bin_val_4, :_bin_val_5]).extend(EBNF::PEG::Rule),
|
61
|
+
EBNF::Rule.new(:_bin_val_4, nil, [:plus, :_bin_val_6]).extend(EBNF::PEG::Rule),
|
62
|
+
EBNF::Rule.new(:_bin_val_6, nil, [:seq, ".", :_bin_val_7]).extend(EBNF::PEG::Rule),
|
63
|
+
EBNF::Rule.new(:_bin_val_7, nil, [:plus, :BIT]).extend(EBNF::PEG::Rule),
|
64
|
+
EBNF::Rule.new(:_bin_val_5, nil, [:seq, "-", :_bin_val_8]).extend(EBNF::PEG::Rule),
|
65
|
+
EBNF::Rule.new(:_bin_val_8, nil, [:plus, :BIT]).extend(EBNF::PEG::Rule),
|
66
|
+
EBNF::Rule.new(:dec_val, nil, [:seq, "d", :_dec_val_1, :_dec_val_2], kind: :terminal).extend(EBNF::PEG::Rule),
|
67
|
+
EBNF::Rule.new(:_dec_val_1, nil, [:plus, :DIGIT]).extend(EBNF::PEG::Rule),
|
68
|
+
EBNF::Rule.new(:_dec_val_2, nil, [:opt, :_dec_val_3]).extend(EBNF::PEG::Rule),
|
69
|
+
EBNF::Rule.new(:_dec_val_3, nil, [:alt, :_dec_val_4, :_dec_val_5]).extend(EBNF::PEG::Rule),
|
70
|
+
EBNF::Rule.new(:_dec_val_4, nil, [:plus, :_dec_val_6]).extend(EBNF::PEG::Rule),
|
71
|
+
EBNF::Rule.new(:_dec_val_6, nil, [:seq, ".", :_dec_val_7]).extend(EBNF::PEG::Rule),
|
72
|
+
EBNF::Rule.new(:_dec_val_7, nil, [:plus, :DIGIT]).extend(EBNF::PEG::Rule),
|
73
|
+
EBNF::Rule.new(:_dec_val_5, nil, [:seq, "-", :_dec_val_8]).extend(EBNF::PEG::Rule),
|
74
|
+
EBNF::Rule.new(:_dec_val_8, nil, [:plus, :DIGIT]).extend(EBNF::PEG::Rule),
|
75
|
+
EBNF::Rule.new(:hex_val, nil, [:seq, "x", :_hex_val_1, :_hex_val_2], kind: :terminal).extend(EBNF::PEG::Rule),
|
76
|
+
EBNF::Rule.new(:_hex_val_1, nil, [:plus, :HEXDIG]).extend(EBNF::PEG::Rule),
|
77
|
+
EBNF::Rule.new(:_hex_val_2, nil, [:opt, :_hex_val_3]).extend(EBNF::PEG::Rule),
|
78
|
+
EBNF::Rule.new(:_hex_val_3, nil, [:alt, :_hex_val_4, :_hex_val_5]).extend(EBNF::PEG::Rule),
|
79
|
+
EBNF::Rule.new(:_hex_val_4, nil, [:plus, :_hex_val_6]).extend(EBNF::PEG::Rule),
|
80
|
+
EBNF::Rule.new(:_hex_val_6, nil, [:seq, ".", :_hex_val_7]).extend(EBNF::PEG::Rule),
|
81
|
+
EBNF::Rule.new(:_hex_val_7, nil, [:plus, :HEXDIG]).extend(EBNF::PEG::Rule),
|
82
|
+
EBNF::Rule.new(:_hex_val_5, nil, [:seq, "-", :_hex_val_8]).extend(EBNF::PEG::Rule),
|
83
|
+
EBNF::Rule.new(:_hex_val_8, nil, [:plus, :HEXDIG]).extend(EBNF::PEG::Rule),
|
84
|
+
EBNF::Rule.new(:prose_val, nil, [:seq, "<", :_prose_val_1, ">"], kind: :terminal).extend(EBNF::PEG::Rule),
|
85
|
+
EBNF::Rule.new(:_prose_val_1, nil, [:star, :_prose_val_2]).extend(EBNF::PEG::Rule),
|
86
|
+
EBNF::Rule.new(:_prose_val_2, nil, [:range, "#x20-#x3D#x3F-#x7E"], kind: :terminal).extend(EBNF::PEG::Rule),
|
87
|
+
EBNF::Rule.new(:ALPHA, nil, [:range, "#x41-#x5A#x61-#x7A"], kind: :terminal).extend(EBNF::PEG::Rule),
|
88
|
+
EBNF::Rule.new(:BIT, nil, [:alt, "0", "1"], kind: :terminal).extend(EBNF::PEG::Rule),
|
89
|
+
EBNF::Rule.new(:CHAR, nil, [:range, "#x01-#x7F"], kind: :terminal).extend(EBNF::PEG::Rule),
|
90
|
+
EBNF::Rule.new(:CR, nil, [:hex, "#x0D"], kind: :terminal).extend(EBNF::PEG::Rule),
|
91
|
+
EBNF::Rule.new(:CRLF, nil, [:seq, :_CRLF_1, :LF], kind: :terminal).extend(EBNF::PEG::Rule),
|
92
|
+
EBNF::Rule.new(:_CRLF_1, nil, [:opt, :CR], kind: :terminal).extend(EBNF::PEG::Rule),
|
93
|
+
EBNF::Rule.new(:CTL, nil, [:alt, :_CTL_1, :_CTL_2], kind: :terminal).extend(EBNF::PEG::Rule),
|
94
|
+
EBNF::Rule.new(:_CTL_1, nil, [:range, "#x00-#x1F"], kind: :terminal).extend(EBNF::PEG::Rule),
|
95
|
+
EBNF::Rule.new(:_CTL_2, nil, [:hex, "#x7F"], kind: :terminal).extend(EBNF::PEG::Rule),
|
96
|
+
EBNF::Rule.new(:DIGIT, nil, [:range, "#x30-#x39"], kind: :terminal).extend(EBNF::PEG::Rule),
|
97
|
+
EBNF::Rule.new(:DQUOTE, nil, [:hex, "#x22"], kind: :terminal).extend(EBNF::PEG::Rule),
|
98
|
+
EBNF::Rule.new(:HEXDIG, nil, [:alt, :DIGIT, :_HEXDIG_1], kind: :terminal).extend(EBNF::PEG::Rule),
|
99
|
+
EBNF::Rule.new(:_HEXDIG_1, nil, [:range, "A-F"], kind: :terminal).extend(EBNF::PEG::Rule),
|
100
|
+
EBNF::Rule.new(:HTAB, nil, [:hex, "#x09"], kind: :terminal).extend(EBNF::PEG::Rule),
|
101
|
+
EBNF::Rule.new(:LF, nil, [:hex, "#x0A"], kind: :terminal).extend(EBNF::PEG::Rule),
|
102
|
+
EBNF::Rule.new(:LWSP, nil, [:star, :_LWSP_1], kind: :terminal).extend(EBNF::PEG::Rule),
|
103
|
+
EBNF::Rule.new(:_LWSP_1, nil, [:alt, :WSP, :_LWSP_2], kind: :terminal).extend(EBNF::PEG::Rule),
|
104
|
+
EBNF::Rule.new(:_LWSP_2, nil, [:seq, :CRLF, :WSP], kind: :terminal).extend(EBNF::PEG::Rule),
|
105
|
+
EBNF::Rule.new(:OCTET, nil, [:range, "#x00-#xFF"], kind: :terminal).extend(EBNF::PEG::Rule),
|
106
|
+
EBNF::Rule.new(:SP, nil, [:hex, "#x20"], kind: :terminal).extend(EBNF::PEG::Rule),
|
107
|
+
EBNF::Rule.new(:VCHAR, nil, [:range, "#x21-#x7E"], kind: :terminal).extend(EBNF::PEG::Rule),
|
108
|
+
EBNF::Rule.new(:WSP, nil, [:alt, :SP, :HTAB], kind: :terminal).extend(EBNF::PEG::Rule),
|
109
|
+
]
|
110
|
+
end
|
111
|
+
|
data/lib/ebnf/base.rb
CHANGED
@@ -66,22 +66,6 @@ require 'strscan'
|
|
66
66
|
# [Cwm Release 1.1.0rc1]: https://lists.w3.org/Archives/Public/public-cwm-announce/2005JulSep/0000.html
|
67
67
|
# [bnf-rules.n3]: https://www.w3.org/2000/10/swap/grammar/bnf-rules.n3
|
68
68
|
#
|
69
|
-
# Open Issues and Future Work
|
70
|
-
# ---------------------------
|
71
|
-
#
|
72
|
-
# The yacker output also has the terminals compiled to elaborate regular
|
73
|
-
# expressions. The best strategy for dealing with lexical tokens is not
|
74
|
-
# yet clear. Many tokens in SPARQL are case insensitive; this is not yet
|
75
|
-
# captured formally.
|
76
|
-
#
|
77
|
-
# The schema for the EBNF vocabulary used here (``g:seq``, ``g:alt``, ...)
|
78
|
-
# is not yet published; it should be aligned with [swap/grammar/bnf][]
|
79
|
-
# and the [bnf2html.n3][] rules (and/or the style of linked XHTML grammar
|
80
|
-
# in the SPARQL and XML specificiations).
|
81
|
-
#
|
82
|
-
# It would be interesting to corroborate the claim in the SPARQL spec
|
83
|
-
# that the grammar is LL(1) with a mechanical proof based on N3 rules.
|
84
|
-
#
|
85
69
|
# [swap/grammar/bnf]: https://www.w3.org/2000/10/swap/grammar/bnf
|
86
70
|
# [bnf2html.n3]: https://www.w3.org/2000/10/swap/grammar/bnf2html.n3
|
87
71
|
#
|
@@ -100,7 +84,7 @@ module EBNF
|
|
100
84
|
class Base
|
101
85
|
include BNF
|
102
86
|
include LL1
|
103
|
-
include
|
87
|
+
include Native
|
104
88
|
include PEG
|
105
89
|
|
106
90
|
# Abstract syntax tree from parse
|
@@ -118,23 +102,32 @@ module EBNF
|
|
118
102
|
#
|
119
103
|
# @param [#read, #to_s] input
|
120
104
|
# @param [Symbol] format (:ebnf)
|
121
|
-
# Format of input, one of
|
105
|
+
# Format of input, one of `:abnf`, `:ebnf`, `:isoebnf`, `:isoebnf`, `:native`, or `:sxp`.
|
106
|
+
# Use `:native` for the native EBNF parser, rather than the PEG parser.
|
122
107
|
# @param [Hash{Symbol => Object}] options
|
123
108
|
# @option options [Boolean, Array] :debug
|
124
109
|
# Output debug information to an array or $stdout.
|
110
|
+
# @option options [Boolean, Array] :validate
|
111
|
+
# Validate resulting grammar.
|
125
112
|
def initialize(input, format: :ebnf, **options)
|
126
113
|
@options = options.dup
|
127
114
|
@lineno, @depth, @errors = 1, 0, []
|
128
|
-
terminal = false
|
129
115
|
@ast = []
|
130
116
|
|
131
117
|
input = input.respond_to?(:read) ? input.read : input.to_s
|
132
118
|
|
133
119
|
case format
|
134
|
-
when :
|
135
|
-
|
136
|
-
@ast =
|
120
|
+
when :abnf
|
121
|
+
abnf = ABNF.new(input, **options)
|
122
|
+
@ast = abnf.ast
|
137
123
|
when :ebnf
|
124
|
+
ebnf = Parser.new(input, **options)
|
125
|
+
@ast = ebnf.ast
|
126
|
+
when :isoebnf
|
127
|
+
iso = ISOEBNF.new(input, **options)
|
128
|
+
@ast = iso.ast
|
129
|
+
when :native
|
130
|
+
terminals = false
|
138
131
|
scanner = StringScanner.new(input)
|
139
132
|
|
140
133
|
eachRule(scanner) do |r|
|
@@ -142,7 +135,9 @@ module EBNF
|
|
142
135
|
case r
|
143
136
|
when /^@terminals/
|
144
137
|
# Switch mode to parsing terminals
|
145
|
-
|
138
|
+
terminals = true
|
139
|
+
rule = Rule.new(nil, nil, nil, kind: :terminals, ebnf: self)
|
140
|
+
@ast << rule
|
146
141
|
when /^@pass\s*(.*)$/m
|
147
142
|
expr = expression($1).first
|
148
143
|
rule = Rule.new(nil, nil, expr, kind: :pass, ebnf: self)
|
@@ -151,14 +146,49 @@ module EBNF
|
|
151
146
|
else
|
152
147
|
rule = depth {ruleParts(r)}
|
153
148
|
|
154
|
-
rule.kind = :terminal if
|
149
|
+
rule.kind = :terminal if terminals # Override after we've parsed @terminals
|
155
150
|
rule.orig = r
|
156
151
|
@ast << rule
|
157
152
|
end
|
158
153
|
end
|
154
|
+
when :sxp
|
155
|
+
require 'sxp' unless defined?(SXP)
|
156
|
+
@ast = SXP::Reader::Basic.read(input).map {|e| Rule.from_sxp(e)}
|
159
157
|
else
|
160
158
|
raise "unknown input format #{format.inspect}"
|
161
159
|
end
|
160
|
+
|
161
|
+
validate! if @options[:validate]
|
162
|
+
end
|
163
|
+
|
164
|
+
##
|
165
|
+
# Validate the grammar.
|
166
|
+
#
|
167
|
+
# Makes sure that rules reference either strings or other defined rules.
|
168
|
+
#
|
169
|
+
# @raise [RangeError]
|
170
|
+
def validate!
|
171
|
+
ast.each do |rule|
|
172
|
+
begin
|
173
|
+
rule.validate!(@ast)
|
174
|
+
rescue SyntaxError => e
|
175
|
+
error("In rule #{rule.sym}: #{e.message}")
|
176
|
+
end
|
177
|
+
end
|
178
|
+
raise SyntaxError, errors.join("\n") unless errors.empty?
|
179
|
+
end
|
180
|
+
|
181
|
+
##
|
182
|
+
# Is the grammar valid?
|
183
|
+
#
|
184
|
+
# Uses `#validate!` and catches `RangeError`
|
185
|
+
#
|
186
|
+
# @return [Boolean]
|
187
|
+
def valid?
|
188
|
+
validate!
|
189
|
+
true
|
190
|
+
rescue SyntaxError
|
191
|
+
false
|
162
192
|
end
|
163
193
|
|
164
194
|
# Iterate over each rule or terminal, except empty
|
@@ -174,21 +204,25 @@ module EBNF
|
|
174
204
|
# @return [String]
|
175
205
|
def to_sxp
|
176
206
|
require 'sxp' unless defined?(SXP)
|
177
|
-
SXP::Generator.string(ast.
|
207
|
+
SXP::Generator.string(ast.map(&:for_sxp))
|
178
208
|
end
|
179
209
|
|
180
210
|
##
|
181
211
|
# Output formatted EBNF
|
212
|
+
#
|
213
|
+
# @param [:abnf, :ebnf, :isoebnf] format (:ebnf)
|
182
214
|
# @return [String]
|
183
|
-
def to_s
|
184
|
-
Writer.string(*ast)
|
215
|
+
def to_s(format: :ebnf)
|
216
|
+
Writer.string(*ast, format: format)
|
185
217
|
end
|
186
218
|
|
187
219
|
##
|
188
220
|
# Output formatted EBNF as HTML
|
221
|
+
#
|
222
|
+
# @param [:abnf, :ebnf, :isoebnf] format (:ebnf)
|
189
223
|
# @return [String]
|
190
|
-
def to_html
|
191
|
-
Writer.html(*ast)
|
224
|
+
def to_html(format: :ebnf)
|
225
|
+
Writer.html(*ast, format: format)
|
192
226
|
end
|
193
227
|
|
194
228
|
##
|
@@ -210,28 +244,22 @@ module EBNF
|
|
210
244
|
end
|
211
245
|
|
212
246
|
# Either output LL(1) BRANCH tables or rules for PEG parsing
|
213
|
-
if ast.first.
|
214
|
-
to_ruby_peg(output)
|
215
|
-
else
|
247
|
+
if ast.first.first
|
216
248
|
to_ruby_ll1(output)
|
249
|
+
else
|
250
|
+
to_ruby_peg(output)
|
217
251
|
end
|
218
252
|
unless output == $stdout
|
219
253
|
output.puts "end"
|
220
254
|
end
|
221
255
|
end
|
222
256
|
|
223
|
-
def dup
|
224
|
-
new_obj = super
|
225
|
-
new_obj.instance_variable_set(:@ast, @ast.dup)
|
226
|
-
new_obj
|
227
|
-
end
|
228
|
-
|
229
257
|
##
|
230
|
-
#
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
258
|
+
# Renumber, rule identifiers
|
259
|
+
def renumber!
|
260
|
+
ast.each_with_index do |rule, index|
|
261
|
+
rule.id = (index + 1).to_s
|
262
|
+
end
|
235
263
|
end
|
236
264
|
|
237
265
|
##
|
@@ -242,6 +270,7 @@ module EBNF
|
|
242
270
|
def to_ttl(prefix = nil, ns = "http://example.org/")
|
243
271
|
unless ast.empty?
|
244
272
|
[
|
273
|
+
"@prefix dc: <http://purl.org/dc/terms/>.",
|
245
274
|
"@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.",
|
246
275
|
"@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.",
|
247
276
|
("@prefix #{prefix}: <#{ns}>." if prefix),
|
@@ -254,7 +283,21 @@ module EBNF
|
|
254
283
|
].compact
|
255
284
|
end.join("\n") +
|
256
285
|
|
257
|
-
ast.
|
286
|
+
ast.map(&:to_ttl).join("\n")
|
287
|
+
end
|
288
|
+
|
289
|
+
def dup
|
290
|
+
new_obj = super
|
291
|
+
new_obj.instance_variable_set(:@ast, @ast.dup)
|
292
|
+
new_obj
|
293
|
+
end
|
294
|
+
|
295
|
+
##
|
296
|
+
# Find a rule given a symbol
|
297
|
+
# @param [Symbol] sym
|
298
|
+
# @return [Rule]
|
299
|
+
def find_rule(sym)
|
300
|
+
(@find ||= {})[sym] ||= ast.detect {|r| r.sym == sym}
|
258
301
|
end
|
259
302
|
|
260
303
|
def depth
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# This file is automatically generated by ebnf version 2.0.0
|
2
|
+
# Derived from etc/ebnf.ebnf
|
3
|
+
module EBNFMeta
|
4
|
+
RULES = [
|
5
|
+
EBNF::Rule.new(:ebnf, "1", [:star, :_ebnf_1]).extend(EBNF::PEG::Rule),
|
6
|
+
EBNF::Rule.new(:_ebnf_1, "1.1", [:alt, :declaration, :rule]).extend(EBNF::PEG::Rule),
|
7
|
+
EBNF::Rule.new(:declaration, "2", [:alt, "@terminals", :pass]).extend(EBNF::PEG::Rule),
|
8
|
+
EBNF::Rule.new(:rule, "3", [:seq, :LHS, :expression]).extend(EBNF::PEG::Rule),
|
9
|
+
EBNF::Rule.new(:expression, "4", [:seq, :alt]).extend(EBNF::PEG::Rule),
|
10
|
+
EBNF::Rule.new(:alt, "5", [:seq, :seq, :_alt_1]).extend(EBNF::PEG::Rule),
|
11
|
+
EBNF::Rule.new(:_alt_1, "5.1", [:star, :_alt_2]).extend(EBNF::PEG::Rule),
|
12
|
+
EBNF::Rule.new(:_alt_2, "5.2", [:seq, "|", :seq]).extend(EBNF::PEG::Rule),
|
13
|
+
EBNF::Rule.new(:seq, "6", [:plus, :diff]).extend(EBNF::PEG::Rule),
|
14
|
+
EBNF::Rule.new(:diff, "7", [:seq, :postfix, :_diff_1]).extend(EBNF::PEG::Rule),
|
15
|
+
EBNF::Rule.new(:_diff_1, "7.1", [:opt, :_diff_2]).extend(EBNF::PEG::Rule),
|
16
|
+
EBNF::Rule.new(:_diff_2, "7.2", [:seq, "-", :postfix]).extend(EBNF::PEG::Rule),
|
17
|
+
EBNF::Rule.new(:postfix, "8", [:seq, :primary, :_postfix_1]).extend(EBNF::PEG::Rule),
|
18
|
+
EBNF::Rule.new(:_postfix_1, "8.1", [:opt, :POSTFIX]).extend(EBNF::PEG::Rule),
|
19
|
+
EBNF::Rule.new(:primary, "9", [:alt, :HEX, :SYMBOL, :O_RANGE, :RANGE, :STRING1, :STRING2, :_primary_1]).extend(EBNF::PEG::Rule),
|
20
|
+
EBNF::Rule.new(:_primary_1, "9.1", [:seq, "(", :expression, ")"]).extend(EBNF::PEG::Rule),
|
21
|
+
EBNF::Rule.new(:pass, "10", [:seq, "@pass", :expression]).extend(EBNF::PEG::Rule),
|
22
|
+
EBNF::Rule.new(:_terminals, nil, [:seq], kind: :terminals).extend(EBNF::PEG::Rule),
|
23
|
+
EBNF::Rule.new(:LHS, "11", [:seq, :_LHS_1, :SYMBOL, :_LHS_2, "::="], kind: :terminal).extend(EBNF::PEG::Rule),
|
24
|
+
EBNF::Rule.new(:_LHS_1, "11.1", [:opt, :_LHS_3], kind: :terminal).extend(EBNF::PEG::Rule),
|
25
|
+
EBNF::Rule.new(:_LHS_3, "11.3", [:seq, "[", :SYMBOL, "]", :_LHS_4], kind: :terminal).extend(EBNF::PEG::Rule),
|
26
|
+
EBNF::Rule.new(:_LHS_4, "11.4", [:plus, " "], kind: :terminal).extend(EBNF::PEG::Rule),
|
27
|
+
EBNF::Rule.new(:_LHS_2, "11.2", [:star, " "], kind: :terminal).extend(EBNF::PEG::Rule),
|
28
|
+
EBNF::Rule.new(:SYMBOL, "12", [:plus, :_SYMBOL_1], kind: :terminal).extend(EBNF::PEG::Rule),
|
29
|
+
EBNF::Rule.new(:_SYMBOL_1, "12.1", [:alt, :_SYMBOL_2, :_SYMBOL_3, :_SYMBOL_4, "_", "."], kind: :terminal).extend(EBNF::PEG::Rule),
|
30
|
+
EBNF::Rule.new(:_SYMBOL_2, "12.2", [:range, "a-z"], kind: :terminal).extend(EBNF::PEG::Rule),
|
31
|
+
EBNF::Rule.new(:_SYMBOL_3, "12.3", [:range, "A-Z"], kind: :terminal).extend(EBNF::PEG::Rule),
|
32
|
+
EBNF::Rule.new(:_SYMBOL_4, "12.4", [:range, "0-9"], kind: :terminal).extend(EBNF::PEG::Rule),
|
33
|
+
EBNF::Rule.new(:HEX, "13", [:seq, "#x", :_HEX_1], kind: :terminal).extend(EBNF::PEG::Rule),
|
34
|
+
EBNF::Rule.new(:_HEX_1, "13.1", [:plus, :_HEX_2], kind: :terminal).extend(EBNF::PEG::Rule),
|
35
|
+
EBNF::Rule.new(:_HEX_2, "13.2", [:alt, :_HEX_3, :_HEX_4, :_HEX_5], kind: :terminal).extend(EBNF::PEG::Rule),
|
36
|
+
EBNF::Rule.new(:_HEX_3, "13.3", [:range, "a-f"], kind: :terminal).extend(EBNF::PEG::Rule),
|
37
|
+
EBNF::Rule.new(:_HEX_4, "13.4", [:range, "A-F"], kind: :terminal).extend(EBNF::PEG::Rule),
|
38
|
+
EBNF::Rule.new(:_HEX_5, "13.5", [:range, "0-9"], kind: :terminal).extend(EBNF::PEG::Rule),
|
39
|
+
EBNF::Rule.new(:RANGE, "14", [:seq, "[", :_RANGE_1, :_RANGE_2, :_RANGE_3], kind: :terminal).extend(EBNF::PEG::Rule),
|
40
|
+
EBNF::Rule.new(:_RANGE_1, "14.1", [:plus, :_RANGE_4], kind: :terminal).extend(EBNF::PEG::Rule),
|
41
|
+
EBNF::Rule.new(:_RANGE_4, "14.4", [:alt, :_RANGE_5, :_RANGE_6, :R_CHAR, :HEX], kind: :terminal).extend(EBNF::PEG::Rule),
|
42
|
+
EBNF::Rule.new(:_RANGE_5, "14.5", [:seq, :R_CHAR, "-", :R_CHAR], kind: :terminal).extend(EBNF::PEG::Rule),
|
43
|
+
EBNF::Rule.new(:_RANGE_6, "14.6", [:seq, :HEX, "-", :HEX], kind: :terminal).extend(EBNF::PEG::Rule),
|
44
|
+
EBNF::Rule.new(:_RANGE_2, "14.2", [:opt, "-"], kind: :terminal).extend(EBNF::PEG::Rule),
|
45
|
+
EBNF::Rule.new(:_RANGE_3, "14.3", [:diff, "]", :LHS], kind: :terminal).extend(EBNF::PEG::Rule),
|
46
|
+
EBNF::Rule.new(:O_RANGE, "15", [:seq, "[^", :_O_RANGE_1, :_O_RANGE_2, "]"], kind: :terminal).extend(EBNF::PEG::Rule),
|
47
|
+
EBNF::Rule.new(:_O_RANGE_1, "15.1", [:plus, :_O_RANGE_3], kind: :terminal).extend(EBNF::PEG::Rule),
|
48
|
+
EBNF::Rule.new(:_O_RANGE_3, "15.3", [:alt, :_O_RANGE_4, :_O_RANGE_5, :R_CHAR, :HEX], kind: :terminal).extend(EBNF::PEG::Rule),
|
49
|
+
EBNF::Rule.new(:_O_RANGE_4, "15.4", [:seq, :R_CHAR, "-", :R_CHAR], kind: :terminal).extend(EBNF::PEG::Rule),
|
50
|
+
EBNF::Rule.new(:_O_RANGE_5, "15.5", [:seq, :HEX, "-", :HEX], kind: :terminal).extend(EBNF::PEG::Rule),
|
51
|
+
EBNF::Rule.new(:_O_RANGE_2, "15.2", [:opt, "-"], kind: :terminal).extend(EBNF::PEG::Rule),
|
52
|
+
EBNF::Rule.new(:STRING1, "16", [:seq, "\"", :_STRING1_1, "\""], kind: :terminal).extend(EBNF::PEG::Rule),
|
53
|
+
EBNF::Rule.new(:_STRING1_1, "16.1", [:star, :_STRING1_2], kind: :terminal).extend(EBNF::PEG::Rule),
|
54
|
+
EBNF::Rule.new(:_STRING1_2, "16.2", [:diff, :CHAR, "\""], kind: :terminal).extend(EBNF::PEG::Rule),
|
55
|
+
EBNF::Rule.new(:STRING2, "17", [:seq, "'", :_STRING2_1, "'"], kind: :terminal).extend(EBNF::PEG::Rule),
|
56
|
+
EBNF::Rule.new(:_STRING2_1, "17.1", [:star, :_STRING2_2], kind: :terminal).extend(EBNF::PEG::Rule),
|
57
|
+
EBNF::Rule.new(:_STRING2_2, "17.2", [:diff, :CHAR, "'"], kind: :terminal).extend(EBNF::PEG::Rule),
|
58
|
+
EBNF::Rule.new(:CHAR, "18", [:alt, :_CHAR_1, :_CHAR_2, :_CHAR_3, :_CHAR_4], kind: :terminal).extend(EBNF::PEG::Rule),
|
59
|
+
EBNF::Rule.new(:_CHAR_1, "18.1", [:range, "#x9#xA#xD"], kind: :terminal).extend(EBNF::PEG::Rule),
|
60
|
+
EBNF::Rule.new(:_CHAR_2, "18.2", [:range, "#x20-#xD7FF"], kind: :terminal).extend(EBNF::PEG::Rule),
|
61
|
+
EBNF::Rule.new(:_CHAR_3, "18.3", [:range, "#xE000-#xFFFD"], kind: :terminal).extend(EBNF::PEG::Rule),
|
62
|
+
EBNF::Rule.new(:_CHAR_4, "18.4", [:range, "#x10000-#x10FFFF"], kind: :terminal).extend(EBNF::PEG::Rule),
|
63
|
+
EBNF::Rule.new(:R_CHAR, "19", [:diff, :CHAR, :_R_CHAR_1], kind: :terminal).extend(EBNF::PEG::Rule),
|
64
|
+
EBNF::Rule.new(:_R_CHAR_1, "19.1", [:alt, "]", "-", :HEX], kind: :terminal).extend(EBNF::PEG::Rule),
|
65
|
+
EBNF::Rule.new(:POSTFIX, "20", [:range, "?*+"], kind: :terminal).extend(EBNF::PEG::Rule),
|
66
|
+
EBNF::Rule.new(:PASS, "21", [:alt, :_PASS_1, :_PASS_2, :_PASS_3, :_PASS_4], kind: :terminal).extend(EBNF::PEG::Rule),
|
67
|
+
EBNF::Rule.new(:_PASS_1, "21.1", [:range, "#x9#xA#xD#x20"], kind: :terminal).extend(EBNF::PEG::Rule),
|
68
|
+
EBNF::Rule.new(:_PASS_2, "21.2", [:seq, :_PASS_5, :_PASS_6], kind: :terminal).extend(EBNF::PEG::Rule),
|
69
|
+
EBNF::Rule.new(:_PASS_5, "21.5", [:alt, :_PASS_7, "//"], kind: :terminal).extend(EBNF::PEG::Rule),
|
70
|
+
EBNF::Rule.new(:_PASS_7, "21.7", [:diff, "#", "#x"], kind: :terminal).extend(EBNF::PEG::Rule),
|
71
|
+
EBNF::Rule.new(:_PASS_6, "21.6", [:star, :_PASS_8], kind: :terminal).extend(EBNF::PEG::Rule),
|
72
|
+
EBNF::Rule.new(:_PASS_8, "21.8", [:range, "^#xA#xD"], kind: :terminal).extend(EBNF::PEG::Rule),
|
73
|
+
EBNF::Rule.new(:_PASS_3, "21.3", [:seq, "/*", :_PASS_9, "*/"], kind: :terminal).extend(EBNF::PEG::Rule),
|
74
|
+
EBNF::Rule.new(:_PASS_9, "21.9", [:star, :_PASS_10], kind: :terminal).extend(EBNF::PEG::Rule),
|
75
|
+
EBNF::Rule.new(:_PASS_10, "21.10", [:alt, :_PASS_11, :_PASS_12], kind: :terminal).extend(EBNF::PEG::Rule),
|
76
|
+
EBNF::Rule.new(:_PASS_11, "21.11", [:opt, :_PASS_13], kind: :terminal).extend(EBNF::PEG::Rule),
|
77
|
+
EBNF::Rule.new(:_PASS_13, "21.13", [:seq, "*", :_PASS_14], kind: :terminal).extend(EBNF::PEG::Rule),
|
78
|
+
EBNF::Rule.new(:_PASS_14, "21.14", [:range, "^/"], kind: :terminal).extend(EBNF::PEG::Rule),
|
79
|
+
EBNF::Rule.new(:_PASS_12, "21.12", [:range, "^*"], kind: :terminal).extend(EBNF::PEG::Rule),
|
80
|
+
EBNF::Rule.new(:_PASS_4, "21.4", [:seq, "(*", :_PASS_15, "*)"], kind: :terminal).extend(EBNF::PEG::Rule),
|
81
|
+
EBNF::Rule.new(:_PASS_15, "21.15", [:star, :_PASS_16], kind: :terminal).extend(EBNF::PEG::Rule),
|
82
|
+
EBNF::Rule.new(:_PASS_16, "21.16", [:alt, :_PASS_17, :_PASS_18], kind: :terminal).extend(EBNF::PEG::Rule),
|
83
|
+
EBNF::Rule.new(:_PASS_17, "21.17", [:opt, :_PASS_19], kind: :terminal).extend(EBNF::PEG::Rule),
|
84
|
+
EBNF::Rule.new(:_PASS_19, "21.19", [:seq, "*", :_PASS_20], kind: :terminal).extend(EBNF::PEG::Rule),
|
85
|
+
EBNF::Rule.new(:_PASS_20, "21.20", [:range, "^)"], kind: :terminal).extend(EBNF::PEG::Rule),
|
86
|
+
EBNF::Rule.new(:_PASS_18, "21.18", [:range, "^*"], kind: :terminal).extend(EBNF::PEG::Rule),
|
87
|
+
EBNF::Rule.new(:_pass, nil, [:seq, :PASS], kind: :pass).extend(EBNF::PEG::Rule),
|
88
|
+
]
|
89
|
+
end
|
90
|
+
|