rley 0.7.03 → 0.7.08
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 -7
- data/CHANGELOG.md +20 -1
- data/LICENSE.txt +1 -1
- data/README.md +6 -7
- data/Rakefile +2 -0
- data/appveyor.yml +2 -4
- data/examples/NLP/benchmark_pico_en.rb +2 -0
- data/examples/NLP/engtagger.rb +193 -188
- data/examples/NLP/nano_eng/nano_en_demo.rb +2 -0
- data/examples/NLP/nano_eng/nano_grammar.rb +7 -5
- data/examples/NLP/pico_en_demo.rb +2 -0
- data/examples/data_formats/JSON/cli_options.rb +3 -1
- data/examples/data_formats/JSON/json_ast_builder.rb +14 -9
- data/examples/data_formats/JSON/json_ast_nodes.rb +14 -21
- data/examples/data_formats/JSON/json_demo.rb +2 -0
- data/examples/data_formats/JSON/json_grammar.rb +4 -2
- data/examples/data_formats/JSON/json_lexer.rb +10 -8
- data/examples/data_formats/JSON/json_minifier.rb +3 -1
- data/examples/general/calc_iter1/calc_ast_builder.rb +15 -10
- data/examples/general/calc_iter1/calc_ast_nodes.rb +25 -37
- data/examples/general/calc_iter1/calc_demo.rb +2 -0
- data/examples/general/calc_iter1/calc_grammar.rb +4 -2
- data/examples/general/calc_iter1/calc_lexer.rb +8 -4
- data/examples/general/calc_iter1/spec/calculator_spec.rb +7 -5
- data/examples/general/calc_iter2/calc_ast_builder.rb +7 -3
- data/examples/general/calc_iter2/calc_ast_nodes.rb +29 -43
- data/examples/general/calc_iter2/calc_demo.rb +2 -0
- data/examples/general/calc_iter2/calc_grammar.rb +5 -3
- data/examples/general/calc_iter2/calc_lexer.rb +13 -10
- data/examples/general/calc_iter2/spec/calculator_spec.rb +28 -26
- data/examples/general/left.rb +4 -2
- data/examples/general/right.rb +4 -2
- data/lib/rley.rb +2 -0
- data/lib/rley/base/base_parser.rb +2 -0
- data/lib/rley/base/dotted_item.rb +38 -41
- data/lib/rley/base/grm_items_builder.rb +2 -0
- data/lib/rley/constants.rb +5 -3
- data/lib/rley/engine.rb +22 -24
- data/lib/rley/formatter/asciitree.rb +6 -4
- data/lib/rley/formatter/base_formatter.rb +2 -0
- data/lib/rley/formatter/bracket_notation.rb +3 -8
- data/lib/rley/formatter/debug.rb +8 -6
- data/lib/rley/formatter/json.rb +4 -2
- data/lib/rley/gfg/call_edge.rb +3 -1
- data/lib/rley/gfg/edge.rb +7 -5
- data/lib/rley/gfg/end_vertex.rb +4 -6
- data/lib/rley/gfg/epsilon_edge.rb +3 -5
- data/lib/rley/gfg/grm_flow_graph.rb +31 -25
- data/lib/rley/gfg/item_vertex.rb +12 -22
- data/lib/rley/gfg/non_terminal_vertex.rb +6 -4
- data/lib/rley/gfg/return_edge.rb +2 -0
- data/lib/rley/gfg/scan_edge.rb +3 -1
- data/lib/rley/gfg/shortcut_edge.rb +4 -2
- data/lib/rley/gfg/start_vertex.rb +6 -8
- data/lib/rley/gfg/vertex.rb +47 -41
- data/lib/rley/lexical/token.rb +3 -1
- data/lib/rley/lexical/token_range.rb +8 -6
- data/lib/rley/parse_forest_visitor.rb +7 -5
- data/lib/rley/parse_rep/ast_base_builder.rb +11 -11
- data/lib/rley/parse_rep/cst_builder.rb +7 -4
- data/lib/rley/parse_rep/parse_forest_builder.rb +36 -25
- data/lib/rley/parse_rep/parse_forest_factory.rb +5 -3
- data/lib/rley/parse_rep/parse_rep_creator.rb +18 -13
- data/lib/rley/parse_rep/parse_tree_builder.rb +15 -15
- data/lib/rley/parse_rep/parse_tree_factory.rb +27 -25
- data/lib/rley/parse_tree_visitor.rb +3 -1
- data/lib/rley/parser/error_reason.rb +9 -8
- data/lib/rley/parser/gfg_chart.rb +54 -22
- data/lib/rley/parser/gfg_earley_parser.rb +3 -1
- data/lib/rley/parser/gfg_parsing.rb +51 -31
- data/lib/rley/parser/parse_entry.rb +29 -33
- data/lib/rley/parser/parse_entry_set.rb +32 -27
- data/lib/rley/parser/parse_entry_tracker.rb +6 -4
- data/lib/rley/parser/parse_state.rb +18 -21
- data/lib/rley/parser/parse_state_tracker.rb +6 -4
- data/lib/rley/parser/parse_tracer.rb +15 -13
- data/lib/rley/parser/parse_walker_factory.rb +28 -29
- data/lib/rley/parser/state_set.rb +11 -10
- data/lib/rley/ptree/non_terminal_node.rb +10 -6
- data/lib/rley/ptree/parse_tree.rb +6 -4
- data/lib/rley/ptree/parse_tree_node.rb +7 -5
- data/lib/rley/ptree/terminal_node.rb +9 -7
- data/lib/rley/rley_error.rb +12 -10
- data/lib/rley/sppf/alternative_node.rb +8 -6
- data/lib/rley/sppf/composite_node.rb +9 -7
- data/lib/rley/sppf/epsilon_node.rb +5 -3
- data/lib/rley/sppf/leaf_node.rb +5 -3
- data/lib/rley/sppf/non_terminal_node.rb +2 -0
- data/lib/rley/sppf/parse_forest.rb +19 -17
- data/lib/rley/sppf/sppf_node.rb +9 -8
- data/lib/rley/sppf/token_node.rb +5 -3
- data/lib/rley/syntax/grammar.rb +7 -5
- data/lib/rley/syntax/grammar_builder.rb +11 -9
- data/lib/rley/syntax/grm_symbol.rb +8 -6
- data/lib/rley/syntax/literal.rb +2 -0
- data/lib/rley/syntax/non_terminal.rb +11 -15
- data/lib/rley/syntax/production.rb +13 -11
- data/lib/rley/syntax/symbol_seq.rb +10 -10
- data/lib/rley/syntax/terminal.rb +6 -5
- data/lib/rley/syntax/verbatim_symbol.rb +5 -3
- data/lib/support/base_tokenizer.rb +23 -20
- data/spec/rley/base/dotted_item_spec.rb +4 -2
- data/spec/rley/base/grm_items_builder_spec.rb +2 -0
- data/spec/rley/engine_spec.rb +47 -9
- data/spec/rley/formatter/asciitree_spec.rb +11 -9
- data/spec/rley/formatter/bracket_notation_spec.rb +16 -14
- data/spec/rley/formatter/debug_spec.rb +4 -2
- data/spec/rley/formatter/json_spec.rb +5 -3
- data/spec/rley/gfg/call_edge_spec.rb +2 -0
- data/spec/rley/gfg/edge_spec.rb +2 -0
- data/spec/rley/gfg/end_vertex_spec.rb +7 -5
- data/spec/rley/gfg/epsilon_edge_spec.rb +2 -0
- data/spec/rley/gfg/grm_flow_graph_spec.rb +2 -0
- data/spec/rley/gfg/item_vertex_spec.rb +12 -10
- data/spec/rley/gfg/non_terminal_vertex_spec.rb +5 -3
- data/spec/rley/gfg/return_edge_spec.rb +2 -0
- data/spec/rley/gfg/scan_edge_spec.rb +2 -0
- data/spec/rley/gfg/shortcut_edge_spec.rb +3 -1
- data/spec/rley/gfg/start_vertex_spec.rb +7 -5
- data/spec/rley/gfg/vertex_spec.rb +5 -3
- data/spec/rley/lexical/token_range_spec.rb +18 -16
- data/spec/rley/lexical/token_spec.rb +4 -2
- data/spec/rley/parse_forest_visitor_spec.rb +167 -163
- data/spec/rley/parse_rep/ambiguous_parse_spec.rb +46 -44
- data/spec/rley/parse_rep/ast_builder_spec.rb +8 -6
- data/spec/rley/parse_rep/cst_builder_spec.rb +7 -5
- data/spec/rley/parse_rep/groucho_spec.rb +25 -25
- data/spec/rley/parse_rep/parse_forest_builder_spec.rb +28 -26
- data/spec/rley/parse_rep/parse_forest_factory_spec.rb +8 -6
- data/spec/rley/parse_rep/parse_tree_factory_spec.rb +4 -2
- data/spec/rley/parse_tree_visitor_spec.rb +12 -8
- data/spec/rley/parser/error_reason_spec.rb +8 -6
- data/spec/rley/parser/gfg_chart_spec.rb +17 -4
- data/spec/rley/parser/gfg_earley_parser_spec.rb +16 -11
- data/spec/rley/parser/gfg_parsing_spec.rb +41 -252
- data/spec/rley/parser/parse_entry_set_spec.rb +2 -0
- data/spec/rley/parser/parse_entry_spec.rb +21 -19
- data/spec/rley/parser/parse_state_spec.rb +7 -5
- data/spec/rley/parser/parse_tracer_spec.rb +16 -14
- data/spec/rley/parser/parse_walker_factory_spec.rb +10 -8
- data/spec/rley/parser/state_set_spec.rb +24 -22
- data/spec/rley/ptree/non_terminal_node_spec.rb +7 -3
- data/spec/rley/ptree/parse_tree_node_spec.rb +6 -4
- data/spec/rley/ptree/parse_tree_spec.rb +2 -0
- data/spec/rley/ptree/terminal_node_spec.rb +8 -6
- data/spec/rley/sppf/alternative_node_spec.rb +8 -6
- data/spec/rley/sppf/non_terminal_node_spec.rb +5 -3
- data/spec/rley/sppf/token_node_spec.rb +6 -4
- data/spec/rley/support/ambiguous_grammar_helper.rb +5 -4
- data/spec/rley/support/expectation_helper.rb +2 -0
- data/spec/rley/support/grammar_abc_helper.rb +4 -4
- data/spec/rley/support/grammar_ambig01_helper.rb +6 -5
- data/spec/rley/support/grammar_arr_int_helper.rb +6 -5
- data/spec/rley/support/grammar_b_expr_helper.rb +6 -5
- data/spec/rley/support/grammar_helper.rb +2 -0
- data/spec/rley/support/grammar_l0_helper.rb +15 -16
- data/spec/rley/support/grammar_pb_helper.rb +8 -5
- data/spec/rley/support/grammar_sppf_helper.rb +3 -1
- data/spec/rley/syntax/grammar_builder_spec.rb +7 -5
- data/spec/rley/syntax/grammar_spec.rb +8 -6
- data/spec/rley/syntax/grm_symbol_spec.rb +3 -1
- data/spec/rley/syntax/literal_spec.rb +2 -0
- data/spec/rley/syntax/non_terminal_spec.rb +10 -8
- data/spec/rley/syntax/production_spec.rb +15 -13
- data/spec/rley/syntax/symbol_seq_spec.rb +4 -2
- data/spec/rley/syntax/terminal_spec.rb +7 -5
- data/spec/rley/syntax/verbatim_symbol_spec.rb +3 -1
- data/spec/spec_helper.rb +2 -12
- data/spec/support/base_tokenizer_spec.rb +9 -2
- metadata +21 -63
- data/.simplecov +0 -7
- data/Gemfile +0 -8
    
        data/lib/rley/formatter/json.rb
    CHANGED
    
    | @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            require_relative 'base_formatter'
         | 
| 2 4 |  | 
| 3 5 |  | 
| @@ -92,11 +94,11 @@ module Rley # This module is used as a namespace | |
| 92 94 |  | 
| 93 95 | 
             
                  private
         | 
| 94 96 |  | 
| 95 | 
            -
                  def indent | 
| 97 | 
            +
                  def indent
         | 
| 96 98 | 
             
                    @indentation += 1
         | 
| 97 99 | 
             
                  end
         | 
| 98 100 |  | 
| 99 | 
            -
                  def dedent | 
| 101 | 
            +
                  def dedent
         | 
| 100 102 | 
             
                    @indentation -= 1
         | 
| 101 103 | 
             
                  end
         | 
| 102 104 |  | 
    
        data/lib/rley/gfg/call_edge.rb
    CHANGED
    
    | @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            require_relative 'edge'
         | 
| 2 4 |  | 
| 3 5 | 
             
            module Rley # This module is used as a namespace
         | 
| @@ -14,7 +16,7 @@ module Rley # This module is used as a namespace | |
| 14 16 | 
             
                  # Pre-condition: theSuccessor is an StartVertex
         | 
| 15 17 | 
             
                  def initialize(thePredecessor, theSuccessor)
         | 
| 16 18 | 
             
                    super(thePredecessor, theSuccessor)
         | 
| 17 | 
            -
                    do_set_key(thePredecessor, theSuccessor) | 
| 19 | 
            +
                    do_set_key(thePredecessor, theSuccessor)
         | 
| 18 20 | 
             
                  end
         | 
| 19 21 |  | 
| 20 22 | 
             
                  private
         | 
    
        data/lib/rley/gfg/edge.rb
    CHANGED
    
    | @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            module Rley # This module is used as a namespace
         | 
| 2 4 | 
             
              module GFG # This module is used as a namespace
         | 
| 3 5 | 
             
                # Abstract class. Represents an edge in a grammar flow graph.
         | 
| @@ -12,18 +14,18 @@ module Rley # This module is used as a namespace | |
| 12 14 | 
             
                  # @param theSuccessor [Vertex]
         | 
| 13 15 | 
             
                  def initialize(thePredecessor, theSuccessor)
         | 
| 14 16 | 
             
                    @successor = theSuccessor
         | 
| 15 | 
            -
                    thePredecessor | 
| 17 | 
            +
                    thePredecessor&.add_edge(self)
         | 
| 16 18 | 
             
                  end
         | 
| 17 19 |  | 
| 18 20 | 
             
                  # @return [String]
         | 
| 19 | 
            -
                  def to_s | 
| 21 | 
            +
                  def to_s
         | 
| 20 22 | 
             
                    " --> #{successor.label}"
         | 
| 21 23 | 
             
                  end
         | 
| 22 | 
            -
             | 
| 23 | 
            -
                  # Returns a string containing a human-readable representation of the | 
| 24 | 
            +
             | 
| 25 | 
            +
                  # Returns a string containing a human-readable representation of the
         | 
| 24 26 | 
             
                  # production.
         | 
| 25 27 | 
             
                  # @return [String]
         | 
| 26 | 
            -
                  def inspect | 
| 28 | 
            +
                  def inspect
         | 
| 27 29 | 
             
                    to_s
         | 
| 28 30 | 
             
                  end
         | 
| 29 31 | 
             
                end # class
         | 
    
        data/lib/rley/gfg/end_vertex.rb
    CHANGED
    
    | @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            require_relative 'non_terminal_vertex'
         | 
| 2 4 |  | 
| 3 5 | 
             
            module Rley # This module is used as a namespace
         | 
| @@ -8,12 +10,8 @@ module Rley # This module is used as a namespace | |
| 8 10 | 
             
                # Responsibilities (in addition to inherited ones):
         | 
| 9 11 | 
             
                # - Know its related non-terminal symbol
         | 
| 10 12 | 
             
                class EndVertex < NonTerminalVertex
         | 
| 11 | 
            -
                  def  | 
| 12 | 
            -
                     | 
| 13 | 
            -
                  end
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                  def label()
         | 
| 16 | 
            -
                    return "#{non_terminal}."
         | 
| 13 | 
            +
                  def label
         | 
| 14 | 
            +
                    "#{non_terminal}."
         | 
| 17 15 | 
             
                  end
         | 
| 18 16 | 
             
                end # class
         | 
| 19 17 | 
             
              end # module
         | 
| @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            require_relative 'edge'
         | 
| 2 4 |  | 
| 3 5 | 
             
            module Rley # This module is used as a namespace
         | 
| @@ -7,12 +9,8 @@ module Rley # This module is used as a namespace | |
| 7 9 | 
             
                # Responsibilities:
         | 
| 8 10 | 
             
                # - To know the successor vertex
         | 
| 9 11 | 
             
                class EpsilonEdge < Edge
         | 
| 10 | 
            -
                  # The destination vertex of the edge | 
| 12 | 
            +
                  # The destination vertex of the edge.
         | 
| 11 13 | 
             
                  attr_reader :successor
         | 
| 12 | 
            -
             | 
| 13 | 
            -
                  def initialize(thePredecessor, theSuccessor)
         | 
| 14 | 
            -
                    super(thePredecessor, theSuccessor)
         | 
| 15 | 
            -
                  end
         | 
| 16 14 | 
             
                end # class
         | 
| 17 15 | 
             
              end # module
         | 
| 18 16 | 
             
            end # module
         | 
| @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            require 'set'
         | 
| 2 4 | 
             
            require_relative 'start_vertex'
         | 
| 3 5 | 
             
            require_relative 'end_vertex'
         | 
| @@ -11,26 +13,26 @@ require_relative 'shortcut_edge' | |
| 11 13 | 
             
            module Rley # This module is used as a namespace
         | 
| 12 14 | 
             
              module GFG # This module is used as a namespace
         | 
| 13 15 | 
             
                # A Grammar Flow Graph (GFG) represents the parsing states of productions
         | 
| 14 | 
            -
                # rules from a context-free grammar. This representation is based on a | 
| 15 | 
            -
                # directed graph structure. The parsing process can then be re-formulated | 
| 16 | 
            +
                # rules from a context-free grammar. This representation is based on a
         | 
| 17 | 
            +
                # directed graph structure. The parsing process can then be re-formulated
         | 
| 16 18 | 
             
                # as a path problem in the graph. The theory behind GFGs can be found in
         | 
| 17 19 | 
             
                # papers. The first article on GFG can be found here:
         | 
| 18 20 | 
             
                # https://apps.cs.utexas.edu/tech_reports/reports/tr/TR-2102.pdf
         | 
| 19 | 
            -
                # There are three types of vertex in a GFG: | 
| 21 | 
            +
                # There are three types of vertex in a GFG:
         | 
| 20 22 | 
             
                # start vertex, end vertex and item vertex.
         | 
| 21 23 | 
             
                # For each non-terminal symbol N of the grammar, there is:
         | 
| 22 24 | 
             
                # a start vertex with label '.N'
         | 
| 23 25 | 
             
                # an end vertex with label 'N.'
         | 
| 24 26 | 
             
                # For each production rule of the grammar:
         | 
| 25 27 | 
             
                # N => s1 s2 s3 (...) sk
         | 
| 26 | 
            -
                # I.e. a rule with k grammar symbols in its right-handed side. | 
| 28 | 
            +
                # I.e. a rule with k grammar symbols in its right-handed side.
         | 
| 27 29 | 
             
                # For such a rule there will be k + 1 item vertices. By convention,
         | 
| 28 30 | 
             
                # the first item vertex is labelled as 'N => . s1 s2 s3 (...) sk'
         | 
| 29 31 | 
             
                # the second item vertex is labelled as 'N => s1 . s2 s3 (...) sk'
         | 
| 30 32 | 
             
                # the third item vertex is labelled as 'N => s1 s2 . s3 (...) sk'
         | 
| 31 33 | 
             
                # and so on. In other words, the labels are obtained by moving a dot
         | 
| 32 | 
            -
                # in successive positions in the rhs. The dot represents the | 
| 33 | 
            -
                # parse progress for the production rule. Symbols on the left of the | 
| 34 | 
            +
                # in successive positions in the rhs. The dot represents the
         | 
| 35 | 
            +
                # parse progress for the production rule. Symbols on the left of the
         | 
| 34 36 | 
             
                # dot represent the symbols that were successfully matched in the input.
         | 
| 35 37 | 
             
                # A GFG has three types of directed edges linking the vertices.
         | 
| 36 38 | 
             
                # call edge, return edge and scan edge.
         | 
| @@ -58,24 +60,24 @@ module Rley # This module is used as a namespace | |
| 58 60 |  | 
| 59 61 | 
             
                    build_graph(theDottedItems)
         | 
| 60 62 | 
             
                  end
         | 
| 61 | 
            -
             | 
| 62 | 
            -
                  # Returns a string containing a human-readable representation of the | 
| 63 | 
            +
             | 
| 64 | 
            +
                  # Returns a string containing a human-readable representation of the
         | 
| 63 65 | 
             
                  # production.
         | 
| 64 66 | 
             
                  # @return [String]
         | 
| 65 | 
            -
                  def inspect | 
| 66 | 
            -
                    result = "#<#{self.class.name}:#{object_id}"
         | 
| 67 | 
            +
                  def inspect
         | 
| 68 | 
            +
                    result = +"#<#{self.class.name}:#{object_id}"
         | 
| 67 69 | 
             
                    result << ' @vertices=['
         | 
| 68 70 | 
             
                    list = vertices.map { |v| "#<#{v.selfie}>" }
         | 
| 69 71 | 
             
                    result << list.join(', ')
         | 
| 70 72 | 
             
                    result << '] '
         | 
| 71 73 | 
             
                    edges = []
         | 
| 72 | 
            -
                    vertices.each do |v| | 
| 74 | 
            +
                    vertices.each do |v|
         | 
| 73 75 | 
             
                      edges << v.edges do |e|
         | 
| 74 76 | 
             
                        result << "#{v.object_id} #{e.inspect}"
         | 
| 75 77 | 
             
                      end
         | 
| 76 78 | 
             
                    end
         | 
| 77 79 | 
             
                    result << "edges=[#{edges.join(",\n ")}]>"
         | 
| 78 | 
            -
                     | 
| 80 | 
            +
                    result
         | 
| 79 81 | 
             
                  end
         | 
| 80 82 |  | 
| 81 83 | 
             
                  # Retrieve the vertex with given vertex label.
         | 
| @@ -90,7 +92,7 @@ module Rley # This module is used as a namespace | |
| 90 92 | 
             
                  # If one wants to remove useless rules, then do first:
         | 
| 91 93 | 
             
                  # elimination of non-generating symbols
         | 
| 92 94 | 
             
                  # then elimination of unreachable symbols
         | 
| 93 | 
            -
                  def diagnose | 
| 95 | 
            +
                  def diagnose
         | 
| 94 96 | 
             
                    mark_unreachable_symbols
         | 
| 95 97 | 
             
                  end
         | 
| 96 98 |  | 
| @@ -119,6 +121,7 @@ module Rley # This module is used as a namespace | |
| 119 121 | 
             
                  # @param aStartVertex [StartVertex] the depth-first traversal begins
         | 
| 120 122 | 
             
                  #   from here
         | 
| 121 123 | 
             
                  # @param _visitAction [Proc] block called when a new graph vertex is found
         | 
| 124 | 
            +
                  # rubocop: disable Lint/Loop
         | 
| 122 125 | 
             
                  def traverse_df(aStartVertex, &_visitAction)
         | 
| 123 126 | 
             
                    visited = Set.new
         | 
| 124 127 | 
             
                    stack = []
         | 
| @@ -127,13 +130,13 @@ module Rley # This module is used as a namespace | |
| 127 130 |  | 
| 128 131 | 
             
                    begin
         | 
| 129 132 | 
             
                      # print_vertex( 'Traversing', visitee)
         | 
| 130 | 
            -
             | 
| 133 | 
            +
             | 
| 131 134 | 
             
                      first_time = !visited.include?(visitee)
         | 
| 132 135 | 
             
                      if first_time
         | 
| 133 136 | 
             
                        yield(visitee)
         | 
| 134 137 | 
             
                        visited << visitee
         | 
| 135 | 
            -
                      end | 
| 136 | 
            -
             | 
| 138 | 
            +
                      end
         | 
| 139 | 
            +
             | 
| 137 140 | 
             
                      case visitee
         | 
| 138 141 | 
             
                        when Rley::GFG::StartVertex
         | 
| 139 142 | 
             
                          if first_time
         | 
| @@ -153,12 +156,12 @@ module Rley # This module is used as a namespace | |
| 153 156 | 
             
                          if stack.last.done?
         | 
| 154 157 | 
             
                            popped = stack.pop
         | 
| 155 158 | 
             
                            break if stack.empty?
         | 
| 156 | 
            -
             | 
| 159 | 
            +
             | 
| 157 160 | 
             
                            # puts "Popped!"
         | 
| 158 161 | 
             
                            return_key = popped.in_edge.key.sub(/^CALL/, 'RET')
         | 
| 159 162 | 
             
                            curr_edge = visitee.edges.find { |e| e.key == return_key }
         | 
| 160 163 | 
             
                          else
         | 
| 161 | 
            -
                            curr_edge = stack.last.next_edge | 
| 164 | 
            +
                            curr_edge = stack.last.next_edge
         | 
| 162 165 | 
             
                          end
         | 
| 163 166 |  | 
| 164 167 | 
             
                        else
         | 
| @@ -171,6 +174,7 @@ module Rley # This module is used as a namespace | |
| 171 174 | 
             
                    last_one = end_vertex_for[aStartVertex.non_terminal]
         | 
| 172 175 | 
             
                    yield(last_one) unless visited.include?(last_one)
         | 
| 173 176 | 
             
                  end
         | 
| 177 | 
            +
                  # rubocop: enable Lint/Loop
         | 
| 174 178 |  | 
| 175 179 | 
             
                  private
         | 
| 176 180 |  | 
| @@ -181,16 +185,16 @@ module Rley # This module is used as a namespace | |
| 181 185 | 
             
                    @start_vertex = aVertex if vertices.empty?
         | 
| 182 186 | 
             
                    vertices << aVertex
         | 
| 183 187 | 
             
                  end
         | 
| 184 | 
            -
             | 
| 188 | 
            +
             | 
| 185 189 | 
             
                  # For debugging purposes
         | 
| 186 190 | 
             
                  def print_vertex(aText, aVertex)
         | 
| 187 | 
            -
                    print aText  | 
| 191 | 
            +
                    print "#{aText} "
         | 
| 188 192 | 
             
                    if aVertex.kind_of?(NonTerminalVertex)
         | 
| 189 193 | 
             
                      puts "#{aVertex.class} #{aVertex.non_terminal.name}"
         | 
| 190 194 | 
             
                    else
         | 
| 191 195 | 
             
                      p(aVertex.label)
         | 
| 192 | 
            -
                    end | 
| 193 | 
            -
                  end | 
| 196 | 
            +
                    end
         | 
| 197 | 
            +
                  end
         | 
| 194 198 |  | 
| 195 199 | 
             
                  def build_graph(theDottedItems)
         | 
| 196 200 | 
             
                    build_all_starts_ends(theDottedItems)
         | 
| @@ -198,7 +202,7 @@ module Rley # This module is used as a namespace | |
| 198 202 | 
             
                    curr_prod = nil
         | 
| 199 203 | 
             
                    theDottedItems.each_with_index do |d_item, index_item|
         | 
| 200 204 | 
             
                      next unless curr_prod.nil? || curr_prod != d_item.production
         | 
| 201 | 
            -
             | 
| 205 | 
            +
             | 
| 202 206 | 
             
                      # Another production found...
         | 
| 203 207 | 
             
                      curr_prod = d_item.production
         | 
| 204 208 | 
             
                      if curr_prod.empty?
         | 
| @@ -266,6 +270,7 @@ module Rley # This module is used as a namespace | |
| 266 270 | 
             
                  #     add a shortcut edge:
         | 
| 267 271 | 
             
                  # ( N => α[1] .A  α[n] ) -> ( N => α[1] A.  α[n] )
         | 
| 268 272 | 
             
                  def augment_graph(theDottedItems, firstItemPos)
         | 
| 273 | 
            +
                    # rubocop: disable Lint/RedundantSafeNavigation
         | 
| 269 274 | 
             
                    production = theDottedItems[firstItemPos].production
         | 
| 270 275 | 
             
                    max_index = production.rhs.size + 1
         | 
| 271 276 | 
             
                    prev_vertex = nil
         | 
| @@ -290,12 +295,13 @@ module Rley # This module is used as a namespace | |
| 290 295 | 
             
                      end
         | 
| 291 296 |  | 
| 292 297 | 
             
                      prev_symbol = current_item.prev_symbol
         | 
| 293 | 
            -
                      if prev_symbol | 
| 298 | 
            +
                      if prev_symbol&.kind_of?(Syntax::NonTerminal)
         | 
| 294 299 | 
             
                        build_shortcut_edge(prev_vertex, new_vertex)
         | 
| 295 300 | 
             
                      end
         | 
| 296 301 | 
             
                      prev_vertex = new_vertex
         | 
| 297 302 | 
             
                    end
         | 
| 298 303 | 
             
                  end
         | 
| 304 | 
            +
                  # rubocop: enable Lint/RedundantSafeNavigation
         | 
| 299 305 |  | 
| 300 306 | 
             
                  # Create an entry edge for the given vertex
         | 
| 301 307 | 
             
                  def build_entry_edge(theVertex)
         | 
| @@ -357,7 +363,7 @@ module Rley # This module is used as a namespace | |
| 357 363 | 
             
                  # Mark non-terminal symbols that cannot be derived from the start symbol.
         | 
| 358 364 | 
             
                  # In a GFG, a non-terminal symbol N is unreachable if there is no path
         | 
| 359 365 | 
             
                  # from the start symbol to the start node .N
         | 
| 360 | 
            -
                  def mark_unreachable_symbols | 
| 366 | 
            +
                  def mark_unreachable_symbols
         | 
| 361 367 | 
             
                    # Mark all non-terminals as unreachable
         | 
| 362 368 | 
             
                    start_vertex_for.each_value do |a_vertex|
         | 
| 363 369 | 
             
                      a_vertex.non_terminal.unreachable = true
         | 
    
        data/lib/rley/gfg/item_vertex.rb
    CHANGED
    
    | @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            require_relative '../syntax/non_terminal'
         | 
| 2 4 | 
             
            require_relative 'vertex'
         | 
| 3 5 |  | 
| @@ -30,53 +32,41 @@ module Rley # This module is used as a namespace | |
| 30 32 | 
             
                  def shortcut=(aShortcut)
         | 
| 31 33 | 
             
                    unless aShortcut.kind_of?(ShortcutEdge)
         | 
| 32 34 | 
             
                      raise StandardError, 'Invalid shortcut argument'
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                    end
         | 
| 35 | 
            -
                    
         | 
| 36 | 
            -
            =begin
         | 
| 37 | 
            -
                    unless next_symbol && next_symbol.kind_of?(Syntax::NonTerminal)
         | 
| 38 | 
            -
                      raise StandardError, 'Invalid shortcut usage'
         | 
| 39 35 | 
             
                    end
         | 
| 40 36 |  | 
| 41 | 
            -
                    shortcut_d_item = aShortcut.successor.dotted_item
         | 
| 42 | 
            -
                    unless (dotted_item.production == shortcut_d_item.production) &&
         | 
| 43 | 
            -
                      (dotted_item.position == shortcut_d_item.prev_position)
         | 
| 44 | 
            -
                      raise StandardError, 'Shortcut refers to wrong vertex'
         | 
| 45 | 
            -
                    end
         | 
| 46 | 
            -
            =end
         | 
| 47 37 | 
             
                    @shortcut = aShortcut
         | 
| 48 38 | 
             
                  end
         | 
| 49 39 |  | 
| 50 40 | 
             
                  # The label of this vertex.
         | 
| 51 41 | 
             
                  # It is the same as the label of the corresponding dotted item.
         | 
| 52 42 | 
             
                  # @return [String] Label for this vertex
         | 
| 53 | 
            -
                  def label | 
| 54 | 
            -
                     | 
| 43 | 
            +
                  def label
         | 
| 44 | 
            +
                    dotted_item.to_s
         | 
| 55 45 | 
             
                  end
         | 
| 56 46 |  | 
| 57 47 | 
             
                  # Returns true if the dotted item has a dot at the end of the production.
         | 
| 58 48 | 
             
                  # @return [Boolean]
         | 
| 59 | 
            -
                  def complete? | 
| 60 | 
            -
                     | 
| 49 | 
            +
                  def complete?
         | 
| 50 | 
            +
                    dotted_item.reduce_item?
         | 
| 61 51 | 
             
                  end
         | 
| 62 52 |  | 
| 63 53 | 
             
                  # Return the symbol before the dot.
         | 
| 64 54 | 
             
                  # @return [Syntax::GrmSymbol, NilClass] Previous symbol otherwise nil.
         | 
| 65 | 
            -
                  def prev_symbol | 
| 66 | 
            -
                     | 
| 55 | 
            +
                  def prev_symbol
         | 
| 56 | 
            +
                    dotted_item.prev_symbol
         | 
| 67 57 | 
             
                  end
         | 
| 68 58 |  | 
| 69 59 | 
             
                  # Return the symbol after the dot.
         | 
| 70 60 | 
             
                  # @return [Syntax::GrmSymbol, NilClass] Next grammar symbol otherwise nil.
         | 
| 71 | 
            -
                  def next_symbol | 
| 72 | 
            -
                     | 
| 61 | 
            +
                  def next_symbol
         | 
| 62 | 
            +
                    @next_symbol ||= dotted_item.next_symbol
         | 
| 73 63 | 
             
                  end
         | 
| 74 64 |  | 
| 75 65 | 
             
                  # Return the non-terminal symbol at the left-hand side of the production
         | 
| 76 66 | 
             
                  # @return [Syntax::GrmSymbol]
         | 
| 77 67 | 
             
                  #   The non-terminal symbol at left side of production.
         | 
| 78 | 
            -
                  def lhs | 
| 79 | 
            -
                     | 
| 68 | 
            +
                  def lhs
         | 
| 69 | 
            +
                    dotted_item.lhs
         | 
| 80 70 | 
             
                  end
         | 
| 81 71 | 
             
                end # class
         | 
| 82 72 | 
             
              end # module
         | 
| @@ -1,9 +1,11 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            require_relative 'vertex'
         | 
| 2 4 |  | 
| 3 5 | 
             
            module Rley # This module is used as a namespace
         | 
| 4 6 | 
             
              module GFG # This module is used as a namespace
         | 
| 5 7 | 
             
                # Abstract class.
         | 
| 6 | 
            -
                # Represents a specialized vertex in a grammar flow graph | 
| 8 | 
            +
                # Represents a specialized vertex in a grammar flow graph
         | 
| 7 9 | 
             
                # that is associated to a given non-terminal symbol and
         | 
| 8 10 | 
             
                # that may have in-degree or out-degree > 1
         | 
| 9 11 | 
             
                # Responsibilities (in addition to inherited ones):
         | 
| @@ -12,20 +14,20 @@ module Rley # This module is used as a namespace | |
| 12 14 | 
             
                  # The non-terminal symbol associated to the vertex
         | 
| 13 15 | 
             
                  # @return [Syntax::NonTerminal]
         | 
| 14 16 | 
             
                  attr_reader :non_terminal
         | 
| 15 | 
            -
             | 
| 17 | 
            +
             | 
| 16 18 | 
             
                  # Constructor to specialize in subclasses.
         | 
| 17 19 | 
             
                  # @param aNonTerminal [Syntax::NonTerminal]
         | 
| 18 20 | 
             
                  def initialize(aNonTerminal)
         | 
| 19 21 | 
             
                    super()
         | 
| 20 22 | 
             
                    @non_terminal = aNonTerminal
         | 
| 21 23 | 
             
                  end
         | 
| 22 | 
            -
             | 
| 24 | 
            +
             | 
| 23 25 | 
             
                  protected
         | 
| 24 26 |  | 
| 25 27 | 
             
                  # Validation method for adding an outgoing edge to the vertex.
         | 
| 26 28 | 
             
                  # A start vertex may accept an indegree and outdegree greater than one
         | 
| 27 29 | 
             
                  def check_add_edge(anEdge)
         | 
| 28 | 
            -
                     | 
| 30 | 
            +
                    anEdge
         | 
| 29 31 | 
             
                  end
         | 
| 30 32 | 
             
                end # class
         | 
| 31 33 | 
             
              end # module
         | 
    
        data/lib/rley/gfg/return_edge.rb
    CHANGED
    
    
    
        data/lib/rley/gfg/scan_edge.rb
    CHANGED
    
    | @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            require_relative 'edge'
         | 
| 2 4 |  | 
| 3 5 | 
             
            module Rley # This module is used as a namespace
         | 
| @@ -15,7 +17,7 @@ module Rley # This module is used as a namespace | |
| 15 17 | 
             
                    @terminal = aTerminal
         | 
| 16 18 | 
             
                  end
         | 
| 17 19 |  | 
| 18 | 
            -
                  def to_s | 
| 20 | 
            +
                  def to_s
         | 
| 19 21 | 
             
                    " -#{terminal}-> #{successor.label}"
         | 
| 20 22 | 
             
                  end
         | 
| 21 23 | 
             
                end # class
         | 
| @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            require_relative 'edge'
         | 
| 2 4 |  | 
| 3 5 | 
             
            module Rley # This module is used as a namespace
         | 
| @@ -10,12 +12,12 @@ module Rley # This module is used as a namespace | |
| 10 12 | 
             
                  attr_reader :nonterminal
         | 
| 11 13 |  | 
| 12 14 | 
             
                  def initialize(thePredecessor, theSuccessor)
         | 
| 13 | 
            -
                     | 
| 15 | 
            +
                    super(nil, theSuccessor)
         | 
| 14 16 | 
             
                    @nonterminal = thePredecessor.next_symbol
         | 
| 15 17 | 
             
                    thePredecessor.shortcut = self
         | 
| 16 18 | 
             
                  end
         | 
| 17 19 |  | 
| 18 | 
            -
                  def to_s | 
| 20 | 
            +
                  def to_s
         | 
| 19 21 | 
             
                    " -#{nonterminal}-> #{successor.label}"
         | 
| 20 22 | 
             
                  end
         | 
| 21 23 | 
             
                end # class
         | 
| @@ -1,21 +1,19 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            require_relative 'non_terminal_vertex'
         | 
| 2 4 |  | 
| 3 5 | 
             
            module Rley # This module is used as a namespace
         | 
| 4 6 | 
             
              module GFG # This module is used as a namespace
         | 
| 5 7 | 
             
                # TODO: change definition.
         | 
| 6 | 
            -
                # Represents a specialized vertex in a grammar flow graph | 
| 8 | 
            +
                # Represents a specialized vertex in a grammar flow graph
         | 
| 7 9 | 
             
                # that is associated to a given non-terminal symbol.
         | 
| 8 10 | 
             
                # Responsibilities (in addition to inherited ones):
         | 
| 9 11 | 
             
                # - Know its related non-terminal symbol
         | 
| 10 12 | 
             
                class StartVertex < NonTerminalVertex
         | 
| 11 | 
            -
                  def initialize(aNonTerminal)
         | 
| 12 | 
            -
                    super(aNonTerminal)
         | 
| 13 | 
            -
                  end
         | 
| 14 | 
            -
             | 
| 15 13 | 
             
                  # @return [String]
         | 
| 16 | 
            -
                  def label | 
| 17 | 
            -
                     | 
| 18 | 
            -
                  end | 
| 14 | 
            +
                  def label
         | 
| 15 | 
            +
                    ".#{non_terminal}"
         | 
| 16 | 
            +
                  end
         | 
| 19 17 | 
             
                end # class
         | 
| 20 18 | 
             
              end # module
         | 
| 21 19 | 
             
            end # module
         |