rley 0.8.00 → 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/CHANGELOG.md +10 -4
 - data/lib/rley/constants.rb +1 -1
 - data/lib/rley/notation/grammar_builder.rb +82 -29
 - data/lib/rley/parse_rep/ast_base_builder.rb +31 -5
 - data/lib/rley/syntax/base_grammar_builder.rb +8 -0
 - data/spec/rley/notation/grammar_builder_spec.rb +49 -42
 - data/spec/rley/parser/gfg_earley_parser_spec.rb +24 -4
 - metadata +2 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 5652efd2016050e7a40a94c279fa545a03b69b705bdcc5089a479d72c4743325
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: c3f46ba853632a95e3c1fbe16f0f77f8e8a07ed3acd69a82297ca13eec9b6ccc
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 532ca6d76a277e6fd234d66ec74e9ade425a91f8ace039e0dc0636547663ac52f64613001e9c36497d5a0e0d9fe67f09eb2fff80b77d8c2f4950095e58ac3b2e
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: b288a0345c1696b8987b362ab99dafa4354f94ece73c5c80c87d7a28aa3c3d9ccaf0f516f29cead1707727582e917812435e4254e372aa2d62c110af7aa99a99
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,3 +1,9 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ### 0.8.01 / 2021-08-22
         
     | 
| 
      
 2 
     | 
    
         
            +
            - Unused/redundant file removal. Fix in rule generation
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            * [CHANGE] Removal of files in repository that were redundant/useless.
         
     | 
| 
      
 5 
     | 
    
         
            +
            * [FIX] The rule ordering was broken by the rules implicitly generated by Rlry
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
       1 
7 
     | 
    
         
             
            ### 0.8.00 / 2021-08-15
         
     | 
| 
       2 
8 
     | 
    
         
             
            - New grammar builder that accepts ? * + modifiers
         
     | 
| 
       3 
9 
     | 
    
         | 
| 
         @@ -15,10 +21,10 @@ 
     | 
|
| 
       15 
21 
     | 
    
         
             
            - [FIX] Method `GFGParsing#nullable_rule`: issue with nullable productions having at least one member in their rhs.
         
     | 
| 
       16 
22 
     | 
    
         | 
| 
       17 
23 
     | 
    
         
             
            ### 0.7.04 / 2019-08-17
         
     | 
| 
       18 
     | 
    
         
            -
            - Rley recognizer is about 25% faster than previous version. Kudos to the people 
     | 
| 
       19 
     | 
    
         
            -
            behind the *magic_frozen_string_literal* gem. 
     | 
| 
      
 24 
     | 
    
         
            +
            - Rley recognizer is about 25% faster than previous version. Kudos to the people
         
     | 
| 
      
 25 
     | 
    
         
            +
            behind the *magic_frozen_string_literal* gem.
         
     | 
| 
       20 
26 
     | 
    
         
             
            - Code refactoring to use string frozen magic comments (as a consequence, Rley runs only on Rubies 2.3 or newer).  
         
     | 
| 
       21 
     | 
    
         
            -
            - Code restyling to please rubocop 0.7.40. 
     | 
| 
      
 27 
     | 
    
         
            +
            - Code restyling to please rubocop 0.7.40.
         
     | 
| 
       22 
28 
     | 
    
         
             
            - [CHANGE] Class `ParseEntrySet`: minor code optimization
         
     | 
| 
       23 
29 
     | 
    
         
             
            - [CHANGE] File `README.md` removed allusion to Ruby 2.0.x up to 2.2.x.
         
     | 
| 
       24 
30 
     | 
    
         
             
            - [CHANGE] File `README.md` added Ruby 2.6.x up as supported version.
         
     | 
| 
         @@ -103,7 +109,7 @@ behind the *magic_frozen_string_literal* gem. 
     | 
|
| 
       103 
109 
     | 
    
         
             
            * [FIX] Code re-styling to remove most style offenses found by Rubocop 0.52.1
         
     | 
| 
       104 
110 
     | 
    
         | 
| 
       105 
111 
     | 
    
         
             
            ### 0.6.00 / 2018-02-25
         
     | 
| 
       106 
     | 
    
         
            -
            Version bump. Highlights: new programming interface through facade object, improved AST generation. 
     | 
| 
      
 112 
     | 
    
         
            +
            Version bump. Highlights: new programming interface through facade object, improved AST generation.
         
     | 
| 
       107 
113 
     | 
    
         
             
            * [NEW] Class `Rley::Engine`: Implementation of Facade design pattern to reach more convenient interface.
         
     | 
| 
       108 
114 
     | 
    
         
             
            * [NEW] Class `Rley::ParseRep::ASTBaseBuilder` Abstract class that simplifies the creation of custom AST (Abstract Syntax Tree)
         
     | 
| 
       109 
115 
     | 
    
         
             
            * [NEW] Module `Rley::ParseRep` hosts the classes for building parse representations (parse trees and forests)
         
     | 
    
        data/lib/rley/constants.rb
    CHANGED
    
    
| 
         @@ -1,12 +1,16 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            require 'set'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
       4 
5 
     | 
    
         
             
            require_relative 'parser'
         
     | 
| 
       5 
6 
     | 
    
         
             
            require_relative 'ast_visitor'
         
     | 
| 
       6 
7 
     | 
    
         
             
            require_relative '../syntax/match_closest'
         
     | 
| 
       7 
8 
     | 
    
         | 
| 
       8 
9 
     | 
    
         
             
            module Rley # This module is used as a namespace
         
     | 
| 
       9 
10 
     | 
    
         
             
              module Notation # This module is used as a namespace
         
     | 
| 
      
 11 
     | 
    
         
            +
                # Structure used for production rules that are implicitly generated by Rley
         
     | 
| 
      
 12 
     | 
    
         
            +
                RawRule = Struct.new(:lhs, :rhs, :tag, :simple, :constraints)
         
     | 
| 
      
 13 
     | 
    
         
            +
              
         
     | 
| 
       10 
14 
     | 
    
         
             
                # Builder GoF pattern. Builder builds a complex object
         
     | 
| 
       11 
15 
     | 
    
         
             
                #   (say, a grammar) from simpler objects (terminals and productions)
         
     | 
| 
       12 
16 
     | 
    
         
             
                #   and using a step by step approach.
         
     | 
| 
         @@ -24,16 +28,19 @@ module Rley # This module is used as a namespace 
     | 
|
| 
       24 
28 
     | 
    
         
             
                  # @return [Array<Production>] The list of production rules for
         
     | 
| 
       25 
29 
     | 
    
         
             
                  #   the grammar to build.
         
     | 
| 
       26 
30 
     | 
    
         
             
                  attr_reader(:productions)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  
         
     | 
| 
      
 32 
     | 
    
         
            +
                  # @return [Hash{String, String}] The synthesized raw productions
         
     | 
| 
      
 33 
     | 
    
         
            +
                  attr_reader(:synthetized)
         
     | 
| 
       27 
34 
     | 
    
         | 
| 
       28 
35 
     | 
    
         
             
                  # Creates a new grammar builder.
         
     | 
| 
       29 
36 
     | 
    
         
             
                  # @param aBlock [Proc] code block used to build the grammar.
         
     | 
| 
       30 
37 
     | 
    
         
             
                  # @example Building a tiny English grammar
         
     | 
| 
       31 
     | 
    
         
            -
                  #   builder = Rley:: 
     | 
| 
      
 38 
     | 
    
         
            +
                  #   builder = Rley::Notation::GrammarBuilder.new do
         
     | 
| 
       32 
39 
     | 
    
         
             
                  #     add_terminals('n', 'v', 'adj', 'det')
         
     | 
| 
       33 
     | 
    
         
            -
                  #     rule 'S' =>  
     | 
| 
       34 
     | 
    
         
            -
                  #     rule 'VP' =>  
     | 
| 
       35 
     | 
    
         
            -
                  #     rule 'NP' =>  
     | 
| 
       36 
     | 
    
         
            -
                  #     rule 'NP' =>  
     | 
| 
      
 40 
     | 
    
         
            +
                  #     rule 'S' => 'NP VP'
         
     | 
| 
      
 41 
     | 
    
         
            +
                  #     rule 'VP' => 'v NP'
         
     | 
| 
      
 42 
     | 
    
         
            +
                  #     rule 'NP' => 'det n'
         
     | 
| 
      
 43 
     | 
    
         
            +
                  #     rule 'NP' => 'adj NP'
         
     | 
| 
       37 
44 
     | 
    
         
             
                  #   end
         
     | 
| 
       38 
45 
     | 
    
         
             
                  #   tiny_eng = builder.grammar
         
     | 
| 
       39 
46 
     | 
    
         
             
                  def initialize(&aBlock)
         
     | 
| 
         @@ -41,8 +48,12 @@ module Rley # This module is used as a namespace 
     | 
|
| 
       41 
48 
     | 
    
         
             
                    @productions = []
         
     | 
| 
       42 
49 
     | 
    
         
             
                    @parser = Notation::Parser.new
         
     | 
| 
       43 
50 
     | 
    
         
             
                    @visitor2rhs = {}
         
     | 
| 
      
 51 
     | 
    
         
            +
                    @synthetized = {}
         
     | 
| 
       44 
52 
     | 
    
         | 
| 
       45 
     | 
    
         
            -
                     
     | 
| 
      
 53 
     | 
    
         
            +
                    if block_given?
         
     | 
| 
      
 54 
     | 
    
         
            +
                      instance_exec(&aBlock)
         
     | 
| 
      
 55 
     | 
    
         
            +
                      grammar_complete!
         
     | 
| 
      
 56 
     | 
    
         
            +
                    end
         
     | 
| 
       46 
57 
     | 
    
         
             
                  end
         
     | 
| 
       47 
58 
     | 
    
         | 
| 
       48 
59 
     | 
    
         
             
                  # Retrieve a grammar symbol from its name.
         
     | 
| 
         @@ -60,6 +71,14 @@ module Rley # This module is used as a namespace 
     | 
|
| 
       60 
71 
     | 
    
         
             
                    new_symbs = build_symbols(Syntax::Terminal, terminalSymbols)
         
     | 
| 
       61 
72 
     | 
    
         
             
                    symbols.merge!(new_symbs)
         
     | 
| 
       62 
73 
     | 
    
         
             
                  end
         
     | 
| 
      
 74 
     | 
    
         
            +
                  
         
     | 
| 
      
 75 
     | 
    
         
            +
                  # Add the given marker symbol to the grammar of the language
         
     | 
| 
      
 76 
     | 
    
         
            +
                  # @param aMarkerSymbol [String] A mazker symbol
         
     | 
| 
      
 77 
     | 
    
         
            +
                  # @return [void]      
         
     | 
| 
      
 78 
     | 
    
         
            +
                  def add_marker(aMarkerSymbol)
         
     | 
| 
      
 79 
     | 
    
         
            +
                    new_symb = build_symbol(Syntax::Marker, aMarkerSymbol)
         
     | 
| 
      
 80 
     | 
    
         
            +
                    symbols[new_symb.name] = new_symb
         
     | 
| 
      
 81 
     | 
    
         
            +
                  end       
         
     | 
| 
       63 
82 
     | 
    
         | 
| 
       64 
83 
     | 
    
         
             
                  # Add a production rule in the grammar given one
         
     | 
| 
       65 
84 
     | 
    
         
             
                  # key-value pair of the form: String => String.
         
     | 
| 
         @@ -204,7 +223,7 @@ module Rley # This module is used as a namespace 
     | 
|
| 
       204 
223 
     | 
    
         
             
                  end
         
     | 
| 
       205 
224 
     | 
    
         | 
| 
       206 
225 
     | 
    
         
             
                  ##################################
         
     | 
| 
       207 
     | 
    
         
            -
                  # AST visit notification events
         
     | 
| 
      
 226 
     | 
    
         
            +
                  # RGN's AST visit notification events
         
     | 
| 
       208 
227 
     | 
    
         
             
                  # ################################
         
     | 
| 
       209 
228 
     | 
    
         
             
                  def after_symbol_node(aSymbolNode, aVisitor)
         
     | 
| 
       210 
229 
     | 
    
         
             
                    symb_name = aSymbolNode.name
         
     | 
| 
         @@ -215,9 +234,9 @@ module Rley # This module is used as a namespace 
     | 
|
| 
       215 
234 
     | 
    
         
             
                      # implicitly called: rule('symb_name_qmark' => '').tag suffix_qmark_none
         
     | 
| 
       216 
235 
     | 
    
         
             
                      name_modified = "#{symb_name}#{suffix_qmark}"
         
     | 
| 
       217 
236 
     | 
    
         
             
                      unless symbols.include? name_modified
         
     | 
| 
       218 
     | 
    
         
            -
                         
     | 
| 
       219 
     | 
    
         
            -
                         
     | 
| 
       220 
     | 
    
         
            -
                         
     | 
| 
      
 237 
     | 
    
         
            +
                        add_nonterminal(name_modified)
         
     | 
| 
      
 238 
     | 
    
         
            +
                        add_raw_rule(name_modified, "#{symb_name}", suffix_qmark_one)
         
     | 
| 
      
 239 
     | 
    
         
            +
                        add_raw_rule(name_modified, '', suffix_qmark_none)
         
     | 
| 
       221 
240 
     | 
    
         
             
                      end
         
     | 
| 
       222 
241 
     | 
    
         
             
                      symb_name = name_modified
         
     | 
| 
       223 
242 
     | 
    
         | 
| 
         @@ -226,9 +245,9 @@ module Rley # This module is used as a namespace 
     | 
|
| 
       226 
245 
     | 
    
         
             
                      # implicitly called: rule('symb_name_star' => '').tag suffix_star_none
         
     | 
| 
       227 
246 
     | 
    
         
             
                      name_modified = "#{symb_name}#{suffix_star}"
         
     | 
| 
       228 
247 
     | 
    
         
             
                      unless symbols.include? name_modified
         
     | 
| 
       229 
     | 
    
         
            -
                         
     | 
| 
       230 
     | 
    
         
            -
                         
     | 
| 
       231 
     | 
    
         
            -
                         
     | 
| 
      
 248 
     | 
    
         
            +
                        add_nonterminal(name_modified)
         
     | 
| 
      
 249 
     | 
    
         
            +
                        add_raw_rule(name_modified, "#{name_modified} #{symb_name}", suffix_star_more)
         
     | 
| 
      
 250 
     | 
    
         
            +
                        add_raw_rule(name_modified, [], suffix_star_none)
         
     | 
| 
       232 
251 
     | 
    
         
             
                      end
         
     | 
| 
       233 
252 
     | 
    
         
             
                      symb_name = name_modified
         
     | 
| 
       234 
253 
     | 
    
         | 
| 
         @@ -238,9 +257,9 @@ module Rley # This module is used as a namespace 
     | 
|
| 
       238 
257 
     | 
    
         
             
                    when  :one_or_more
         
     | 
| 
       239 
258 
     | 
    
         
             
                      name_modified = "#{symb_name}#{suffix_plus}"
         
     | 
| 
       240 
259 
     | 
    
         
             
                      unless symbols.include? name_modified
         
     | 
| 
       241 
     | 
    
         
            -
                         
     | 
| 
       242 
     | 
    
         
            -
                         
     | 
| 
       243 
     | 
    
         
            -
                         
     | 
| 
      
 260 
     | 
    
         
            +
                        add_nonterminal(name_modified)
         
     | 
| 
      
 261 
     | 
    
         
            +
                        add_raw_rule(name_modified, "#{name_modified} #{symb_name}", suffix_plus_more)
         
     | 
| 
      
 262 
     | 
    
         
            +
                        add_raw_rule(name_modified, symb_name, suffix_plus_one)
         
     | 
| 
       244 
263 
     | 
    
         
             
                      end
         
     | 
| 
       245 
264 
     | 
    
         
             
                      symb_name = name_modified
         
     | 
| 
       246 
265 
     | 
    
         
             
                    else
         
     | 
| 
         @@ -264,10 +283,9 @@ module Rley # This module is used as a namespace 
     | 
|
| 
       264 
283 
     | 
    
         
             
                    symb_name = sequence_name(aGroupingNode)
         
     | 
| 
       265 
284 
     | 
    
         | 
| 
       266 
285 
     | 
    
         
             
                    unless symbols.include?(symb_name) || aGroupingNode.repetition == :exactly_one
         
     | 
| 
       267 
     | 
    
         
            -
                       
     | 
| 
       268 
     | 
    
         
            -
                       
     | 
| 
       269 
     | 
    
         
            -
                       
     | 
| 
       270 
     | 
    
         
            -
                      prod.constraints = aGroupingNode.constraints
         
     | 
| 
      
 286 
     | 
    
         
            +
                      add_nonterminal(symb_name)
         
     | 
| 
      
 287 
     | 
    
         
            +
                      rhs = serialize_sequence(aGroupingNode)
         
     | 
| 
      
 288 
     | 
    
         
            +
                      add_raw_rule(symb_name, rhs, 'return_children', true, aGroupingNode.constraints)
         
     | 
| 
       271 
289 
     | 
    
         
             
                    end
         
     | 
| 
       272 
290 
     | 
    
         
             
                    name_modified = "#{symb_name}#{repetition2suffix(aGroupingNode.repetition)}"
         
     | 
| 
       273 
291 
     | 
    
         | 
| 
         @@ -276,18 +294,18 @@ module Rley # This module is used as a namespace 
     | 
|
| 
       276 
294 
     | 
    
         
             
                      # implicitly called: rule('symb_name_qmark' => 'symb_name_qmark').tag suffix_qmark_one
         
     | 
| 
       277 
295 
     | 
    
         
             
                      # implicitly called: rule('symb_name_qmark' => '').tag suffix_qmark_none
         
     | 
| 
       278 
296 
     | 
    
         
             
                      unless symbols.include? name_modified
         
     | 
| 
       279 
     | 
    
         
            -
                         
     | 
| 
       280 
     | 
    
         
            -
                         
     | 
| 
       281 
     | 
    
         
            -
                         
     | 
| 
      
 297 
     | 
    
         
            +
                        add_nonterminal(name_modified)
         
     | 
| 
      
 298 
     | 
    
         
            +
                        add_raw_rule(name_modified, symb_name, suffix_qmark_one, true)
         
     | 
| 
      
 299 
     | 
    
         
            +
                        add_raw_rule(name_modified, [], suffix_qmark_none, true)
         
     | 
| 
       282 
300 
     | 
    
         
             
                      end
         
     | 
| 
       283 
301 
     | 
    
         | 
| 
       284 
302 
     | 
    
         
             
                    when :zero_or_more
         
     | 
| 
       285 
303 
     | 
    
         
             
                      # implicitly called: rule('symb_name_star' => 'symb_name_star symb_name').tag suffix_star_more
         
     | 
| 
       286 
304 
     | 
    
         
             
                      # implicitly called: rule('symb_name_star' => '').tag suffix_star_none
         
     | 
| 
       287 
305 
     | 
    
         
             
                      unless symbols.include? name_modified
         
     | 
| 
       288 
     | 
    
         
            -
                         
     | 
| 
       289 
     | 
    
         
            -
                         
     | 
| 
       290 
     | 
    
         
            -
                         
     | 
| 
      
 306 
     | 
    
         
            +
                        add_nonterminal(name_modified)
         
     | 
| 
      
 307 
     | 
    
         
            +
                        add_raw_rule(name_modified, "#{name_modified} #{symb_name}", suffix_star_more)
         
     | 
| 
      
 308 
     | 
    
         
            +
                        add_raw_rule(name_modified, '', suffix_star_none)
         
     | 
| 
       291 
309 
     | 
    
         
             
                      end
         
     | 
| 
       292 
310 
     | 
    
         | 
| 
       293 
311 
     | 
    
         
             
                    when :exactly_one
         
     | 
| 
         @@ -295,9 +313,9 @@ module Rley # This module is used as a namespace 
     | 
|
| 
       295 
313 
     | 
    
         | 
| 
       296 
314 
     | 
    
         
             
                    when :one_or_more
         
     | 
| 
       297 
315 
     | 
    
         
             
                      unless symbols.include? name_modified
         
     | 
| 
       298 
     | 
    
         
            -
                         
     | 
| 
       299 
     | 
    
         
            -
                         
     | 
| 
       300 
     | 
    
         
            -
                         
     | 
| 
      
 316 
     | 
    
         
            +
                        add_nonterminal(name_modified)
         
     | 
| 
      
 317 
     | 
    
         
            +
                        add_raw_rule(name_modified, "#{name_modified} #{symb_name}", suffix_plus_more)
         
     | 
| 
      
 318 
     | 
    
         
            +
                        add_raw_rule(name_modified, symb_name, suffix_plus_one)
         
     | 
| 
       301 
319 
     | 
    
         
             
                      end
         
     | 
| 
       302 
320 
     | 
    
         
             
                    else
         
     | 
| 
       303 
321 
     | 
    
         
             
                      raise StandardError, 'Unhandled multiplicity'
         
     | 
| 
         @@ -309,7 +327,17 @@ module Rley # This module is used as a namespace 
     | 
|
| 
       309 
327 
     | 
    
         
             
                    end
         
     | 
| 
       310 
328 
     | 
    
         
             
                  end
         
     | 
| 
       311 
329 
     | 
    
         | 
| 
      
 330 
     | 
    
         
            +
                  # A notification to the builderobject that the programmer
         
     | 
| 
      
 331 
     | 
    
         
            +
                  # has completed the entry of terminals and production rules
         
     | 
| 
      
 332 
     | 
    
         
            +
                  def grammar_complete!
         
     | 
| 
      
 333 
     | 
    
         
            +
                    process_raw_rules()
         
     | 
| 
      
 334 
     | 
    
         
            +
                  end
         
     | 
| 
      
 335 
     | 
    
         
            +
             
     | 
| 
       312 
336 
     | 
    
         
             
                  private
         
     | 
| 
      
 337 
     | 
    
         
            +
                  
         
     | 
| 
      
 338 
     | 
    
         
            +
                  def add_nonterminal(aName) 
         
     | 
| 
      
 339 
     | 
    
         
            +
                    symbols[aName] = Syntax::NonTerminal.new(aName)
         
     | 
| 
      
 340 
     | 
    
         
            +
                  end  
         
     | 
| 
       313 
341 
     | 
    
         | 
| 
       314 
342 
     | 
    
         
             
                  def simple_rule(aProductionRepr)
         
     | 
| 
       315 
343 
     | 
    
         
             
                    aProductionRepr.each_pair do |(lhs_name, rhs_repr)|
         
     | 
| 
         @@ -444,6 +472,31 @@ module Rley # This module is used as a namespace 
     | 
|
| 
       444 
472 
     | 
    
         | 
| 
       445 
473 
     | 
    
         
             
                    text.strip
         
     | 
| 
       446 
474 
     | 
    
         
             
                  end
         
     | 
| 
      
 475 
     | 
    
         
            +
                  
         
     | 
| 
      
 476 
     | 
    
         
            +
                  def add_raw_rule(aSymbol, aRHS, aTag, simplified = false, constraints = [])
         
     | 
| 
      
 477 
     | 
    
         
            +
                    raw_rule = RawRule.new(aSymbol, aRHS, aTag, simplified, constraints)
         
     | 
| 
      
 478 
     | 
    
         
            +
                    if synthetized.include?(aSymbol)
         
     | 
| 
      
 479 
     | 
    
         
            +
                      @synthetized[aSymbol] << raw_rule
         
     | 
| 
      
 480 
     | 
    
         
            +
                    else
         
     | 
| 
      
 481 
     | 
    
         
            +
                      @synthetized[aSymbol] = [raw_rule]
         
     | 
| 
      
 482 
     | 
    
         
            +
                    end
         
     | 
| 
      
 483 
     | 
    
         
            +
                  end
         
     | 
| 
      
 484 
     | 
    
         
            +
             
     | 
| 
      
 485 
     | 
    
         
            +
                  def process_raw_rules
         
     | 
| 
      
 486 
     | 
    
         
            +
                    until synthetized.empty? do
         
     | 
| 
      
 487 
     | 
    
         
            +
                      raw_rules = synthetized.delete(synthetized.keys.first)
         
     | 
| 
      
 488 
     | 
    
         
            +
                      raw_rules.each do |raw|
         
     | 
| 
      
 489 
     | 
    
         
            +
                        new_prod = nil
         
     | 
| 
      
 490 
     | 
    
         
            +
                        if raw.simple
         
     | 
| 
      
 491 
     | 
    
         
            +
                          new_prod = simple_rule(raw.lhs => raw.rhs)
         
     | 
| 
      
 492 
     | 
    
         
            +
                        else
         
     | 
| 
      
 493 
     | 
    
         
            +
                          new_prod = rule(raw.lhs => raw.rhs)
         
     | 
| 
      
 494 
     | 
    
         
            +
                        end
         
     | 
| 
      
 495 
     | 
    
         
            +
                        new_prod.tag(raw.tag)
         
     | 
| 
      
 496 
     | 
    
         
            +
                        new_prod.constraints = raw.constraints
         
     | 
| 
      
 497 
     | 
    
         
            +
                      end
         
     | 
| 
      
 498 
     | 
    
         
            +
                    end
         
     | 
| 
      
 499 
     | 
    
         
            +
                  end
         
     | 
| 
       447 
500 
     | 
    
         
             
                end # class
         
     | 
| 
       448 
501 
     | 
    
         
             
              end # module
         
     | 
| 
       449 
502 
     | 
    
         
             
            end # module
         
     | 
| 
         @@ -126,16 +126,42 @@ module Rley # This module is used as a namespace 
     | 
|
| 
       126 
126 
     | 
    
         | 
| 
       127 
127 
     | 
    
         
             
                  # Standard method for handling one or more modifier: symbol+
         
     | 
| 
       128 
128 
     | 
    
         
             
                  # rule('symbol_plus' => 'symbol_plus symbol')
         
     | 
| 
       129 
     | 
    
         
            -
                  def reduce_base_plus_more(_production, _range, _tokens, theChildren)
         
     | 
| 
       130 
     | 
    
         
            -
                    theChildren[0] << theChildren[1]
         
     | 
| 
       131 
     | 
    
         
            -
                  end
         
     | 
| 
      
 129 
     | 
    
         
            +
                  # def reduce_base_plus_more(_production, _range, _tokens, theChildren)
         
     | 
| 
      
 130 
     | 
    
         
            +
                    # theChildren[0] << theChildren[1]
         
     | 
| 
      
 131 
     | 
    
         
            +
                  # end
         
     | 
| 
       132 
132 
     | 
    
         | 
| 
       133 
133 
     | 
    
         
             
                  # Standard rule method handling one or more modifier: symbol+
         
     | 
| 
       134 
134 
     | 
    
         
             
                  # rule('symbol_plus' => 'symbol')
         
     | 
| 
       135 
     | 
    
         
            -
                  def reduce_base_plus_last(_production, _range, _tokens, theChildren)
         
     | 
| 
       136 
     | 
    
         
            -
                    [theChildren[0]]
         
     | 
| 
      
 135 
     | 
    
         
            +
                  # def reduce_base_plus_last(_production, _range, _tokens, theChildren)
         
     | 
| 
      
 136 
     | 
    
         
            +
                    # [theChildren[0]]
         
     | 
| 
      
 137 
     | 
    
         
            +
                  # end
         
     | 
| 
      
 138 
     | 
    
         
            +
                  
         
     | 
| 
      
 139 
     | 
    
         
            +
                  # Implicit rule generated for * modifier
         
     | 
| 
      
 140 
     | 
    
         
            +
                  # rule('X') => 'X item'.as '_star_more'
         
     | 
| 
      
 141 
     | 
    
         
            +
                  def reduce__star_more(_production, _range, _tokens, theChildren)
         
     | 
| 
      
 142 
     | 
    
         
            +
                    theChildren[0]  << theChildren[1]
         
     | 
| 
      
 143 
     | 
    
         
            +
                    theChildren[0]
         
     | 
| 
      
 144 
     | 
    
         
            +
                  end
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
                  # Implicit rule generated for * modifier
         
     | 
| 
      
 147 
     | 
    
         
            +
                  # rule('X') => ''.as '_star_none'
         
     | 
| 
      
 148 
     | 
    
         
            +
                  def reduce__star_none(_production, _range, _tokens, theChildren)
         
     | 
| 
      
 149 
     | 
    
         
            +
                    []
         
     | 
| 
       137 
150 
     | 
    
         
             
                  end
         
     | 
| 
       138 
151 
     | 
    
         | 
| 
      
 152 
     | 
    
         
            +
                  # Implicit rule generated for + modifier
         
     | 
| 
      
 153 
     | 
    
         
            +
                  # rule('X') => 'X item'.as '_plus_more'
         
     | 
| 
      
 154 
     | 
    
         
            +
                  def reduce__plus_more(_production, _range, _tokens, theChildren)
         
     | 
| 
      
 155 
     | 
    
         
            +
                    theChildren[0]  << theChildren[1]
         
     | 
| 
      
 156 
     | 
    
         
            +
                    theChildren[0]
         
     | 
| 
      
 157 
     | 
    
         
            +
                  end
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
                  # Implicit rule generated for + modifier
         
     | 
| 
      
 160 
     | 
    
         
            +
                  # rule('X') => 'item'.as '_plus_one'
         
     | 
| 
      
 161 
     | 
    
         
            +
                  def reduce__plus_one(_production, _range, _tokens, theChildren)
         
     | 
| 
      
 162 
     | 
    
         
            +
                    [theChildren[0]]
         
     | 
| 
      
 163 
     | 
    
         
            +
                  end      
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
       139 
165 
     | 
    
         
             
                end # class
         
     | 
| 
       140 
166 
     | 
    
         
             
              end # module
         
     | 
| 
       141 
167 
     | 
    
         
             
            end # module
         
     | 
| 
         @@ -55,6 +55,14 @@ module Rley # This module is used as a namespace 
     | 
|
| 
       55 
55 
     | 
    
         
             
                    new_symbs = build_symbols(Terminal, terminalSymbols)
         
     | 
| 
       56 
56 
     | 
    
         
             
                    symbols.merge!(new_symbs)
         
     | 
| 
       57 
57 
     | 
    
         
             
                  end
         
     | 
| 
      
 58 
     | 
    
         
            +
                  
         
     | 
| 
      
 59 
     | 
    
         
            +
                  # Add the given marker symbol to the grammar of the language
         
     | 
| 
      
 60 
     | 
    
         
            +
                  # @param aMarkerSymbol [Syntax::Marker] A mazker symbol
         
     | 
| 
      
 61 
     | 
    
         
            +
                  # @return [void]      
         
     | 
| 
      
 62 
     | 
    
         
            +
                  def add_marker(aMarkerSymbol)
         
     | 
| 
      
 63 
     | 
    
         
            +
                    new_symb = build_symbol(Marker, aMarkerSymbol)
         
     | 
| 
      
 64 
     | 
    
         
            +
                    symbols[aMarkerSymbol.name] = new_symb
         
     | 
| 
      
 65 
     | 
    
         
            +
                  end      
         
     | 
| 
       58 
66 
     | 
    
         | 
| 
       59 
67 
     | 
    
         
             
                  # Add a production rule in the grammar given one
         
     | 
| 
       60 
68 
     | 
    
         
             
                  # key-value pair of the form: String => Array.
         
     | 
| 
         @@ -113,70 +113,78 @@ module Rley # Open this namespace to avoid module qualifier prefixes 
     | 
|
| 
       113 
113 
     | 
    
         
             
                      expect(new_prod.constraints[0].closest_symb).to eq('IF')
         
     | 
| 
       114 
114 
     | 
    
         
             
                    end
         
     | 
| 
       115 
115 
     | 
    
         | 
| 
       116 
     | 
    
         
            -
                    it  
     | 
| 
      
 116 
     | 
    
         
            +
                    it 'should support optional symbol' do
         
     | 
| 
       117 
117 
     | 
    
         
             
                      instance = GrammarBuilder.new
         
     | 
| 
       118 
118 
     | 
    
         
             
                      instance.add_terminals('LPAREN', 'RPAREN')
         
     | 
| 
       119 
119 
     | 
    
         | 
| 
       120 
     | 
    
         
            -
                      instance. 
     | 
| 
      
 120 
     | 
    
         
            +
                      instance.rule 'argument_list' => 'LPAREN arguments? RPAREN'
         
     | 
| 
      
 121 
     | 
    
         
            +
                      instance.grammar_complete!
         
     | 
| 
       121 
122 
     | 
    
         | 
| 
       122 
123 
     | 
    
         
             
                      # implicitly called: rule('arguments_qmark' => 'arguments').tag suffix_qmark_one
         
     | 
| 
       123 
124 
     | 
    
         
             
                      # implicitly called: rule('arguments_qmark' => '').tag suffix_qmark_none
         
     | 
| 
       124 
125 
     | 
    
         
             
                      expect(instance.productions.size).to eq(3)
         
     | 
| 
       125 
126 
     | 
    
         
             
                      prod_star = instance.productions.select { |prod| prod.lhs.name == 'arguments_qmark' }
         
     | 
| 
       126 
127 
     | 
    
         
             
                      expect(prod_star.size).to eq(2)
         
     | 
| 
       127 
     | 
    
         
            -
                       
     | 
| 
       128 
     | 
    
         
            -
                      expect( 
     | 
| 
       129 
     | 
    
         
            -
                      expect( 
     | 
| 
      
 128 
     | 
    
         
            +
                      first_prod = instance.productions.first
         
     | 
| 
      
 129 
     | 
    
         
            +
                      expect(first_prod.lhs.name).to eq('argument_list')
         
     | 
| 
      
 130 
     | 
    
         
            +
                      expect(first_prod.rhs.members[1].name).to eq('arguments_qmark')
         
     | 
| 
       130 
131 
     | 
    
         
             
                    end
         
     | 
| 
       131 
132 
     | 
    
         | 
| 
       132 
133 
     | 
    
         
             
                    it "should support Kleene's star" do
         
     | 
| 
       133 
134 
     | 
    
         
             
                      instance = GrammarBuilder.new
         
     | 
| 
       134 
135 
     | 
    
         
             
                      instance.add_terminals('EOF')
         
     | 
| 
       135 
136 
     | 
    
         | 
| 
       136 
     | 
    
         
            -
                      instance. 
     | 
| 
      
 137 
     | 
    
         
            +
                      instance.rule 'program' => 'declaration* EOF'
         
     | 
| 
      
 138 
     | 
    
         
            +
                      instance.grammar_complete!
         
     | 
| 
       137 
139 
     | 
    
         | 
| 
       138 
140 
     | 
    
         
             
                      # implicitly called: rule('declaration_star' => 'declaration_star declaration').tag suffix_star_more
         
     | 
| 
       139 
141 
     | 
    
         
             
                      # implicitly called: rule('declaration_star' => '').tag suffix_star_last
         
     | 
| 
       140 
142 
     | 
    
         
             
                      expect(instance.productions.size).to eq(3)
         
     | 
| 
       141 
143 
     | 
    
         
             
                      prod_star = instance.productions.select { |prod| prod.lhs.name == 'declaration_star' }
         
     | 
| 
       142 
144 
     | 
    
         
             
                      expect(prod_star.size).to eq(2)
         
     | 
| 
       143 
     | 
    
         
            -
                       
     | 
| 
       144 
     | 
    
         
            -
                      expect( 
     | 
| 
       145 
     | 
    
         
            -
                      expect( 
     | 
| 
      
 145 
     | 
    
         
            +
                      first_prod = instance.productions.first
         
     | 
| 
      
 146 
     | 
    
         
            +
                      expect(first_prod.lhs.name).to eq('program')
         
     | 
| 
      
 147 
     | 
    
         
            +
                      expect(first_prod.rhs.members[0].name).to eq('declaration_star')
         
     | 
| 
       146 
148 
     | 
    
         
             
                    end
         
     | 
| 
       147 
149 
     | 
    
         | 
| 
       148 
150 
     | 
    
         
             
                    it "should support symbols decorated with Kleene's plus" do
         
     | 
| 
       149 
151 
     | 
    
         
             
                      instance = GrammarBuilder.new
         
     | 
| 
       150 
152 
     | 
    
         
             
                      instance.add_terminals('plus', 'minus', 'digit')
         
     | 
| 
       151 
153 
     | 
    
         | 
| 
       152 
     | 
    
         
            -
                      instance. 
     | 
| 
       153 
     | 
    
         
            -
                      instance. 
     | 
| 
       154 
     | 
    
         
            -
                      instance. 
     | 
| 
       155 
     | 
    
         
            -
                      instance. 
     | 
| 
       156 
     | 
    
         
            -
                       
     | 
| 
       157 
     | 
    
         
            -
                      instance. 
     | 
| 
      
 154 
     | 
    
         
            +
                      instance.rule 'integer' => 'value'
         
     | 
| 
      
 155 
     | 
    
         
            +
                      instance.rule 'integer' => 'sign value'
         
     | 
| 
      
 156 
     | 
    
         
            +
                      instance.rule 'sign' => 'plus'
         
     | 
| 
      
 157 
     | 
    
         
            +
                      instance.rule 'sign' => 'minus'
         
     | 
| 
      
 158 
     | 
    
         
            +
                      instance.rule 'value' => 'digit+'
         
     | 
| 
      
 159 
     | 
    
         
            +
                      expect(instance.productions.size).to eq(5)
         
     | 
| 
      
 160 
     | 
    
         
            +
                      instance.grammar_complete!
         
     | 
| 
      
 161 
     | 
    
         
            +
                      expect(instance.productions.size).to eq(7)
         
     | 
| 
       158 
162 
     | 
    
         | 
| 
       159 
163 
     | 
    
         
             
                      # implicitly called: rule('digit_plus' => 'digit_plus digit').tag suffix_plus_more
         
     | 
| 
       160 
164 
     | 
    
         
             
                      # implicitly called: rule('digit_plus' => 'digit').tag suffix_plus_last
         
     | 
| 
       161 
165 
     | 
    
         
             
                      expect(instance.productions.size).to eq(7) # Two additional rules generated
         
     | 
| 
       162 
166 
     | 
    
         
             
                      prod_plus = instance.productions.select { |prod| prod.lhs.name == 'digit_plus' }
         
     | 
| 
       163 
167 
     | 
    
         
             
                      expect(prod_plus.size).to eq(2)
         
     | 
| 
       164 
     | 
    
         
            -
                       
     | 
| 
       165 
     | 
    
         
            -
                      expect( 
     | 
| 
       166 
     | 
    
         
            -
                      expect( 
     | 
| 
      
 168 
     | 
    
         
            +
                      val_prod = instance.productions[4]
         
     | 
| 
      
 169 
     | 
    
         
            +
                      expect(val_prod.lhs.name).to eq('value')
         
     | 
| 
      
 170 
     | 
    
         
            +
                      expect(val_prod.rhs.members[0].name).to eq('digit_plus')
         
     | 
| 
       167 
171 
     | 
    
         
             
                    end
         
     | 
| 
       168 
172 
     | 
    
         | 
| 
       169 
173 
     | 
    
         
             
                    it "should support optional grouping" do
         
     | 
| 
       170 
174 
     | 
    
         
             
                      instance = GrammarBuilder.new
         
     | 
| 
       171 
175 
     | 
    
         
             
                      instance.add_terminals('EQUAL', 'IDENTIFIER', 'VAR')
         
     | 
| 
       172 
176 
     | 
    
         | 
| 
       173 
     | 
    
         
            -
                      instance. 
     | 
| 
      
 177 
     | 
    
         
            +
                      instance.rule 'var_decl' => 'VAR IDENTIFIER (EQUAL expression)?'
         
     | 
| 
      
 178 
     | 
    
         
            +
                      instance.grammar_complete!
         
     | 
| 
       174 
179 
     | 
    
         | 
| 
       175 
180 
     | 
    
         
             
                      # implicitly called: rule('seq_EQUAL_expression' => 'EQUAL expression').tag 'return_children'
         
     | 
| 
       176 
181 
     | 
    
         
             
                      # implicitly called: rule('seq_EQUAL_expression_qmark' => 'seq_EQUAL_expression').tag suffix_qmark_one
         
     | 
| 
       177 
182 
     | 
    
         
             
                      # implicitly called: rule('seq_EQUAL_expression_qmark' => '').tag suffix_qmark_none
         
     | 
| 
       178 
183 
     | 
    
         
             
                      expect(instance.productions.size).to eq(4)
         
     | 
| 
       179 
     | 
    
         
            -
                       
     | 
| 
      
 184 
     | 
    
         
            +
                      first_prod = instance.productions.first
         
     | 
| 
      
 185 
     | 
    
         
            +
                      expect(first_prod.lhs.name).to eq('var_decl')
         
     | 
| 
      
 186 
     | 
    
         
            +
                      expect(first_prod.rhs.members[2].name).to eq('seq_EQUAL_expression_qmark')
         
     | 
| 
      
 187 
     | 
    
         
            +
                      (p0, p1, p2) = instance.productions[1..3]
         
     | 
| 
       180 
188 
     | 
    
         
             
                      expect(p0.lhs.name).to eq('seq_EQUAL_expression')
         
     | 
| 
       181 
189 
     | 
    
         
             
                      expect(p0.rhs[0].name).to eq('EQUAL')
         
     | 
| 
       182 
190 
     | 
    
         
             
                      expect(p0.rhs[1].name).to eq('expression')
         
     | 
| 
         @@ -189,23 +197,24 @@ module Rley # Open this namespace to avoid module qualifier prefixes 
     | 
|
| 
       189 
197 
     | 
    
         
             
                      expect(p2.lhs.name).to eq('seq_EQUAL_expression_qmark')
         
     | 
| 
       190 
198 
     | 
    
         
             
                      expect(p2.rhs).to be_empty
         
     | 
| 
       191 
199 
     | 
    
         
             
                      expect(p2.name).to eq('_qmark_none')
         
     | 
| 
       192 
     | 
    
         
            -
             
     | 
| 
       193 
     | 
    
         
            -
                      last_prod = instance.productions.last
         
     | 
| 
       194 
     | 
    
         
            -
                      expect(last_prod.lhs.name).to eq('var_decl')
         
     | 
| 
       195 
     | 
    
         
            -
                      expect(last_prod.rhs.members[2].name).to eq('seq_EQUAL_expression_qmark')
         
     | 
| 
       196 
200 
     | 
    
         
             
                    end
         
     | 
| 
       197 
201 
     | 
    
         | 
| 
       198 
202 
     | 
    
         
             
                    it "should support grouping with star modifier" do
         
     | 
| 
       199 
203 
     | 
    
         
             
                      instance = GrammarBuilder.new
         
     | 
| 
       200 
204 
     | 
    
         
             
                      instance.add_terminals('OR')
         
     | 
| 
       201 
205 
     | 
    
         | 
| 
       202 
     | 
    
         
            -
                      instance. 
     | 
| 
      
 206 
     | 
    
         
            +
                      instance.rule 'logic_or' => 'logic_and (OR logic_and)*'
         
     | 
| 
      
 207 
     | 
    
         
            +
                      instance.grammar_complete!
         
     | 
| 
       203 
208 
     | 
    
         | 
| 
       204 
209 
     | 
    
         
             
                      # implicitly called: rule('seq_OR_logic_and' => 'OR logic_and').tag 'return_children'
         
     | 
| 
       205 
210 
     | 
    
         
             
                      # implicitly called: rule('seq_EQUAL_expression_star' => 'seq_EQUAL_expression_star seq_EQUAL_expression').tag suffix_star_more
         
     | 
| 
       206 
211 
     | 
    
         
             
                      # implicitly called: rule('seq_EQUAL_expression_star' => '').tag suffix_star_none
         
     | 
| 
       207 
212 
     | 
    
         
             
                      expect(instance.productions.size).to eq(4)
         
     | 
| 
       208 
     | 
    
         
            -
                       
     | 
| 
      
 213 
     | 
    
         
            +
                      first_prod = instance.productions.first
         
     | 
| 
      
 214 
     | 
    
         
            +
                      expect(first_prod.lhs.name).to eq('logic_or')
         
     | 
| 
      
 215 
     | 
    
         
            +
                      expect(first_prod.rhs.members[1].name).to eq('seq_OR_logic_and_star')
         
     | 
| 
      
 216 
     | 
    
         
            +
             
     | 
| 
      
 217 
     | 
    
         
            +
                      (p0, p1, p2) = instance.productions[1..3]
         
     | 
| 
       209 
218 
     | 
    
         
             
                      expect(p0.lhs.name).to eq('seq_OR_logic_and')
         
     | 
| 
       210 
219 
     | 
    
         
             
                      expect(p0.rhs[0].name).to eq('OR')
         
     | 
| 
       211 
220 
     | 
    
         
             
                      expect(p0.rhs[1].name).to eq('logic_and')
         
     | 
| 
         @@ -219,23 +228,24 @@ module Rley # Open this namespace to avoid module qualifier prefixes 
     | 
|
| 
       219 
228 
     | 
    
         
             
                      expect(p2.lhs.name).to eq('seq_OR_logic_and_star')
         
     | 
| 
       220 
229 
     | 
    
         
             
                      expect(p2.rhs).to be_empty
         
     | 
| 
       221 
230 
     | 
    
         
             
                      expect(p2.name).to eq('_star_none')
         
     | 
| 
       222 
     | 
    
         
            -
             
     | 
| 
       223 
     | 
    
         
            -
                      last_prod = instance.productions.last
         
     | 
| 
       224 
     | 
    
         
            -
                      expect(last_prod.lhs.name).to eq('logic_or')
         
     | 
| 
       225 
     | 
    
         
            -
                      expect(last_prod.rhs.members[1].name).to eq('seq_OR_logic_and_star')
         
     | 
| 
       226 
231 
     | 
    
         
             
                    end
         
     | 
| 
       227 
232 
     | 
    
         | 
| 
       228 
233 
     | 
    
         
             
                    it "should support grouping with plus modifier" do
         
     | 
| 
       229 
234 
     | 
    
         
             
                      instance = GrammarBuilder.new
         
     | 
| 
       230 
235 
     | 
    
         
             
                      instance.add_terminals('POINT TO SEMI_COLON')
         
     | 
| 
       231 
236 
     | 
    
         | 
| 
       232 
     | 
    
         
            -
                      instance. 
     | 
| 
      
 237 
     | 
    
         
            +
                      instance.rule 'path' => 'POINT (TO POINT)+ SEMI_COLON'
         
     | 
| 
      
 238 
     | 
    
         
            +
                      instance.grammar_complete!
         
     | 
| 
       233 
239 
     | 
    
         | 
| 
       234 
240 
     | 
    
         
             
                      # implicitly called: rule('seq_TO_POINT' => 'TO POINT').tag 'return_children'
         
     | 
| 
       235 
241 
     | 
    
         
             
                      # implicitly called: rule('seq_TO_POINT_plus' => 'seq_TO_POINT_plus seq_TO_POINT').tag suffix_plus_more
         
     | 
| 
       236 
242 
     | 
    
         
             
                      # implicitly called: rule('seq_TO_POINT_plus' => 'seq_TO_POINT').tag suffix_plus_one
         
     | 
| 
       237 
243 
     | 
    
         
             
                      expect(instance.productions.size).to eq(4)
         
     | 
| 
       238 
     | 
    
         
            -
                       
     | 
| 
      
 244 
     | 
    
         
            +
                      first_prod = instance.productions.first
         
     | 
| 
      
 245 
     | 
    
         
            +
                      expect(first_prod.lhs.name).to eq('path')
         
     | 
| 
      
 246 
     | 
    
         
            +
                      expect(first_prod.rhs.members[1].name).to eq('seq_TO_POINT_plus')
         
     | 
| 
      
 247 
     | 
    
         
            +
             
     | 
| 
      
 248 
     | 
    
         
            +
                      (p0, p1, p2) = instance.productions[1..3]
         
     | 
| 
       239 
249 
     | 
    
         
             
                      expect(p0.lhs.name).to eq('seq_TO_POINT')
         
     | 
| 
       240 
250 
     | 
    
         
             
                      expect(p0.rhs[0].name).to eq('TO')
         
     | 
| 
       241 
251 
     | 
    
         
             
                      expect(p0.rhs[1].name).to eq('POINT')
         
     | 
| 
         @@ -249,23 +259,24 @@ module Rley # Open this namespace to avoid module qualifier prefixes 
     | 
|
| 
       249 
259 
     | 
    
         
             
                      expect(p2.lhs.name).to eq('seq_TO_POINT_plus')
         
     | 
| 
       250 
260 
     | 
    
         
             
                      expect(p2.rhs[0].name).to eq('seq_TO_POINT')
         
     | 
| 
       251 
261 
     | 
    
         
             
                      expect(p2.name).to eq('_plus_one')
         
     | 
| 
       252 
     | 
    
         
            -
             
     | 
| 
       253 
     | 
    
         
            -
                      last_prod = instance.productions.last
         
     | 
| 
       254 
     | 
    
         
            -
                      expect(last_prod.lhs.name).to eq('path')
         
     | 
| 
       255 
     | 
    
         
            -
                      expect(last_prod.rhs.members[1].name).to eq('seq_TO_POINT_plus')
         
     | 
| 
       256 
262 
     | 
    
         
             
                    end
         
     | 
| 
       257 
263 
     | 
    
         | 
| 
       258 
264 
     | 
    
         
             
                    it "should support grouping with nested annotation" do
         
     | 
| 
       259 
265 
     | 
    
         
             
                      instance = GrammarBuilder.new
         
     | 
| 
       260 
266 
     | 
    
         
             
                      instance.add_terminals('IF ELSE LPAREN RPAREN')
         
     | 
| 
       261 
267 
     | 
    
         
             
                      st = "IF LPAREN expr RPAREN stmt (ELSE { match_closest: 'IF' } stmt)?"
         
     | 
| 
       262 
     | 
    
         
            -
                      instance. 
     | 
| 
      
 268 
     | 
    
         
            +
                      instance.rule('if_stmt' => st)
         
     | 
| 
      
 269 
     | 
    
         
            +
                      instance.grammar_complete!
         
     | 
| 
       263 
270 
     | 
    
         | 
| 
       264 
271 
     | 
    
         
             
                      # implicitly called: rule('seq_ELSE_stmt' => 'ELSE stmt').tag 'return_children'
         
     | 
| 
       265 
272 
     | 
    
         
             
                      # implicitly called: rule('seq_ELSE_stmt_qmark' => 'seq_ELSE_stmt ').tag suffix_plus_more
         
     | 
| 
       266 
273 
     | 
    
         
             
                      # implicitly called: rule('seq_ELSE_stmt_qmark' => '').tag suffix_plus_one
         
     | 
| 
       267 
274 
     | 
    
         
             
                      expect(instance.productions.size).to eq(4)
         
     | 
| 
       268 
     | 
    
         
            -
                       
     | 
| 
      
 275 
     | 
    
         
            +
                      first_prod = instance.productions.first
         
     | 
| 
      
 276 
     | 
    
         
            +
                      expect(first_prod.lhs.name).to eq('if_stmt')
         
     | 
| 
      
 277 
     | 
    
         
            +
                      expect(first_prod.rhs.members[5].name).to eq('seq_ELSE_stmt_qmark')
         
     | 
| 
      
 278 
     | 
    
         
            +
             
     | 
| 
      
 279 
     | 
    
         
            +
                      (p0, p1, p2) = instance.productions[1..3]
         
     | 
| 
       269 
280 
     | 
    
         
             
                      expect(p0.lhs.name).to eq('seq_ELSE_stmt')
         
     | 
| 
       270 
281 
     | 
    
         
             
                      expect(p0.rhs[0].name).to eq('ELSE')
         
     | 
| 
       271 
282 
     | 
    
         
             
                      expect(p0.rhs[1].name).to eq('stmt')
         
     | 
| 
         @@ -282,10 +293,6 @@ module Rley # Open this namespace to avoid module qualifier prefixes 
     | 
|
| 
       282 
293 
     | 
    
         
             
                      expect(p2.lhs.name).to eq('seq_ELSE_stmt_qmark')
         
     | 
| 
       283 
294 
     | 
    
         
             
                      expect(p2.rhs).to be_empty
         
     | 
| 
       284 
295 
     | 
    
         
             
                      expect(p2.name).to eq('_qmark_none')
         
     | 
| 
       285 
     | 
    
         
            -
             
     | 
| 
       286 
     | 
    
         
            -
                      last_prod = instance.productions.last
         
     | 
| 
       287 
     | 
    
         
            -
                      expect(last_prod.lhs.name).to eq('if_stmt')
         
     | 
| 
       288 
     | 
    
         
            -
                      expect(last_prod.rhs.members[5].name).to eq('seq_ELSE_stmt_qmark')
         
     | 
| 
       289 
296 
     | 
    
         
             
                    end
         
     | 
| 
       290 
297 
     | 
    
         
             
                  end # context
         
     | 
| 
       291 
298 
     | 
    
         
             
                end # describe
         
     | 
| 
         @@ -934,10 +934,11 @@ MSG 
     | 
|
| 
       934 
934 
     | 
    
         
             
                      # S => ;
         
     | 
| 
       935 
935 
     | 
    
         
             
                      # This grammar requires a time that is quadratic in the number of
         
     | 
| 
       936 
936 
     | 
    
         
             
                      # input tokens
         
     | 
| 
       937 
     | 
    
         
            -
                      builder = Notation::GrammarBuilder.new
         
     | 
| 
       938 
     | 
    
         
            -
             
     | 
| 
       939 
     | 
    
         
            -
             
     | 
| 
       940 
     | 
    
         
            -
             
     | 
| 
      
 937 
     | 
    
         
            +
                      builder = Notation::GrammarBuilder.new do
         
     | 
| 
      
 938 
     | 
    
         
            +
                        add_terminals('a')
         
     | 
| 
      
 939 
     | 
    
         
            +
                        rule('S' => 'a S')
         
     | 
| 
      
 940 
     | 
    
         
            +
                        rule('S' => '')
         
     | 
| 
      
 941 
     | 
    
         
            +
                      end
         
     | 
| 
       941 
942 
     | 
    
         
             
                      grammar = builder.grammar
         
     | 
| 
       942 
943 
     | 
    
         
             
                      tokens = build_token_sequence(%w[a a a a], grammar)
         
     | 
| 
       943 
944 
     | 
    
         | 
| 
         @@ -1017,6 +1018,25 @@ MSG 
     | 
|
| 
       1017 
1018 
     | 
    
         
             
                      ]
         
     | 
| 
       1018 
1019 
     | 
    
         
             
                      compare_entry_texts(parse_result.chart[4], expected)
         
     | 
| 
       1019 
1020 
     | 
    
         
             
                    end
         
     | 
| 
      
 1021 
     | 
    
         
            +
             
     | 
| 
      
 1022 
     | 
    
         
            +
                    it 'should support modifier(s) in start rule' do
         
     | 
| 
      
 1023 
     | 
    
         
            +
                      # An implicit EOF marker is a special terminal
         
     | 
| 
      
 1024 
     | 
    
         
            +
                      # that denotes the end of input string but doesn't
         
     | 
| 
      
 1025 
     | 
    
         
            +
                      # appear explicitly as some character or text in the input.
         
     | 
| 
      
 1026 
     | 
    
         
            +
                      builder = Notation::GrammarBuilder.new do
         
     | 
| 
      
 1027 
     | 
    
         
            +
                        add_terminals('a', 'b', 'EOF')
         
     | 
| 
      
 1028 
     | 
    
         
            +
             
     | 
| 
      
 1029 
     | 
    
         
            +
                        rule('S' => 'a_or_b* EOF')
         
     | 
| 
      
 1030 
     | 
    
         
            +
                        rule('a_or_b' => 'a')
         
     | 
| 
      
 1031 
     | 
    
         
            +
                        rule('a_or_b' => 'b')
         
     | 
| 
      
 1032 
     | 
    
         
            +
                      end
         
     | 
| 
      
 1033 
     | 
    
         
            +
                      grammar = builder.grammar
         
     | 
| 
      
 1034 
     | 
    
         
            +
                      tokens = build_token_sequence(%w[EOF], grammar)
         
     | 
| 
      
 1035 
     | 
    
         
            +
                      tokens[0].instance_variable_set(:@lexeme, '')
         
     | 
| 
      
 1036 
     | 
    
         
            +
                      instance = GFGEarleyParser.new(grammar)
         
     | 
| 
      
 1037 
     | 
    
         
            +
                      parse_result = instance.parse(tokens)
         
     | 
| 
      
 1038 
     | 
    
         
            +
                      expect(parse_result.success?).to eq(true)
         
     | 
| 
      
 1039 
     | 
    
         
            +
                    end
         
     | 
| 
       1020 
1040 
     | 
    
         
             
                  end # context
         
     | 
| 
       1021 
1041 
     | 
    
         
             
                end # describe
         
     | 
| 
       1022 
1042 
     | 
    
         
             
              end # module
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: rley
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0.8. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.8.01
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Dimitri Geshef
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire:
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2021-08- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2021-08-22 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: rake
         
     |