ebnf 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +123 -11
- data/VERSION +1 -1
- data/bin/ebnf +3 -3
- data/etc/ebnf.ebnf +15 -9
- data/etc/ebnf.html +35 -9
- data/etc/ebnf.ll1.sxp +70 -50
- data/etc/ebnf.rb +87 -0
- data/etc/ebnf.sxp +18 -10
- data/etc/sparql.ll1.sxp +277 -102
- data/etc/sparql.rb +140 -0
- data/etc/turtle.ll1.sxp +27 -16
- data/etc/turtle.rb +13 -0
- data/lib/ebnf/base.rb +3 -2
- data/lib/ebnf/bnf.rb +1 -1
- data/lib/ebnf/ll1.rb +19 -9
- data/lib/ebnf/ll1/lexer.rb +15 -11
- data/lib/ebnf/ll1/parser.rb +34 -16
- data/lib/ebnf/ll1/scanner.rb +22 -8
- data/lib/ebnf/parser.rb +1 -1
- data/lib/ebnf/rule.rb +22 -10
- data/lib/ebnf/writer.rb +1 -1
- metadata +3 -3
data/etc/sparql.rb
CHANGED
@@ -45629,5 +45629,145 @@ module Branch
|
|
45629
45629
|
:DECIMAL_NEGATIVE,
|
45630
45630
|
:DOUBLE_NEGATIVE],
|
45631
45631
|
}.freeze
|
45632
|
+
CLEANUP = {
|
45633
|
+
:_Add_1 => :opt,
|
45634
|
+
:_AdditiveExpression_1 => :star,
|
45635
|
+
:_AdditiveExpression_3 => :merge,
|
45636
|
+
:_AdditiveExpression_8 => :opt,
|
45637
|
+
:_Aggregate_10 => :opt,
|
45638
|
+
:_Aggregate_11 => :opt,
|
45639
|
+
:_Aggregate_12 => :opt,
|
45640
|
+
:_Aggregate_13 => :opt,
|
45641
|
+
:_Aggregate_14 => :opt,
|
45642
|
+
:_Aggregate_15 => :opt,
|
45643
|
+
:_Aggregate_16 => :opt,
|
45644
|
+
:_Aggregate_8 => :opt,
|
45645
|
+
:_ArgList_2 => :opt,
|
45646
|
+
:_ArgList_3 => :star,
|
45647
|
+
:_ArgList_5 => :merge,
|
45648
|
+
:_AskQuery_1 => :star,
|
45649
|
+
:_AskQuery_2 => :merge,
|
45650
|
+
:_Clear_1 => :opt,
|
45651
|
+
:_CollectionPath_1 => :plus,
|
45652
|
+
:_CollectionPath_2 => :star,
|
45653
|
+
:_CollectionPath_3 => :merge,
|
45654
|
+
:_Collection_1 => :plus,
|
45655
|
+
:_Collection_2 => :star,
|
45656
|
+
:_Collection_3 => :merge,
|
45657
|
+
:_ConditionalAndExpression_1 => :star,
|
45658
|
+
:_ConditionalAndExpression_3 => :merge,
|
45659
|
+
:_ConditionalOrExpression_1 => :star,
|
45660
|
+
:_ConditionalOrExpression_3 => :merge,
|
45661
|
+
:_ConstructQuery_4 => :star,
|
45662
|
+
:_ConstructQuery_5 => :merge,
|
45663
|
+
:_ConstructQuery_6 => :star,
|
45664
|
+
:_ConstructQuery_7 => :opt,
|
45665
|
+
:_ConstructQuery_8 => :merge,
|
45666
|
+
:_ConstructTemplate_1 => :opt,
|
45667
|
+
:_ConstructTriples_1 => :opt,
|
45668
|
+
:_ConstructTriples_3 => :opt,
|
45669
|
+
:_Copy_1 => :opt,
|
45670
|
+
:_Create_1 => :opt,
|
45671
|
+
:_DescribeQuery_2 => :star,
|
45672
|
+
:_DescribeQuery_3 => :opt,
|
45673
|
+
:_DescribeQuery_4 => :plus,
|
45674
|
+
:_DescribeQuery_5 => :star,
|
45675
|
+
:_DescribeQuery_6 => :merge,
|
45676
|
+
:_DescribeQuery_7 => :merge,
|
45677
|
+
:_Drop_1 => :opt,
|
45678
|
+
:_ExpressionList_2 => :star,
|
45679
|
+
:_ExpressionList_4 => :merge,
|
45680
|
+
:_GraphOrDefault_2 => :opt,
|
45681
|
+
:_GroupClause_1 => :plus,
|
45682
|
+
:_GroupClause_2 => :star,
|
45683
|
+
:_GroupClause_3 => :merge,
|
45684
|
+
:_GroupCondition_2 => :opt,
|
45685
|
+
:_GroupGraphPatternSub_1 => :opt,
|
45686
|
+
:_GroupGraphPatternSub_2 => :star,
|
45687
|
+
:_GroupGraphPatternSub_4 => :merge,
|
45688
|
+
:_GroupGraphPatternSub_5 => :opt,
|
45689
|
+
:_GroupGraphPatternSub_6 => :opt,
|
45690
|
+
:_GroupOrUnionGraphPattern_1 => :star,
|
45691
|
+
:_GroupOrUnionGraphPattern_3 => :merge,
|
45692
|
+
:_HavingClause_1 => :plus,
|
45693
|
+
:_HavingClause_2 => :star,
|
45694
|
+
:_HavingClause_3 => :merge,
|
45695
|
+
:_InlineDataFull_10 => :merge,
|
45696
|
+
:_InlineDataFull_2 => :star,
|
45697
|
+
:_InlineDataFull_4 => :star,
|
45698
|
+
:_InlineDataFull_5 => :merge,
|
45699
|
+
:_InlineDataFull_7 => :merge,
|
45700
|
+
:_InlineDataFull_9 => :star,
|
45701
|
+
:_InlineDataOneVar_1 => :star,
|
45702
|
+
:_InlineDataOneVar_2 => :merge,
|
45703
|
+
:_LimitOffsetClauses_3 => :opt,
|
45704
|
+
:_LimitOffsetClauses_4 => :opt,
|
45705
|
+
:_Load_1 => :opt,
|
45706
|
+
:_Load_2 => :opt,
|
45707
|
+
:_Modify_1 => :opt,
|
45708
|
+
:_Modify_3 => :star,
|
45709
|
+
:_Modify_6 => :opt,
|
45710
|
+
:_Modify_7 => :merge,
|
45711
|
+
:_Move_1 => :opt,
|
45712
|
+
:_MultiplicativeExpression_1 => :star,
|
45713
|
+
:_MultiplicativeExpression_3 => :merge,
|
45714
|
+
:_ObjectListPath_1 => :star,
|
45715
|
+
:_ObjectListPath_3 => :merge,
|
45716
|
+
:_ObjectList_1 => :star,
|
45717
|
+
:_ObjectList_3 => :merge,
|
45718
|
+
:_OrderClause_1 => :plus,
|
45719
|
+
:_OrderClause_2 => :star,
|
45720
|
+
:_OrderClause_3 => :merge,
|
45721
|
+
:_PathAlternative_1 => :star,
|
45722
|
+
:_PathAlternative_3 => :merge,
|
45723
|
+
:_PathElt_1 => :opt,
|
45724
|
+
:_PathNegatedPropertySet_2 => :opt,
|
45725
|
+
:_PathNegatedPropertySet_4 => :star,
|
45726
|
+
:_PathNegatedPropertySet_6 => :merge,
|
45727
|
+
:_PathSequence_1 => :star,
|
45728
|
+
:_PathSequence_3 => :merge,
|
45729
|
+
:Prologue => :star,
|
45730
|
+
:_Prologue_2 => :merge,
|
45731
|
+
:PropertyList => :opt,
|
45732
|
+
:_PropertyListNotEmptyPath_2 => :star,
|
45733
|
+
:_PropertyListNotEmptyPath_4 => :merge,
|
45734
|
+
:_PropertyListNotEmptyPath_5 => :opt,
|
45735
|
+
:_PropertyListNotEmpty_1 => :star,
|
45736
|
+
:_PropertyListNotEmpty_3 => :merge,
|
45737
|
+
:_PropertyListNotEmpty_4 => :opt,
|
45738
|
+
:PropertyListPath => :opt,
|
45739
|
+
:_QuadsNotTriples_1 => :opt,
|
45740
|
+
:_Quads_1 => :opt,
|
45741
|
+
:_Quads_2 => :star,
|
45742
|
+
:_Quads_4 => :merge,
|
45743
|
+
:_Quads_5 => :opt,
|
45744
|
+
:_Quads_6 => :opt,
|
45745
|
+
:QueryUnit => :opt,
|
45746
|
+
:_RDFLiteral_1 => :opt,
|
45747
|
+
:_RegexExpression_1 => :opt,
|
45748
|
+
:_RelationalExpression_1 => :opt,
|
45749
|
+
:_SelectClause_1 => :opt,
|
45750
|
+
:_SelectClause_4 => :plus,
|
45751
|
+
:_SelectClause_6 => :star,
|
45752
|
+
:_SelectClause_7 => :merge,
|
45753
|
+
:_SelectQuery_1 => :star,
|
45754
|
+
:_SelectQuery_2 => :merge,
|
45755
|
+
:_ServiceGraphPattern_1 => :opt,
|
45756
|
+
:_SolutionModifier_1 => :opt,
|
45757
|
+
:_SolutionModifier_2 => :opt,
|
45758
|
+
:_SolutionModifier_3 => :opt,
|
45759
|
+
:_SolutionModifier_4 => :opt,
|
45760
|
+
:_StrReplaceExpression_1 => :opt,
|
45761
|
+
:_SubstringExpression_1 => :opt,
|
45762
|
+
:_TriplesBlock_1 => :opt,
|
45763
|
+
:_TriplesBlock_3 => :opt,
|
45764
|
+
:_TriplesTemplate_1 => :opt,
|
45765
|
+
:_TriplesTemplate_3 => :opt,
|
45766
|
+
:_Update_1 => :opt,
|
45767
|
+
:_Update_3 => :opt,
|
45768
|
+
:ValuesClause => :opt,
|
45769
|
+
:_WhereClause_1 => :opt,
|
45770
|
+
:_iriOrFunction_1 => :opt,
|
45771
|
+
}.freeze
|
45632
45772
|
end
|
45633
45773
|
|
data/etc/turtle.ll1.sxp
CHANGED
@@ -5,11 +5,13 @@
|
|
5
5
|
(first "(" "@base" "@prefix" ANON BLANK_NODE_LABEL IRIREF PNAME_LN PNAME_NS
|
6
6
|
SPARQL_BASE SPARQL_PREFIX "[" _eps )
|
7
7
|
(follow _eof)
|
8
|
+
(cleanup star)
|
8
9
|
(alt _empty _turtleDoc_1))
|
9
10
|
(rule _turtleDoc_1 "1.1"
|
10
11
|
(first "(" "@base" "@prefix" ANON BLANK_NODE_LABEL IRIREF PNAME_LN PNAME_NS
|
11
12
|
SPARQL_BASE SPARQL_PREFIX "[" )
|
12
13
|
(follow _eof)
|
14
|
+
(cleanup merge)
|
13
15
|
(seq statement turtleDoc))
|
14
16
|
(rule _turtleDoc_2 "1.2"
|
15
17
|
(first "(" "@base" "@prefix" ANON BLANK_NODE_LABEL IRIREF PNAME_LN PNAME_NS
|
@@ -69,6 +71,7 @@
|
|
69
71
|
(rule _triples_3 "6.3"
|
70
72
|
(first IRIREF PNAME_LN PNAME_NS _eps "a")
|
71
73
|
(follow ".")
|
74
|
+
(cleanup opt)
|
72
75
|
(alt _empty predicateObjectList))
|
73
76
|
(rule _triples_4 "6.4"
|
74
77
|
(first IRIREF PNAME_LN PNAME_NS "a")
|
@@ -85,6 +88,7 @@
|
|
85
88
|
(rule _predicateObjectList_1 "7.1"
|
86
89
|
(first ";" _eps)
|
87
90
|
(follow "." "]")
|
91
|
+
(cleanup star)
|
88
92
|
(alt _empty _predicateObjectList_3))
|
89
93
|
(rule _predicateObjectList_2 "7.2"
|
90
94
|
(first ";")
|
@@ -93,10 +97,12 @@
|
|
93
97
|
(rule _predicateObjectList_3 "7.3"
|
94
98
|
(first ";")
|
95
99
|
(follow "." "]")
|
100
|
+
(cleanup merge)
|
96
101
|
(seq _predicateObjectList_2 _predicateObjectList_1))
|
97
102
|
(rule _predicateObjectList_4 "7.4"
|
98
103
|
(first IRIREF PNAME_LN PNAME_NS _eps "a")
|
99
104
|
(follow "." ";" "]")
|
105
|
+
(cleanup opt)
|
100
106
|
(alt _empty _predicateObjectList_5))
|
101
107
|
(rule _predicateObjectList_5 "7.5"
|
102
108
|
(first IRIREF PNAME_LN PNAME_NS "a")
|
@@ -131,11 +137,13 @@
|
|
131
137
|
(rule _objectList_1 "8.1"
|
132
138
|
(first "," _eps)
|
133
139
|
(follow "." ";" "]")
|
140
|
+
(cleanup star)
|
134
141
|
(alt _empty _objectList_3))
|
135
142
|
(rule _objectList_2 "8.2" (first ",") (follow "," "." ";" "]") (seq "," object))
|
136
143
|
(rule _objectList_3 "8.3"
|
137
144
|
(first ",")
|
138
145
|
(follow "." ";" "]")
|
146
|
+
(cleanup merge)
|
139
147
|
(seq _objectList_2 _objectList_1))
|
140
148
|
(rule _objectList_4 "8.4" (first "," _eps) (follow "." ";" "]") (seq _objectList_1))
|
141
149
|
(rule _objectList_5 "8.5" (first "," _eps) (follow "." ";" "]") (seq _objectList_1))
|
@@ -213,12 +221,14 @@
|
|
213
221
|
PNAME_NS STRING_LITERAL_LONG_QUOTE STRING_LITERAL_LONG_SINGLE_QUOTE
|
214
222
|
STRING_LITERAL_QUOTE STRING_LITERAL_SINGLE_QUOTE "[" _eps "false" "true" )
|
215
223
|
(follow ")")
|
224
|
+
(cleanup star)
|
216
225
|
(alt _empty _collection_2))
|
217
226
|
(rule _collection_2 "15.2"
|
218
227
|
(first "(" ANON BLANK_NODE_LABEL DECIMAL DOUBLE INTEGER IRIREF PNAME_LN
|
219
228
|
PNAME_NS STRING_LITERAL_LONG_QUOTE STRING_LITERAL_LONG_SINGLE_QUOTE
|
220
229
|
STRING_LITERAL_QUOTE STRING_LITERAL_SINGLE_QUOTE "[" "false" "true" )
|
221
230
|
(follow ")")
|
231
|
+
(cleanup merge)
|
222
232
|
(seq object _collection_1))
|
223
233
|
(rule _collection_3 "15.3"
|
224
234
|
(first "(" ")" ANON BLANK_NODE_LABEL DECIMAL DOUBLE INTEGER IRIREF PNAME_LN
|
@@ -279,6 +289,11 @@
|
|
279
289
|
(seq "\"\"\"" (seq (opt (alt "\"" "\"\"")) (range "^\"] | ECHAR | UCHAR ))* '\"\"\"'"))))
|
280
290
|
(terminal UCHAR "26"
|
281
291
|
(alt (seq "u" HEX HEX HEX HEX) (seq "U" HEX HEX HEX HEX HEX HEX HEX HEX)))
|
292
|
+
(rule _sparqlPrefix_1 "28s.1"
|
293
|
+
(first PNAME_NS)
|
294
|
+
(follow "(" "@base" "@prefix" ANON BLANK_NODE_LABEL IRIREF PNAME_LN PNAME_NS
|
295
|
+
SPARQL_BASE SPARQL_PREFIX "[" _eof )
|
296
|
+
(seq PNAME_NS IRIREF))
|
282
297
|
(rule sparqlPrefix "28s"
|
283
298
|
(first SPARQL_PREFIX)
|
284
299
|
(follow "(" "@base" "@prefix" ANON BLANK_NODE_LABEL IRIREF PNAME_LN PNAME_NS
|
@@ -286,28 +301,24 @@
|
|
286
301
|
(seq SPARQL_PREFIX PNAME_NS IRIREF))
|
287
302
|
(terminal SPARQL_PREFIX "28t"
|
288
303
|
(seq (range "Pp") (range "Rr") (range "Ee") (range "Ff") (range "Ii") (range "Xx")))
|
289
|
-
(
|
290
|
-
|
304
|
+
(terminal SPARQL_BASE "29t" (seq (range "Bb") (range "Aa") (range "Ss") (range "Ee")))
|
305
|
+
(rule _sparqlBase_1 "29s.1"
|
306
|
+
(first IRIREF)
|
291
307
|
(follow "(" "@base" "@prefix" ANON BLANK_NODE_LABEL IRIREF PNAME_LN PNAME_NS
|
292
308
|
SPARQL_BASE SPARQL_PREFIX "[" _eof )
|
293
|
-
(seq
|
309
|
+
(seq IRIREF))
|
294
310
|
(rule sparqlBase "29s"
|
295
311
|
(first SPARQL_BASE)
|
296
312
|
(follow "(" "@base" "@prefix" ANON BLANK_NODE_LABEL IRIREF PNAME_LN PNAME_NS
|
297
313
|
SPARQL_BASE SPARQL_PREFIX "[" _eof )
|
298
314
|
(seq SPARQL_BASE IRIREF))
|
299
|
-
(terminal SPARQL_BASE "29t" (seq (range "Bb") (range "Aa") (range "Ss") (range "Ee")))
|
300
|
-
(rule _sparqlBase_1 "29s.1"
|
301
|
-
(first IRIREF)
|
302
|
-
(follow "(" "@base" "@prefix" ANON BLANK_NODE_LABEL IRIREF PNAME_LN PNAME_NS
|
303
|
-
SPARQL_BASE SPARQL_PREFIX "[" _eof )
|
304
|
-
(seq IRIREF))
|
305
315
|
(rule _RDFLiteral_1 "128s.1"
|
306
316
|
(first LANGTAG "^^" _eps)
|
307
317
|
(follow "(" ")" "," "." ";" ANON BLANK_NODE_LABEL DECIMAL DOUBLE INTEGER
|
308
318
|
IRIREF PNAME_LN PNAME_NS STRING_LITERAL_LONG_QUOTE
|
309
319
|
STRING_LITERAL_LONG_SINGLE_QUOTE STRING_LITERAL_QUOTE
|
310
320
|
STRING_LITERAL_SINGLE_QUOTE "[" "]" "false" "true" )
|
321
|
+
(cleanup opt)
|
311
322
|
(alt _empty _RDFLiteral_2))
|
312
323
|
(rule _RDFLiteral_3 "128s.3"
|
313
324
|
(first "^^")
|
@@ -316,13 +327,6 @@
|
|
316
327
|
STRING_LITERAL_LONG_SINGLE_QUOTE STRING_LITERAL_QUOTE
|
317
328
|
STRING_LITERAL_SINGLE_QUOTE "[" "]" "false" "true" )
|
318
329
|
(seq "^^" iri))
|
319
|
-
(rule _RDFLiteral_4 "128s.4"
|
320
|
-
(first LANGTAG "^^" _eps)
|
321
|
-
(follow "(" ")" "," "." ";" ANON BLANK_NODE_LABEL DECIMAL DOUBLE INTEGER
|
322
|
-
IRIREF PNAME_LN PNAME_NS STRING_LITERAL_LONG_QUOTE
|
323
|
-
STRING_LITERAL_LONG_SINGLE_QUOTE STRING_LITERAL_QUOTE
|
324
|
-
STRING_LITERAL_SINGLE_QUOTE "[" "]" "false" "true" )
|
325
|
-
(seq _RDFLiteral_1))
|
326
330
|
(rule _RDFLiteral_2 "128s.2"
|
327
331
|
(first LANGTAG "^^")
|
328
332
|
(follow "(" ")" "," "." ";" ANON BLANK_NODE_LABEL DECIMAL DOUBLE INTEGER
|
@@ -338,6 +342,13 @@
|
|
338
342
|
STRING_LITERAL_LONG_SINGLE_QUOTE STRING_LITERAL_QUOTE
|
339
343
|
STRING_LITERAL_SINGLE_QUOTE "[" "]" "false" "true" )
|
340
344
|
(seq String _RDFLiteral_1))
|
345
|
+
(rule _RDFLiteral_4 "128s.4"
|
346
|
+
(first LANGTAG "^^" _eps)
|
347
|
+
(follow "(" ")" "," "." ";" ANON BLANK_NODE_LABEL DECIMAL DOUBLE INTEGER
|
348
|
+
IRIREF PNAME_LN PNAME_NS STRING_LITERAL_LONG_QUOTE
|
349
|
+
STRING_LITERAL_LONG_SINGLE_QUOTE STRING_LITERAL_QUOTE
|
350
|
+
STRING_LITERAL_SINGLE_QUOTE "[" "]" "false" "true" )
|
351
|
+
(seq _RDFLiteral_1))
|
341
352
|
(rule BooleanLiteral "133s"
|
342
353
|
(first "false" "true")
|
343
354
|
(follow "(" ")" "," "." ";" ANON BLANK_NODE_LABEL DECIMAL DOUBLE INTEGER
|
data/etc/turtle.rb
CHANGED
@@ -1466,5 +1466,18 @@ module Branch
|
|
1466
1466
|
:STRING_LITERAL_LONG_SINGLE_QUOTE,
|
1467
1467
|
:STRING_LITERAL_LONG_QUOTE],
|
1468
1468
|
}.freeze
|
1469
|
+
CLEANUP = {
|
1470
|
+
:_RDFLiteral_1 => :opt,
|
1471
|
+
:_collection_1 => :star,
|
1472
|
+
:_collection_2 => :merge,
|
1473
|
+
:_objectList_1 => :star,
|
1474
|
+
:_objectList_3 => :merge,
|
1475
|
+
:_predicateObjectList_1 => :star,
|
1476
|
+
:_predicateObjectList_3 => :merge,
|
1477
|
+
:_predicateObjectList_4 => :opt,
|
1478
|
+
:_triples_3 => :opt,
|
1479
|
+
:turtleDoc => :star,
|
1480
|
+
:_turtleDoc_1 => :merge,
|
1481
|
+
}.freeze
|
1469
1482
|
end
|
1470
1483
|
|
data/lib/ebnf/base.rb
CHANGED
@@ -122,7 +122,7 @@ module EBNF
|
|
122
122
|
# @option options [Symbol] :format (:ebnf)
|
123
123
|
# Format of input, one of :ebnf, or :sxp
|
124
124
|
def initialize(input, options = {})
|
125
|
-
@options = {:
|
125
|
+
@options = {format: :ebnf}.merge(options)
|
126
126
|
@lineno, @depth, @errors = 1, 0, []
|
127
127
|
terminal = false
|
128
128
|
@ast = []
|
@@ -144,7 +144,7 @@ module EBNF
|
|
144
144
|
terminal = true
|
145
145
|
when /^@pass\s*(.*)$/m
|
146
146
|
expr = expression($1).first
|
147
|
-
rule = Rule.new(nil, nil, expr, :
|
147
|
+
rule = Rule.new(nil, nil, expr, kind: :pass)
|
148
148
|
rule.orig = expr
|
149
149
|
@ast << rule
|
150
150
|
else
|
@@ -213,6 +213,7 @@ module EBNF
|
|
213
213
|
self.outputTable(output, 'TERMINALS', self.terminals, 1)
|
214
214
|
self.outputTable(output, 'FIRST', self.first, 1)
|
215
215
|
self.outputTable(output, 'FOLLOW', self.follow, 1)
|
216
|
+
self.outputTable(output, 'CLEANUP', self.cleanup, 1)
|
216
217
|
self.outputTable(output, 'PASS', [self.pass], 1) if self.pass
|
217
218
|
unless output == STDOUT
|
218
219
|
output.puts "end"
|
data/lib/ebnf/bnf.rb
CHANGED
@@ -8,7 +8,7 @@ module EBNF
|
|
8
8
|
# @return [ENBF] self
|
9
9
|
def make_bnf
|
10
10
|
progress("make_bnf") {"Start: #{@ast.length} rules"}
|
11
|
-
new_ast = [Rule.new(:_empty, "0", [:seq], :
|
11
|
+
new_ast = [Rule.new(:_empty, "0", [:seq], kind: :rule)]
|
12
12
|
|
13
13
|
ast.each do |rule|
|
14
14
|
debug("make_bnf") {"expand from: #{rule.inspect}"}
|
data/lib/ebnf/ll1.rb
CHANGED
@@ -12,14 +12,21 @@ module EBNF
|
|
12
12
|
|
13
13
|
# First table
|
14
14
|
#
|
15
|
-
# @return [Hash{Symbol
|
15
|
+
# @return [Hash{Symbol => Array<String, Symbol>}]
|
16
16
|
attr_reader :first
|
17
17
|
|
18
18
|
# Follow table
|
19
19
|
#
|
20
|
-
# @return [Hash{Symbol
|
20
|
+
# @return [Hash{Symbol => Array<String, Symbol>}]
|
21
21
|
attr_reader :follow
|
22
22
|
|
23
|
+
# EBNF Cleanup table
|
24
|
+
#
|
25
|
+
# The list of terminals used in the grammar.
|
26
|
+
#
|
27
|
+
# @return [Hash{Symbol => Symbol}]
|
28
|
+
attr_reader :cleanup
|
29
|
+
|
23
30
|
# Terminal table
|
24
31
|
#
|
25
32
|
# The list of terminals used in the grammar.
|
@@ -175,18 +182,20 @@ module EBNF
|
|
175
182
|
@first = ast.
|
176
183
|
select(&:first).
|
177
184
|
inject({}) {|memo, r|
|
178
|
-
memo
|
179
|
-
memo
|
185
|
+
memo.merge(r.sym => r.first)
|
180
186
|
}
|
181
187
|
@follow = ast.
|
182
188
|
select(&:follow).
|
183
189
|
inject({}) {|memo, r|
|
184
|
-
memo
|
185
|
-
memo
|
190
|
+
memo.merge(r.sym => r.follow)
|
186
191
|
}
|
192
|
+
|
193
|
+
@cleanup = ast.
|
194
|
+
select(&:cleanup).
|
195
|
+
inject({}) {|memo, r| memo.merge(r.sym => r.cleanup)}
|
196
|
+
|
187
197
|
@terminals = ast.map {|r| Array(r.first) + Array(r.follow)}.flatten.uniq
|
188
198
|
@terminals = (@terminals - [:_eps, :_eof]).sort_by{|t| t.to_s.sub(/^_/, '')}
|
189
|
-
|
190
199
|
# FIXME: assumes that this is a (seq :PASS), or similar
|
191
200
|
if pass = ast.detect {|r| r.pass?}
|
192
201
|
@pass = pass.expr.last
|
@@ -228,7 +237,7 @@ module EBNF
|
|
228
237
|
# @param [IO, StringIO] io
|
229
238
|
# @param [String] name of the table constant
|
230
239
|
# @param [String] table
|
231
|
-
# to output, one of {#branch}, {#first}, {#follow}, or {#terminals}
|
240
|
+
# to output, one of {#branch}, {#first}, {#follow}, {#cleanup} or {#terminals}
|
232
241
|
# @param [Integer] indent = 0
|
233
242
|
def outputTable(io, name, table, indent = 0)
|
234
243
|
ind0 = ' ' * indent
|
@@ -239,6 +248,8 @@ module EBNF
|
|
239
248
|
io.puts "#{ind0}#{name} = {"
|
240
249
|
table.keys.sort_by{|t| t.to_s.sub(/^_/, '')}.each do |prod|
|
241
250
|
case table[prod]
|
251
|
+
when Symbol, String
|
252
|
+
io.puts "#{ind1}#{prod.inspect} => #{table[prod].inspect},"
|
242
253
|
when Array
|
243
254
|
list = table[prod].map(&:inspect).join(",\n#{ind2}")
|
244
255
|
io.puts "#{ind1}#{prod.inspect} => [\n#{ind2}#{list}],"
|
@@ -306,7 +317,6 @@ module EBNF
|
|
306
317
|
# A First/First conflict appears when there are two rules having
|
307
318
|
# the same first, so the parser can't know which one to choose.
|
308
319
|
if branchDict.has_key?(f)
|
309
|
-
#require 'byebug'; byebug
|
310
320
|
error("First/First Conflict: #{f.inspect} is the condition for both #{prod_rule.sym} and #{branchDict[f].first}")
|
311
321
|
end
|
312
322
|
|
data/lib/ebnf/ll1/lexer.rb
CHANGED
@@ -180,27 +180,28 @@ module EBNF::LL1
|
|
180
180
|
##
|
181
181
|
# Returns first token in input stream
|
182
182
|
#
|
183
|
+
# @param [Array[Symbol]] types Optional set of types for restricting terminals examined
|
183
184
|
# @return [Token]
|
184
|
-
def first
|
185
|
+
def first(*types)
|
185
186
|
return nil unless scanner
|
186
187
|
|
187
188
|
@first ||= begin
|
188
189
|
{} while !scanner.eos? && skip_whitespace
|
189
190
|
return @scanner = nil if scanner.eos?
|
190
191
|
|
191
|
-
token = match_token
|
192
|
+
token = match_token(*types)
|
192
193
|
|
193
194
|
if token.nil?
|
194
195
|
lexme = (scanner.rest.split(@whitespace || /\s/).first rescue nil) || scanner.rest
|
195
196
|
raise Error.new("Invalid token #{lexme[0..100].inspect}",
|
196
|
-
:
|
197
|
+
input: scanner.rest[0..100], token: lexme, lineno: lineno)
|
197
198
|
end
|
198
199
|
|
199
200
|
token
|
200
201
|
end
|
201
202
|
rescue ArgumentError, Encoding::CompatibilityError => e
|
202
203
|
raise Error.new(e.message,
|
203
|
-
:
|
204
|
+
input: (scanner.rest[0..100] rescue '??'), token: lexme, lineno: lineno)
|
204
205
|
rescue Error
|
205
206
|
raise
|
206
207
|
rescue
|
@@ -221,9 +222,10 @@ module EBNF::LL1
|
|
221
222
|
##
|
222
223
|
# Skip input until a token is matched
|
223
224
|
#
|
225
|
+
# @param [Array[Symbol]] types Optional set of types for restricting terminals examined
|
224
226
|
# @return [Token]
|
225
|
-
def recover
|
226
|
-
until scanner.eos? || tok = match_token
|
227
|
+
def recover(*types)
|
228
|
+
until scanner.eos? || tok = match_token(*types)
|
227
229
|
if scanner.skip_until(@whitespace || /\s/m).nil? # Skip past current "token"
|
228
230
|
# No whitespace at the end, must be and end of string
|
229
231
|
scanner.terminate
|
@@ -259,11 +261,13 @@ module EBNF::LL1
|
|
259
261
|
# track this with the resulting {Token}, so that comparisons
|
260
262
|
# with that token are also case insensitive
|
261
263
|
#
|
264
|
+
# @param [Array[Symbol]] types Optional set of types for restricting terminals examined
|
262
265
|
# @return [Token]
|
263
|
-
def match_token
|
266
|
+
def match_token(*types)
|
264
267
|
@terminals.each do |term|
|
268
|
+
next unless types.empty? || types.include?(term.type)
|
265
269
|
#STDERR.puts "match[#{term.type}] #{scanner.rest[0..100].inspect} against #{term.regexp.inspect}" #if term.type == :STRING_LITERAL_SINGLE_QUOTE
|
266
|
-
if term.partial_regexp && scanner.match?(term.partial_regexp) && !scanner.match?(term.regexp)
|
270
|
+
if term.partial_regexp && scanner.match?(term.partial_regexp) && !scanner.match?(term.regexp) && scanner.respond_to?(:ensure_buffer_full)
|
267
271
|
scanner.ensure_buffer_full
|
268
272
|
end
|
269
273
|
|
@@ -350,7 +354,7 @@ module EBNF::LL1
|
|
350
354
|
# @param [Hash{Symbol => Object}] options
|
351
355
|
# @return [Token]
|
352
356
|
def token(type, value, options = {})
|
353
|
-
Token.new(type, value, options.merge(:
|
357
|
+
Token.new(type, value, options.merge(lineno: lineno))
|
354
358
|
end
|
355
359
|
|
356
360
|
##
|
@@ -442,7 +446,7 @@ module EBNF::LL1
|
|
442
446
|
#
|
443
447
|
# @return [Hash]
|
444
448
|
def to_hash
|
445
|
-
{:
|
449
|
+
{type: @type, value: @value}
|
446
450
|
end
|
447
451
|
|
448
452
|
##
|
@@ -480,7 +484,7 @@ module EBNF::LL1
|
|
480
484
|
# @example Raising a lexer error
|
481
485
|
# raise EBNF::LL1::Lexer::Error.new(
|
482
486
|
# "invalid token '%' on line 10",
|
483
|
-
# :
|
487
|
+
# input: query, token: '%', lineno: 9)
|
484
488
|
#
|
485
489
|
# @see http://ruby-doc.org/core/classes/StandardError.html
|
486
490
|
class Error < StandardError
|