rley 0.7.06 → 0.8.01
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/.rubocop.yml +362 -62
- data/.travis.yml +6 -6
- data/CHANGELOG.md +20 -4
- data/LICENSE.txt +1 -1
- data/README.md +7 -7
- data/examples/NLP/engtagger.rb +193 -190
- data/examples/NLP/nano_eng/nano_en_demo.rb +7 -11
- data/examples/NLP/nano_eng/nano_grammar.rb +21 -21
- data/examples/NLP/pico_en_demo.rb +2 -2
- data/examples/data_formats/JSON/cli_options.rb +1 -1
- data/examples/data_formats/JSON/json_ast_builder.rb +21 -27
- data/examples/data_formats/JSON/json_ast_nodes.rb +12 -21
- data/examples/data_formats/JSON/json_demo.rb +1 -2
- data/examples/data_formats/JSON/json_grammar.rb +13 -13
- data/examples/data_formats/JSON/json_lexer.rb +8 -8
- data/examples/data_formats/JSON/json_minifier.rb +1 -1
- data/examples/general/calc_iter1/calc_ast_builder.rb +13 -10
- data/examples/general/calc_iter1/calc_ast_nodes.rb +23 -37
- data/examples/general/calc_iter1/calc_grammar.rb +7 -6
- data/examples/general/calc_iter1/calc_lexer.rb +6 -4
- data/examples/general/calc_iter1/spec/calculator_spec.rb +5 -5
- data/examples/general/calc_iter2/calc_ast_builder.rb +5 -3
- data/examples/general/calc_iter2/calc_ast_nodes.rb +27 -43
- data/examples/general/calc_iter2/calc_grammar.rb +12 -12
- data/examples/general/calc_iter2/calc_lexer.rb +11 -10
- data/examples/general/calc_iter2/spec/calculator_spec.rb +26 -26
- data/examples/general/left.rb +2 -2
- data/examples/general/right.rb +2 -2
- data/lib/rley.rb +1 -1
- data/lib/rley/base/dotted_item.rb +28 -31
- data/lib/rley/base/grm_items_builder.rb +6 -0
- data/lib/rley/constants.rb +2 -2
- data/lib/rley/engine.rb +22 -25
- data/lib/rley/formatter/asciitree.rb +3 -3
- data/lib/rley/formatter/bracket_notation.rb +1 -8
- data/lib/rley/formatter/debug.rb +6 -6
- data/lib/rley/formatter/json.rb +2 -2
- data/lib/rley/gfg/call_edge.rb +1 -1
- data/lib/rley/gfg/edge.rb +5 -5
- data/lib/rley/gfg/end_vertex.rb +2 -6
- data/lib/rley/gfg/epsilon_edge.rb +1 -5
- data/lib/rley/gfg/grm_flow_graph.rb +27 -23
- data/lib/rley/gfg/item_vertex.rb +10 -10
- data/lib/rley/gfg/non_terminal_vertex.rb +4 -4
- data/lib/rley/gfg/scan_edge.rb +1 -1
- data/lib/rley/gfg/shortcut_edge.rb +2 -2
- data/lib/rley/gfg/start_vertex.rb +4 -8
- data/lib/rley/gfg/vertex.rb +43 -39
- data/lib/rley/interface.rb +16 -0
- data/lib/rley/lexical/token_range.rb +6 -6
- data/lib/rley/notation/all_notation_nodes.rb +2 -0
- data/lib/rley/notation/ast_builder.rb +191 -0
- data/lib/rley/notation/ast_node.rb +44 -0
- data/lib/rley/notation/ast_visitor.rb +113 -0
- data/lib/rley/notation/grammar.rb +49 -0
- data/lib/rley/notation/grammar_builder.rb +504 -0
- data/lib/rley/notation/grouping_node.rb +23 -0
- data/lib/rley/notation/parser.rb +56 -0
- data/lib/rley/notation/sequence_node.rb +35 -0
- data/lib/rley/notation/symbol_node.rb +29 -0
- data/lib/rley/notation/tokenizer.rb +192 -0
- data/lib/rley/parse_forest_visitor.rb +5 -5
- data/lib/rley/parse_rep/ast_base_builder.rb +48 -11
- data/lib/rley/parse_rep/cst_builder.rb +5 -6
- data/lib/rley/parse_rep/parse_forest_builder.rb +22 -18
- data/lib/rley/parse_rep/parse_forest_factory.rb +3 -3
- data/lib/rley/parse_rep/parse_rep_creator.rb +14 -16
- data/lib/rley/parse_rep/parse_tree_builder.rb +4 -4
- data/lib/rley/parse_rep/parse_tree_factory.rb +27 -27
- data/lib/rley/parse_tree_visitor.rb +1 -1
- data/lib/rley/parser/error_reason.rb +4 -5
- data/lib/rley/parser/gfg_chart.rb +118 -26
- data/lib/rley/parser/gfg_parsing.rb +22 -33
- data/lib/rley/parser/parse_entry.rb +25 -31
- data/lib/rley/parser/parse_entry_set.rb +19 -16
- data/lib/rley/parser/parse_entry_tracker.rb +4 -4
- data/lib/rley/parser/parse_tracer.rb +13 -13
- data/lib/rley/parser/parse_walker_factory.rb +23 -28
- data/lib/rley/ptree/non_terminal_node.rb +7 -5
- data/lib/rley/ptree/parse_tree.rb +3 -3
- data/lib/rley/ptree/parse_tree_node.rb +5 -5
- data/lib/rley/ptree/terminal_node.rb +7 -7
- data/lib/rley/rley_error.rb +12 -12
- data/lib/rley/sppf/alternative_node.rb +6 -6
- data/lib/rley/sppf/composite_node.rb +7 -7
- data/lib/rley/sppf/epsilon_node.rb +3 -3
- data/lib/rley/sppf/leaf_node.rb +3 -3
- data/lib/rley/sppf/parse_forest.rb +16 -16
- data/lib/rley/sppf/sppf_node.rb +7 -8
- data/lib/rley/sppf/token_node.rb +3 -3
- data/lib/rley/syntax/{grammar_builder.rb → base_grammar_builder.rb} +61 -23
- data/lib/rley/syntax/grammar.rb +5 -5
- data/lib/rley/syntax/grm_symbol.rb +7 -7
- data/lib/rley/syntax/match_closest.rb +43 -0
- data/lib/rley/syntax/non_terminal.rb +9 -15
- data/lib/rley/syntax/production.rb +16 -10
- data/lib/rley/syntax/symbol_seq.rb +7 -9
- data/lib/rley/syntax/terminal.rb +4 -5
- data/lib/rley/syntax/verbatim_symbol.rb +3 -3
- data/lib/support/base_tokenizer.rb +19 -18
- data/spec/rley/base/dotted_item_spec.rb +2 -2
- data/spec/rley/engine_spec.rb +23 -21
- data/spec/rley/formatter/asciitree_spec.rb +7 -7
- data/spec/rley/formatter/bracket_notation_spec.rb +13 -13
- data/spec/rley/formatter/json_spec.rb +1 -1
- data/spec/rley/gfg/end_vertex_spec.rb +5 -5
- data/spec/rley/gfg/grm_flow_graph_spec.rb +2 -2
- data/spec/rley/gfg/item_vertex_spec.rb +10 -10
- data/spec/rley/gfg/non_terminal_vertex_spec.rb +3 -3
- data/spec/rley/gfg/shortcut_edge_spec.rb +1 -1
- data/spec/rley/gfg/start_vertex_spec.rb +5 -5
- data/spec/rley/gfg/vertex_spec.rb +3 -3
- data/spec/rley/lexical/token_range_spec.rb +16 -16
- data/spec/rley/lexical/token_spec.rb +2 -2
- data/spec/rley/notation/grammar_builder_spec.rb +302 -0
- data/spec/rley/notation/parser_spec.rb +184 -0
- data/spec/rley/notation/tokenizer_spec.rb +370 -0
- data/spec/rley/parse_forest_visitor_spec.rb +165 -163
- data/spec/rley/parse_rep/ambiguous_parse_spec.rb +44 -44
- data/spec/rley/parse_rep/ast_builder_spec.rb +6 -7
- data/spec/rley/parse_rep/cst_builder_spec.rb +5 -5
- data/spec/rley/parse_rep/groucho_spec.rb +24 -26
- data/spec/rley/parse_rep/parse_forest_builder_spec.rb +27 -27
- data/spec/rley/parse_rep/parse_forest_factory_spec.rb +8 -8
- data/spec/rley/parse_rep/parse_tree_factory_spec.rb +3 -3
- data/spec/rley/parse_tree_visitor_spec.rb +10 -8
- data/spec/rley/parser/dangling_else_spec.rb +445 -0
- data/spec/rley/parser/error_reason_spec.rb +6 -6
- data/spec/rley/parser/gfg_earley_parser_spec.rb +120 -12
- data/spec/rley/parser/gfg_parsing_spec.rb +6 -13
- data/spec/rley/parser/parse_entry_spec.rb +19 -19
- data/spec/rley/parser/parse_walker_factory_spec.rb +10 -10
- data/spec/rley/ptree/non_terminal_node_spec.rb +5 -3
- data/spec/rley/ptree/parse_tree_node_spec.rb +4 -4
- data/spec/rley/ptree/terminal_node_spec.rb +6 -6
- data/spec/rley/sppf/alternative_node_spec.rb +6 -6
- data/spec/rley/sppf/non_terminal_node_spec.rb +3 -3
- data/spec/rley/sppf/token_node_spec.rb +4 -4
- data/spec/rley/support/ambiguous_grammar_helper.rb +4 -5
- data/spec/rley/support/grammar_abc_helper.rb +3 -5
- data/spec/rley/support/grammar_ambig01_helper.rb +5 -6
- data/spec/rley/support/grammar_arr_int_helper.rb +5 -6
- data/spec/rley/support/grammar_b_expr_helper.rb +5 -6
- data/spec/rley/support/grammar_int_seq_helper.rb +51 -0
- data/spec/rley/support/grammar_l0_helper.rb +14 -17
- data/spec/rley/support/grammar_pb_helper.rb +8 -7
- data/spec/rley/support/grammar_sppf_helper.rb +3 -3
- data/spec/rley/syntax/{grammar_builder_spec.rb → base_grammar_builder_spec.rb} +35 -16
- data/spec/rley/syntax/grammar_spec.rb +6 -6
- data/spec/rley/syntax/grm_symbol_spec.rb +1 -1
- data/spec/rley/syntax/match_closest_spec.rb +46 -0
- data/spec/rley/syntax/non_terminal_spec.rb +8 -8
- data/spec/rley/syntax/production_spec.rb +17 -13
- data/spec/rley/syntax/symbol_seq_spec.rb +2 -2
- data/spec/rley/syntax/terminal_spec.rb +5 -5
- data/spec/rley/syntax/verbatim_symbol_spec.rb +1 -1
- data/spec/spec_helper.rb +0 -12
- data/spec/support/base_tokenizer_spec.rb +7 -2
- metadata +48 -74
- data/.simplecov +0 -7
- data/lib/rley/parser/parse_state.rb +0 -83
- data/lib/rley/parser/parse_state_tracker.rb +0 -59
- data/lib/rley/parser/state_set.rb +0 -101
- data/spec/rley/parser/parse_state_spec.rb +0 -125
- data/spec/rley/parser/parse_tracer_spec.rb +0 -200
- data/spec/rley/parser/state_set_spec.rb +0 -130
@@ -24,20 +24,16 @@ engine.build_grammar do
|
|
24
24
|
|
25
25
|
# Here we define the productions (= grammar rules)
|
26
26
|
rule 'Start' => 'S'
|
27
|
-
rule 'S' =>
|
28
|
-
rule 'S' => %w[Aux NP VP]
|
27
|
+
rule 'S' => 'Aux? NP VP'
|
29
28
|
rule 'S' => 'VP'
|
30
29
|
rule 'NP' => 'Pronoun'
|
31
30
|
rule 'NP' => 'Proper-Noun'
|
32
|
-
rule 'NP' =>
|
33
|
-
rule 'Nominal' =>
|
34
|
-
rule '
|
35
|
-
rule 'VP' => 'Verb'
|
36
|
-
rule 'VP' =>
|
37
|
-
rule '
|
38
|
-
rule 'VP' => %w[Verb PP]
|
39
|
-
rule 'VP' => %w[VP PP]
|
40
|
-
rule 'PP' => %w[Preposition NP]
|
31
|
+
rule 'NP' => 'Determiner Nominal'
|
32
|
+
rule 'Nominal' => 'Nominal? Noun'
|
33
|
+
rule 'VP' => 'Verb PP?'
|
34
|
+
rule 'VP' => 'Verb NP PP?'
|
35
|
+
rule 'VP' => 'VP PP'
|
36
|
+
rule 'PP' => 'Preposition NP'
|
41
37
|
end
|
42
38
|
|
43
39
|
########################################
|
@@ -11,8 +11,8 @@ require 'rley' # Load the gem
|
|
11
11
|
# based on chapter 12 from Jurafski & Martin book.
|
12
12
|
# Daniel Jurafsky, James H. Martin: "Speech and Language Processing";
|
13
13
|
# 2009, Pearson Education, Inc., ISBN 978-0135041963
|
14
|
-
# It defines the syntax of a sentence in a mini English-like language
|
15
|
-
builder = Rley::
|
14
|
+
# It defines the syntax of a sentence in a mini English-like language
|
15
|
+
builder = Rley::grammar_builder do
|
16
16
|
add_terminals('Pronoun', 'Proper-Noun')
|
17
17
|
add_terminals('Determiner', 'Noun')
|
18
18
|
add_terminals('Cardinal_number', 'Ordinal_number', 'Quant')
|
@@ -21,39 +21,39 @@ builder = Rley::Syntax::GrammarBuilder.new do
|
|
21
21
|
|
22
22
|
rule 'language' => 'sentence'
|
23
23
|
rule 'sentence' => 'declarative'
|
24
|
-
rule 'sentence' => 'imperative'
|
24
|
+
rule 'sentence' => 'imperative'
|
25
25
|
rule 'sentence' => 'yes_no_question'
|
26
26
|
rule 'sentence' => 'wh_subject_question'
|
27
27
|
rule 'sentence' => 'wh_non_subject_question'
|
28
|
-
rule 'declarative' =>
|
28
|
+
rule 'declarative' => 'NP VP'
|
29
29
|
rule 'imperative' => 'VP'
|
30
|
-
rule 'yes_no_question' =>
|
31
|
-
rule 'wh_subject_question' =>
|
32
|
-
rule 'wh_non_subject_question' =>
|
33
|
-
rule 'NP' =>
|
30
|
+
rule 'yes_no_question' => 'Aux NP VP'
|
31
|
+
rule 'wh_subject_question' => 'Wh_NP NP VP'
|
32
|
+
rule 'wh_non_subject_question' => 'Wh_NP Aux NP VP'
|
33
|
+
rule 'NP' => 'Predeterminer NP'
|
34
34
|
rule 'NP' => 'Pronoun'
|
35
35
|
rule 'NP' => 'Proper-Noun'
|
36
|
-
rule 'NP' =>
|
36
|
+
rule 'NP' => 'Det Card Ord Quant Nominal'
|
37
37
|
rule 'VP' => 'Verb'
|
38
|
-
rule 'VP' =>
|
39
|
-
rule 'VP' =>
|
40
|
-
rule 'VP' =>
|
38
|
+
rule 'VP' => 'Verb NP'
|
39
|
+
rule 'VP' => 'Verb NP PP'
|
40
|
+
rule 'VP' => 'Verb PP'
|
41
41
|
rule 'Det' => 'Determiner'
|
42
42
|
rule 'Det' => []
|
43
43
|
rule 'Card' => 'Cardinal_number'
|
44
44
|
rule 'Card' => []
|
45
45
|
rule 'Ord' => 'Ordinal_number'
|
46
|
-
rule 'Ord' => []
|
46
|
+
rule 'Ord' => []
|
47
47
|
rule 'Nominal' => 'Noun'
|
48
|
-
rule 'Nominal' =>
|
49
|
-
rule 'Nominal' =>
|
50
|
-
rule 'Nominal' =>
|
51
|
-
rule 'PP' =>
|
48
|
+
rule 'Nominal' => 'Nominal Noun'
|
49
|
+
rule 'Nominal' => 'Nominal GerundVP'
|
50
|
+
rule 'Nominal' => 'Nominal RelClause'
|
51
|
+
rule 'PP' => 'Preposition NP'
|
52
52
|
rule 'GerundVP' => 'GerundV'
|
53
|
-
rule 'GerundVP' =>
|
54
|
-
rule 'GerundVP' =>
|
55
|
-
rule 'GerundVP' =>
|
56
|
-
rule 'RelClause' =>
|
53
|
+
rule 'GerundVP' => 'GerundV NP'
|
54
|
+
rule 'GerundVP' => 'GerundV NP PP'
|
55
|
+
rule 'GerundVP' => 'GerundV PP'
|
56
|
+
rule 'RelClause' => 'Relative_pronoun VP'
|
57
57
|
end
|
58
58
|
|
59
59
|
# And now build the grammar...
|
@@ -26,8 +26,8 @@ engine.build_grammar do
|
|
26
26
|
rule 'S' => 'NP VP'
|
27
27
|
rule 'NP' => 'Proper-Noun'
|
28
28
|
rule 'NP' => 'Determiner Noun'
|
29
|
-
rule 'NP' => 'Determiner Noun PP'
|
30
|
-
rule 'VP' => 'Verb NP'
|
29
|
+
rule 'NP' => 'Determiner Noun PP'
|
30
|
+
rule 'VP' => 'Verb NP'
|
31
31
|
rule 'VP' => 'Verb NP PP'
|
32
32
|
rule 'PP' => 'Preposition NP'
|
33
33
|
end
|
@@ -55,7 +55,7 @@ END_TEXT
|
|
55
55
|
|
56
56
|
rep_help = <<-END_TEXT
|
57
57
|
Set the parse tree representation (default: cst)
|
58
|
-
cst Concrete Syntax Tree. The out-of-the-box parse tree
|
58
|
+
cst Concrete Syntax Tree. The out-of-the-box parse tree
|
59
59
|
representation.
|
60
60
|
ast Abstract Syntaxt Tree. A customized parse tree for JSON.
|
61
61
|
It is a more compact and practical representation.
|
@@ -9,7 +9,7 @@ require_relative 'json_ast_nodes'
|
|
9
9
|
# The Builder pattern creates a complex object
|
10
10
|
# (say, a parse tree) from simpler objects (terminal and non-terminal
|
11
11
|
# nodes) and using a step by step approach.
|
12
|
-
class JSONASTBuilder < Rley::ParseRep::ASTBaseBuilder
|
12
|
+
class JSONASTBuilder < Rley::ParseRep::ASTBaseBuilder
|
13
13
|
Terminal2NodeClass = {
|
14
14
|
'false' => JSONBooleanNode,
|
15
15
|
'true' => JSONBooleanNode,
|
@@ -19,35 +19,33 @@ class JSONASTBuilder < Rley::ParseRep::ASTBaseBuilder
|
|
19
19
|
}.freeze
|
20
20
|
|
21
21
|
protected
|
22
|
-
|
23
|
-
def terminal2node
|
22
|
+
|
23
|
+
def terminal2node
|
24
24
|
Terminal2NodeClass
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
# Default class for representing terminal nodes.
|
28
28
|
# @return [Class]
|
29
|
-
def terminalnode_class
|
29
|
+
def terminalnode_class
|
30
30
|
JSONTerminalNode
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
|
+
# rubocop: disable Naming/VariableNumber
|
34
|
+
|
35
|
+
# rule 'JSON_text' => 'value'
|
33
36
|
def reduce_JSON_text_0(_aProd, aRange, theTokens, theChildren)
|
34
37
|
return_first_child(aRange, theTokens, theChildren)
|
35
38
|
end
|
36
|
-
|
37
|
-
# rule 'object' =>
|
39
|
+
|
40
|
+
# rule 'object' => 'begin-object member-list? end-object'
|
38
41
|
def reduce_object_0(aProduction, _range, _tokens, theChildren)
|
39
42
|
second_child = theChildren[1]
|
40
43
|
second_child.symbol = aProduction.lhs
|
41
44
|
return second_child
|
42
45
|
end
|
43
46
|
|
44
|
-
# rule '
|
45
|
-
def
|
46
|
-
return JSONObjectNode.new(aProduction.lhs)
|
47
|
-
end
|
48
|
-
|
49
|
-
# rule 'member-list' => %w[member-list value-separator member]
|
50
|
-
def reduce_member_list_0(_range, _tokens, theChildren)
|
47
|
+
# rule 'member-list' => 'member-list value-separator member'
|
48
|
+
def reduce_member_list_0(_production, _range, _tokens, theChildren)
|
51
49
|
node = theChildren[0]
|
52
50
|
node.members << theChildren.last
|
53
51
|
return node
|
@@ -60,35 +58,31 @@ class JSONASTBuilder < Rley::ParseRep::ASTBaseBuilder
|
|
60
58
|
return node
|
61
59
|
end
|
62
60
|
|
63
|
-
# rule 'member' =>
|
61
|
+
# rule 'member' => 'string name-separator value'
|
64
62
|
def reduce_member_0(aProduction, _range, _tokens, theChildren)
|
65
63
|
return JSONPair.new(theChildren[0], theChildren[2], aProduction.lhs)
|
66
64
|
end
|
67
65
|
|
68
|
-
# rule 'array' =>
|
66
|
+
# rule 'array' => 'begin-array array-items? end-array'
|
69
67
|
def reduce_array_0(aProduction, _range, _tokens, theChildren)
|
70
68
|
second_child = theChildren[1]
|
71
69
|
second_child.symbol = aProduction.lhs
|
72
|
-
return second_child
|
73
|
-
end
|
74
|
-
|
75
|
-
# rule 'array' => %w[begin-array end-array]
|
76
|
-
def reduce_array_1(_range, _tokens, _children)
|
77
|
-
return JSONArrayNode.new
|
70
|
+
return second_child
|
78
71
|
end
|
79
72
|
|
80
|
-
# rule 'array-items' =>
|
81
|
-
def reduce_array_items_0(_range, _tokens, theChildren)
|
73
|
+
# rule 'array-items' => 'array-items value-separator value'
|
74
|
+
def reduce_array_items_0(_production, _range, _tokens, theChildren)
|
82
75
|
node = theChildren[0]
|
83
76
|
node.children << theChildren[2]
|
84
77
|
return node
|
85
78
|
end
|
86
|
-
|
87
|
-
# rule 'array-items' =>
|
79
|
+
|
80
|
+
# rule 'array-items' => 'value'
|
88
81
|
def reduce_array_items_1(aProduction, _range, _tokens, theChildren)
|
89
82
|
node = JSONArrayNode.new(aProduction.lhs)
|
90
83
|
node.children << theChildren[0]
|
91
84
|
return node
|
92
85
|
end
|
86
|
+
# rubocop: enable Naming/VariableNumber
|
93
87
|
end # class
|
94
88
|
# End of file
|
@@ -16,11 +16,11 @@ JSONTerminalNode = Struct.new(:token, :value, :position) do
|
|
16
16
|
self.value = aLiteral.dup
|
17
17
|
end
|
18
18
|
|
19
|
-
def symbol
|
19
|
+
def symbol
|
20
20
|
token.terminal
|
21
21
|
end
|
22
22
|
|
23
|
-
def to_ruby
|
23
|
+
def to_ruby
|
24
24
|
value
|
25
25
|
end
|
26
26
|
|
@@ -29,9 +29,9 @@ JSONTerminalNode = Struct.new(:token, :value, :position) do
|
|
29
29
|
def accept(aVisitor)
|
30
30
|
aVisitor.visit_terminal(self)
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
def done!
|
34
|
-
# Do nothing
|
34
|
+
# Do nothing
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
@@ -77,23 +77,18 @@ class JSONCompositeNode
|
|
77
77
|
def accept(aVisitor)
|
78
78
|
aVisitor.visit_nonterminal(self)
|
79
79
|
end
|
80
|
-
|
80
|
+
|
81
81
|
def done!
|
82
|
-
# Do nothing
|
82
|
+
# Do nothing
|
83
83
|
end
|
84
84
|
|
85
85
|
alias subnodes children
|
86
86
|
end # class
|
87
87
|
|
88
|
-
|
89
88
|
class JSONArrayNode < JSONCompositeNode
|
90
|
-
def initialize(aSymbol)
|
91
|
-
super(aSymbol)
|
92
|
-
end
|
93
|
-
|
94
89
|
# Convert this tree node in a simpler Ruby representation.
|
95
90
|
# Basically a JSON object corresponds to a Ruhy Hash
|
96
|
-
def to_ruby
|
91
|
+
def to_ruby
|
97
92
|
rep = []
|
98
93
|
children.each do |child|
|
99
94
|
rep << child.to_ruby
|
@@ -114,7 +109,7 @@ class JSONPair
|
|
114
109
|
@symbol = aSymbol
|
115
110
|
end
|
116
111
|
|
117
|
-
def children
|
112
|
+
def children
|
118
113
|
return [name, value]
|
119
114
|
end
|
120
115
|
|
@@ -125,27 +120,23 @@ class JSONPair
|
|
125
120
|
def accept(aVisitor)
|
126
121
|
aVisitor.visit_nonterminal(self)
|
127
122
|
end
|
128
|
-
|
123
|
+
|
129
124
|
def done!
|
130
125
|
# Do nothing
|
131
126
|
end
|
132
|
-
|
127
|
+
|
133
128
|
def to_ruby
|
134
129
|
rep = {}
|
135
130
|
rep[name.to_ruby] = value.to_ruby
|
136
131
|
|
137
|
-
return rep
|
132
|
+
return rep
|
138
133
|
end
|
139
134
|
end # class
|
140
135
|
|
141
136
|
class JSONObjectNode < JSONCompositeNode
|
142
|
-
def initialize(aSymbol)
|
143
|
-
super(aSymbol)
|
144
|
-
end
|
145
|
-
|
146
137
|
# Convert this tree node in a simpler Ruby representation.
|
147
138
|
# Basically a JSON object corresponds to a Ruby Hash
|
148
|
-
def to_ruby
|
139
|
+
def to_ruby
|
149
140
|
rep = {}
|
150
141
|
members.each do |pair|
|
151
142
|
rep[pair.name.to_ruby] = pair.value.to_ruby
|
@@ -37,9 +37,8 @@ case cli_options[:format]
|
|
37
37
|
raise StandardError, msg if tree_rep == :cst
|
38
38
|
end
|
39
39
|
|
40
|
-
|
41
40
|
# Create a Rley facade object
|
42
|
-
# If
|
41
|
+
# If requested, select AST representation
|
43
42
|
engine = Rley::Engine.new do |cfg|
|
44
43
|
builder = tree_rep == :ast ? JSONASTBuilder : nil
|
45
44
|
cfg.repr_builder = builder
|
@@ -9,30 +9,30 @@ require 'rley' # Load the gem
|
|
9
9
|
# Original JSON grammar is available at: http://www.json.org/fatfree.html
|
10
10
|
# Official JSON grammar: http://rfc7159.net/rfc7159#rfc.section.2
|
11
11
|
# Names of grammar elements are based on the RFC 7159 documentation
|
12
|
-
builder = Rley::
|
12
|
+
builder = Rley::grammar_builder do
|
13
13
|
add_terminals('false', 'null', 'true') # Literal names
|
14
14
|
add_terminals('string', 'number')
|
15
15
|
add_terminals('begin-object', 'end-object') # For '{', '}' delimiters
|
16
16
|
add_terminals('begin-array', 'end-array') # For '[', ']' delimiters
|
17
17
|
add_terminals('name-separator', 'value-separator') # For ':', ',' separators
|
18
|
+
|
18
19
|
rule 'JSON_text' => 'value'
|
19
20
|
rule 'value' => 'false'
|
20
21
|
rule 'value' => 'null'
|
21
|
-
rule 'value' => 'true'
|
22
|
-
rule 'value' => 'object'
|
22
|
+
rule 'value' => 'true'
|
23
23
|
rule 'value' => 'array'
|
24
|
+
rule 'value' => 'object'
|
24
25
|
rule 'value' => 'number'
|
25
|
-
rule 'value' => 'string'
|
26
|
-
rule 'object' =>
|
27
|
-
|
26
|
+
rule 'value' => 'string'
|
27
|
+
rule 'object' => 'begin-object member_list? end-object'
|
28
|
+
|
28
29
|
# Next rule is an example of a left recursive rule
|
29
|
-
rule '
|
30
|
-
rule '
|
31
|
-
rule 'member' =>
|
32
|
-
rule 'array' =>
|
33
|
-
rule '
|
34
|
-
rule '
|
35
|
-
rule 'array-items' => %w[value]
|
30
|
+
rule 'member_list' => 'member_list value-separator member'
|
31
|
+
rule 'member_list' => 'member'
|
32
|
+
rule 'member' => 'string name-separator value'
|
33
|
+
rule 'array' => 'begin-array array_items? end-array'
|
34
|
+
rule 'array_items' => 'array_items value-separator value'
|
35
|
+
rule 'array_items' => 'value'
|
36
36
|
end
|
37
37
|
|
38
38
|
# And now build the JSON grammar...
|
@@ -28,19 +28,19 @@ class JSONLexer
|
|
28
28
|
@line_start = 0
|
29
29
|
end
|
30
30
|
|
31
|
-
def tokens
|
31
|
+
def tokens
|
32
32
|
tok_sequence = []
|
33
33
|
until @scanner.eos?
|
34
34
|
token = _next_token
|
35
35
|
tok_sequence << token unless token.nil?
|
36
36
|
end
|
37
37
|
|
38
|
-
|
38
|
+
tok_sequence
|
39
39
|
end
|
40
40
|
|
41
41
|
private
|
42
42
|
|
43
|
-
def _next_token
|
43
|
+
def _next_token
|
44
44
|
token = nil
|
45
45
|
skip_whitespaces
|
46
46
|
curr_ch = scanner.getch # curr_ch is at start of token or eof reached...
|
@@ -58,7 +58,7 @@ class JSONLexer
|
|
58
58
|
keyw = scanner.scan(/false|true|null/)
|
59
59
|
if keyw.nil?
|
60
60
|
invalid_keyw = scanner.scan(/\w+/)
|
61
|
-
raise ScanError
|
61
|
+
raise ScanError, "Invalid keyword: #{invalid_keyw}"
|
62
62
|
else
|
63
63
|
token = build_token(keyw, keyw)
|
64
64
|
end
|
@@ -68,7 +68,7 @@ class JSONLexer
|
|
68
68
|
value = scanner.scan(/([^"\\]|\\.)*/)
|
69
69
|
end_delimiter = scanner.getch
|
70
70
|
err_msg = 'No closing quotes (") found'
|
71
|
-
raise ScanError
|
71
|
+
raise ScanError, err_msg if end_delimiter.nil?
|
72
72
|
|
73
73
|
token = build_token(value, 'string')
|
74
74
|
|
@@ -81,12 +81,12 @@ class JSONLexer
|
|
81
81
|
erroneous = curr_ch.nil? ? '' : curr_ch
|
82
82
|
sequel = scanner.scan(/.{1,20}/)
|
83
83
|
erroneous += sequel unless sequel.nil?
|
84
|
-
raise ScanError
|
84
|
+
raise ScanError, "Unknown token #{erroneous}"
|
85
85
|
end # case
|
86
86
|
break unless token.nil? && (curr_ch = scanner.getch)
|
87
87
|
end
|
88
88
|
|
89
|
-
|
89
|
+
token
|
90
90
|
end
|
91
91
|
|
92
92
|
def build_token(lexeme, token)
|
@@ -94,7 +94,7 @@ class JSONLexer
|
|
94
94
|
Rley::Lexical::Token.new(lexeme, token, pos)
|
95
95
|
end
|
96
96
|
|
97
|
-
def skip_whitespaces
|
97
|
+
def skip_whitespaces
|
98
98
|
matched = scanner.scan(/[ \t\f\n\r]+/)
|
99
99
|
return if matched.nil?
|
100
100
|
|
@@ -15,8 +15,8 @@ class CalcASTBuilder < Rley::ParseRep::ASTBaseBuilder
|
|
15
15
|
}.freeze
|
16
16
|
|
17
17
|
protected
|
18
|
-
|
19
|
-
def terminal2node
|
18
|
+
|
19
|
+
def terminal2node
|
20
20
|
Terminal2NodeClass
|
21
21
|
end
|
22
22
|
|
@@ -26,7 +26,9 @@ class CalcASTBuilder < Rley::ParseRep::ASTBaseBuilder
|
|
26
26
|
operator_node.children << theChildren[2]
|
27
27
|
return operator_node
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
|
+
# rubocop: disable Naming/VariableNumber
|
31
|
+
|
30
32
|
# rule 'expression' => 'simple_expression'
|
31
33
|
def reduce_expression_0(_production, aRange, theTokens, theChildren)
|
32
34
|
return_first_child(aRange, theTokens, theChildren)
|
@@ -35,32 +37,32 @@ class CalcASTBuilder < Rley::ParseRep::ASTBaseBuilder
|
|
35
37
|
# rule 'simple_expression' => 'term'
|
36
38
|
def reduce_simple_expression_0(_production, aRange, theTokens, theChildren)
|
37
39
|
return_first_child(aRange, theTokens, theChildren)
|
38
|
-
end
|
40
|
+
end
|
39
41
|
|
40
42
|
# rule 'simple_expression' => %w[simple_expression add_operator term]
|
41
43
|
def reduce_simple_expression_1(_production, _range, _tokens, theChildren)
|
42
44
|
reduce_binary_operator(theChildren)
|
43
45
|
end
|
44
|
-
|
45
|
-
# rule 'term' => 'factor'
|
46
|
+
|
47
|
+
# rule 'term' => 'factor'
|
46
48
|
def reduce_term_0(_production, aRange, theTokens, theChildren)
|
47
49
|
return_first_child(aRange, theTokens, theChildren)
|
48
|
-
end
|
50
|
+
end
|
49
51
|
|
50
52
|
# rule 'term' => %w[term mul_operator factor]
|
51
53
|
def reduce_term_1(_production, _range, _tokens, theChildren)
|
52
54
|
reduce_binary_operator(theChildren)
|
53
55
|
end
|
54
|
-
|
56
|
+
|
55
57
|
# rule 'factor' => 'NUMBER'
|
56
58
|
def reduce_factor_0(_aProd, aRange, theTokens, theChildren)
|
57
59
|
return_first_child(aRange, theTokens, theChildren)
|
58
60
|
end
|
59
|
-
|
61
|
+
|
60
62
|
# # rule 'factor' => %w[LPAREN expression RPAREN]
|
61
63
|
def reduce_factor_1(_aProd, aRange, theTokens, theChildren)
|
62
64
|
return_second_child(aRange, theTokens, theChildren)
|
63
|
-
end
|
65
|
+
end
|
64
66
|
|
65
67
|
# rule 'add_operator' => 'PLUS'
|
66
68
|
def reduce_add_operator_0(_production, _range, _tokens, theChildren)
|
@@ -81,5 +83,6 @@ class CalcASTBuilder < Rley::ParseRep::ASTBaseBuilder
|
|
81
83
|
def reduce_mul_operator_1(_production, _range, _tokens, theChildren)
|
82
84
|
return CalcDivideNode.new(theChildren[0].symbol)
|
83
85
|
end
|
86
|
+
# rubocop: enable Naming/VariableNumber
|
84
87
|
end # class
|
85
88
|
# End of file
|