kdl 1.0.6 → 2.0.1
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/.github/workflows/ruby.yml +8 -1
 - data/.gitignore +1 -0
 - data/.gitmodules +4 -0
 - data/Gemfile +6 -1
 - data/README.md +67 -7
 - data/Rakefile +6 -1
 - data/bin/kdl +1 -1
 - data/kdl.gemspec +2 -2
 - data/lib/kdl/document.rb +60 -2
 - data/lib/kdl/error.rb +24 -0
 - data/lib/kdl/kdl.tab.rb +305 -231
 - data/lib/kdl/kdl.yy +57 -49
 - data/lib/kdl/node.rb +116 -13
 - data/lib/kdl/parser_common.rb +28 -0
 - data/lib/kdl/string_dumper.rb +32 -33
 - data/lib/kdl/tokenizer.rb +387 -136
 - data/lib/kdl/types/base64.rb +3 -1
 - data/lib/kdl/types/country/iso3166_countries.rb +3 -1
 - data/lib/kdl/types/country/iso3166_subdivisions.rb +3 -1
 - data/lib/kdl/types/country.rb +4 -2
 - data/lib/kdl/types/currency/iso4217_currencies.rb +3 -1
 - data/lib/kdl/types/currency.rb +3 -1
 - data/lib/kdl/types/date_time.rb +5 -3
 - data/lib/kdl/types/decimal.rb +3 -1
 - data/lib/kdl/types/duration/iso8601_parser.rb +3 -1
 - data/lib/kdl/types/duration.rb +3 -1
 - data/lib/kdl/types/email/parser.rb +10 -8
 - data/lib/kdl/types/email.rb +3 -1
 - data/lib/kdl/types/hostname/validator.rb +3 -1
 - data/lib/kdl/types/hostname.rb +3 -1
 - data/lib/kdl/types/ip.rb +3 -1
 - data/lib/kdl/types/irl/parser.rb +10 -8
 - data/lib/kdl/types/irl.rb +3 -1
 - data/lib/kdl/types/regex.rb +3 -1
 - data/lib/kdl/types/url.rb +3 -1
 - data/lib/kdl/types/url_template.rb +6 -4
 - data/lib/kdl/types/uuid.rb +3 -1
 - data/lib/kdl/types.rb +2 -0
 - data/lib/kdl/v1/document.rb +19 -0
 - data/lib/kdl/v1/kdl.tab.rb +594 -0
 - data/lib/kdl/v1/kdl.yy +89 -0
 - data/lib/kdl/v1/node.rb +32 -0
 - data/lib/kdl/v1/string_dumper.rb +30 -0
 - data/lib/kdl/v1/tokenizer.rb +298 -0
 - data/lib/kdl/v1/value.rb +91 -0
 - data/lib/kdl/v1.rb +13 -0
 - data/lib/kdl/value.rb +87 -15
 - data/lib/kdl/version.rb +3 -1
 - data/lib/kdl.rb +47 -1
 - metadata +14 -7
 
    
        data/lib/kdl/kdl.yy
    CHANGED
    
    | 
         @@ -1,7 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            class KDL::Parser
         
     | 
| 
       2 
2 
     | 
    
         
             
              options no_result_var
         
     | 
| 
       3 
     | 
    
         
            -
              token IDENT
         
     | 
| 
       4 
     | 
    
         
            -
                    STRING RAWSTRING
         
     | 
| 
      
 3 
     | 
    
         
            +
              token IDENT STRING RAWSTRING
         
     | 
| 
       5 
4 
     | 
    
         
             
                    INTEGER FLOAT TRUE FALSE NULL
         
     | 
| 
       6 
5 
     | 
    
         
             
                    WS NEWLINE
         
     | 
| 
       7 
6 
     | 
    
         
             
                    LBRACE RBRACE
         
     | 
| 
         @@ -10,57 +9,66 @@ class KDL::Parser 
     | 
|
| 
       10 
9 
     | 
    
         
             
                    SEMICOLON
         
     | 
| 
       11 
10 
     | 
    
         
             
                    EOF
         
     | 
| 
       12 
11 
     | 
    
         
             
                    SLASHDASH
         
     | 
| 
       13 
     | 
    
         
            -
                    ESCLINE
         
     | 
| 
       14 
12 
     | 
    
         
             
            rule
         
     | 
| 
       15 
     | 
    
         
            -
              document  : nodes {  
     | 
| 
       16 
     | 
    
         
            -
                        | linespaces {  
     | 
| 
      
 13 
     | 
    
         
            +
              document  : nodes { @output_module::Document.new(val[0]) }
         
     | 
| 
      
 14 
     | 
    
         
            +
                        | linespaces { @output_module::Document.new([]) }
         
     | 
| 
       17 
15 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
            nodes 
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
              node 
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
      
 16 
     | 
    
         
            +
              nodes          : none                        { [] }
         
     | 
| 
      
 17 
     | 
    
         
            +
                             | linespaces node             { [val[1]] }
         
     | 
| 
      
 18 
     | 
    
         
            +
                             | linespaces empty_node       { [] }
         
     | 
| 
      
 19 
     | 
    
         
            +
                             | nodes node                  { [*val[0], val[1]] }
         
     | 
| 
      
 20 
     | 
    
         
            +
                             | nodes empty_node            { val[0] }
         
     | 
| 
      
 21 
     | 
    
         
            +
              node           : unterm_node node_term       { val[0] }
         
     | 
| 
      
 22 
     | 
    
         
            +
              unterm_node    : untyped_node      { val[0] }
         
     | 
| 
      
 23 
     | 
    
         
            +
                             | type untyped_node { val[1].as_type(val[0], @type_parsers.fetch(val[0], nil)) }
         
     | 
| 
      
 24 
     | 
    
         
            +
              untyped_node   : node_decl                                                       { val[0].tap { |x| x.children = [] } }
         
     | 
| 
      
 25 
     | 
    
         
            +
                             | node_decl ws_plus node_children                                 { val[0].tap { |x| x.children = val[2] } }
         
     | 
| 
      
 26 
     | 
    
         
            +
                             | node_decl ws_plus empty_childrens                               { val[0].tap { |x| x.children = [] } }
         
     | 
| 
      
 27 
     | 
    
         
            +
                             | node_decl ws_plus empty_childrens node_children                 { val[0].tap { |x| x.children = val[3] } }
         
     | 
| 
      
 28 
     | 
    
         
            +
                             | node_decl ws_plus node_children empty_childrens                 { val[0].tap { |x| x.children = val[2] } }
         
     | 
| 
      
 29 
     | 
    
         
            +
                             | node_decl ws_plus empty_childrens node_children empty_childrens { val[0].tap { |x| x.children = val[3] } }
         
     | 
| 
      
 30 
     | 
    
         
            +
              node_decl      : identifier                           { @output_module::Node.new(val[0]) }
         
     | 
| 
      
 31 
     | 
    
         
            +
                             | node_decl ws_plus value              { val[0].tap { |x| x.arguments << val[2] } }
         
     | 
| 
      
 32 
     | 
    
         
            +
                             | node_decl ws_plus slashdash value    { val[0] }
         
     | 
| 
      
 33 
     | 
    
         
            +
                             | node_decl ws_plus property           { val[0].tap { |x| x.properties[val[2][0]] = val[2][1] } }
         
     | 
| 
      
 34 
     | 
    
         
            +
                             | node_decl ws_plus slashdash property { val[0] }
         
     | 
| 
      
 35 
     | 
    
         
            +
                             | node_decl ws_plus                    { val[0] }
         
     | 
| 
      
 36 
     | 
    
         
            +
              empty_node     : slashdash node
         
     | 
| 
      
 37 
     | 
    
         
            +
              node_children  : ws_star LBRACE nodes RBRACE                          { val[2] }
         
     | 
| 
      
 38 
     | 
    
         
            +
                             | ws_star LBRACE linespaces RBRACE                     { [] }
         
     | 
| 
      
 39 
     | 
    
         
            +
                             | ws_star LBRACE nodes unterm_node ws_star RBRACE      { [*val[2], val[3]] }
         
     | 
| 
      
 40 
     | 
    
         
            +
                             | ws_star LBRACE linespaces unterm_node ws_star RBRACE { [val[3]] }
         
     | 
| 
      
 41 
     | 
    
         
            +
              empty_children : slashdash node_children
         
     | 
| 
      
 42 
     | 
    
         
            +
                             | ws_plus empty_children
         
     | 
| 
      
 43 
     | 
    
         
            +
              empty_childrens: empty_children | empty_childrens empty_children
         
     | 
| 
       38 
44 
     | 
    
         
             
              node_term: linespaces | semicolon_term
         
     | 
| 
       39 
45 
     | 
    
         
             
              semicolon_term: SEMICOLON | SEMICOLON linespaces
         
     | 
| 
      
 46 
     | 
    
         
            +
              slashdash: SLASHDASH | slashdash linespaces
         
     | 
| 
       40 
47 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
              type : LPAREN identifier RPAREN { val[ 
     | 
| 
      
 48 
     | 
    
         
            +
              type : LPAREN ws_star identifier ws_star RPAREN ws_star { val[2] }
         
     | 
| 
       42 
49 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
              identifier: IDENT     { val[0].value }
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
      
 50 
     | 
    
         
            +
              identifier : IDENT     { val[0].value }
         
     | 
| 
      
 51 
     | 
    
         
            +
                         | STRING    { val[0].value }
         
     | 
| 
      
 52 
     | 
    
         
            +
                         | RAWSTRING { val[0].value }
         
     | 
| 
       46 
53 
     | 
    
         | 
| 
       47 
     | 
    
         
            -
              property: identifier EQUALS value { [val[0], val[2]] }
         
     | 
| 
      
 54 
     | 
    
         
            +
              property : identifier EQUALS value { [val[0], val[2]] }
         
     | 
| 
       48 
55 
     | 
    
         | 
| 
       49 
56 
     | 
    
         
             
              value : untyped_value
         
     | 
| 
       50 
57 
     | 
    
         
             
                    | type untyped_value { val[1].as_type(val[0], @type_parsers.fetch(val[0], nil)) }
         
     | 
| 
       51 
58 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
              untyped_value :  
     | 
| 
       53 
     | 
    
         
            -
                            |  
     | 
| 
       54 
     | 
    
         
            -
                            |  
     | 
| 
       55 
     | 
    
         
            -
                            |  
     | 
| 
       56 
     | 
    
         
            -
                            |  
     | 
| 
       57 
     | 
    
         
            -
                            |  
     | 
| 
      
 59 
     | 
    
         
            +
              untyped_value : IDENT      { @output_module::Value::String.new(val[0].value) }
         
     | 
| 
      
 60 
     | 
    
         
            +
                            | STRING     { @output_module::Value::String.new(val[0].value) }
         
     | 
| 
      
 61 
     | 
    
         
            +
                            | RAWSTRING  { @output_module::Value::String.new(val[0].value) }
         
     | 
| 
      
 62 
     | 
    
         
            +
                            | INTEGER    { @output_module::Value::Int.new(val[0].value) }
         
     | 
| 
      
 63 
     | 
    
         
            +
                            | FLOAT      { @output_module::Value::Float.new(val[0].value, format: val[0].meta[:format]) }
         
     | 
| 
      
 64 
     | 
    
         
            +
                            | boolean    { @output_module::Value::Boolean.new(val[0]) }
         
     | 
| 
      
 65 
     | 
    
         
            +
                            | NULL       { @output_module::Value::Null }
         
     | 
| 
       58 
66 
     | 
    
         | 
| 
       59 
67 
     | 
    
         
             
              boolean : TRUE  { true }
         
     | 
| 
       60 
68 
     | 
    
         
             
                      | FALSE { false }
         
     | 
| 
       61 
69 
     | 
    
         | 
| 
       62 
     | 
    
         
            -
               
     | 
| 
       63 
     | 
    
         
            -
              ws_star: none |  
     | 
| 
      
 70 
     | 
    
         
            +
              ws_plus: WS | WS ws_plus
         
     | 
| 
      
 71 
     | 
    
         
            +
              ws_star: none | ws_plus
         
     | 
| 
       64 
72 
     | 
    
         
             
              linespace: WS | NEWLINE | EOF
         
     | 
| 
       65 
73 
     | 
    
         
             
              linespaces: linespace | linespaces linespace
         
     | 
| 
       66 
74 
     | 
    
         | 
| 
         @@ -68,18 +76,18 @@ nodes           : none                      { [] } 
     | 
|
| 
       68 
76 
     | 
    
         | 
| 
       69 
77 
     | 
    
         
             
            ---- inner
         
     | 
| 
       70 
78 
     | 
    
         | 
| 
       71 
     | 
    
         
            -
               
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
                 
     | 
| 
       75 
     | 
    
         
            -
                  @type_parsers = {}
         
     | 
| 
       76 
     | 
    
         
            -
                end
         
     | 
| 
       77 
     | 
    
         
            -
                @tokenizer = ::KDL::Tokenizer.new(str)
         
     | 
| 
       78 
     | 
    
         
            -
                do_parse
         
     | 
| 
      
 79 
     | 
    
         
            +
              include KDL::ParserCommon
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
              def initialize(**options)
         
     | 
| 
      
 82 
     | 
    
         
            +
                init(**options)
         
     | 
| 
       79 
83 
     | 
    
         
             
              end
         
     | 
| 
       80 
84 
     | 
    
         | 
| 
       81 
     | 
    
         
            -
               
     | 
| 
      
 85 
     | 
    
         
            +
              def parser_version
         
     | 
| 
      
 86 
     | 
    
         
            +
                2
         
     | 
| 
      
 87 
     | 
    
         
            +
              end
         
     | 
| 
       82 
88 
     | 
    
         | 
| 
       83 
     | 
    
         
            -
              def  
     | 
| 
       84 
     | 
    
         
            -
                @tokenizer. 
     | 
| 
      
 89 
     | 
    
         
            +
              def parse(str)
         
     | 
| 
      
 90 
     | 
    
         
            +
                @tokenizer = ::KDL::Tokenizer.new(str)
         
     | 
| 
      
 91 
     | 
    
         
            +
                check_version
         
     | 
| 
      
 92 
     | 
    
         
            +
                do_parse
         
     | 
| 
       85 
93 
     | 
    
         
             
              end
         
     | 
    
        data/lib/kdl/node.rb
    CHANGED
    
    | 
         @@ -1,32 +1,116 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module KDL
         
     | 
| 
       2 
4 
     | 
    
         
             
              class Node
         
     | 
| 
      
 5 
     | 
    
         
            +
                class Custom < Node
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def self.call(node, type)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    new(node.name, arguments: node.arguments, properties: node.properties, children: node.children, type:)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def version
         
     | 
| 
      
 11 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def to_v1
         
     | 
| 
      
 15 
     | 
    
         
            +
                    self
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  def to_v2
         
     | 
| 
      
 19 
     | 
    
         
            +
                    self
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                include Enumerable
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
       3 
25 
     | 
    
         
             
                attr_accessor :name, :arguments, :properties, :children, :type
         
     | 
| 
       4 
26 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
                def initialize(name,  
     | 
| 
      
 27 
     | 
    
         
            +
                def initialize(name, _args = [], _props = {}, _children = [],
         
     | 
| 
      
 28 
     | 
    
         
            +
                  arguments: _args,
         
     | 
| 
      
 29 
     | 
    
         
            +
                  properties: _props,
         
     | 
| 
      
 30 
     | 
    
         
            +
                  children: _children,
         
     | 
| 
      
 31 
     | 
    
         
            +
                  type: nil
         
     | 
| 
      
 32 
     | 
    
         
            +
                )
         
     | 
| 
       6 
33 
     | 
    
         
             
                  @name = name
         
     | 
| 
       7 
34 
     | 
    
         
             
                  @arguments = arguments
         
     | 
| 
       8 
     | 
    
         
            -
                  @properties = properties
         
     | 
| 
      
 35 
     | 
    
         
            +
                  @properties = properties.transform_keys(&:to_s)
         
     | 
| 
       9 
36 
     | 
    
         
             
                  @children = children
         
     | 
| 
       10 
37 
     | 
    
         
             
                  @type = type
         
     | 
| 
       11 
38 
     | 
    
         
             
                end
         
     | 
| 
       12 
39 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
                def  
     | 
| 
      
 40 
     | 
    
         
            +
                def [](key)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  case key
         
     | 
| 
      
 42 
     | 
    
         
            +
                  when Integer
         
     | 
| 
      
 43 
     | 
    
         
            +
                    arguments[key]&.value
         
     | 
| 
      
 44 
     | 
    
         
            +
                  when String, Symbol
         
     | 
| 
      
 45 
     | 
    
         
            +
                    properties[key.to_s]&.value
         
     | 
| 
      
 46 
     | 
    
         
            +
                  else
         
     | 
| 
      
 47 
     | 
    
         
            +
                    raise ArgumentError, "node can only be indexed by Integer, String, or Symbol"
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                def child(key)
         
     | 
| 
      
 52 
     | 
    
         
            +
                  case key
         
     | 
| 
      
 53 
     | 
    
         
            +
                  when Integer
         
     | 
| 
      
 54 
     | 
    
         
            +
                    children[key]
         
     | 
| 
      
 55 
     | 
    
         
            +
                  when String, Symbol
         
     | 
| 
      
 56 
     | 
    
         
            +
                    children.find { _1.name == key.to_s }
         
     | 
| 
      
 57 
     | 
    
         
            +
                  else
         
     | 
| 
      
 58 
     | 
    
         
            +
                    raise ArgumentError, "node can only be indexed by Integer, String, or Symbol"
         
     | 
| 
      
 59 
     | 
    
         
            +
                  end
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                def arg(key)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  child(key)&.arguments&.first&.value
         
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                def args(key)
         
     | 
| 
      
 67 
     | 
    
         
            +
                  child(key)&.arguments&.map(&:value)
         
     | 
| 
      
 68 
     | 
    
         
            +
                end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                def each_arg(key, &block)
         
     | 
| 
      
 71 
     | 
    
         
            +
                  args(key)&.each(&block)
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                def dash_vals(key)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  child(key)
         
     | 
| 
      
 76 
     | 
    
         
            +
                    &.children
         
     | 
| 
      
 77 
     | 
    
         
            +
                    &.select { _1.name == "-" }
         
     | 
| 
      
 78 
     | 
    
         
            +
                    &.map { _1.arguments.first&.value }
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                def each_dash_val(key, &block)
         
     | 
| 
      
 82 
     | 
    
         
            +
                  dash_vals(key)&.each(&block)
         
     | 
| 
      
 83 
     | 
    
         
            +
                end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                def each(&block)
         
     | 
| 
      
 86 
     | 
    
         
            +
                  children.each(&block)
         
     | 
| 
      
 87 
     | 
    
         
            +
                end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                def <=>(other)
         
     | 
| 
      
 90 
     | 
    
         
            +
                  name <=> other.name
         
     | 
| 
      
 91 
     | 
    
         
            +
                end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                def to_s(level = 0, m = :to_s)
         
     | 
| 
       14 
94 
     | 
    
         
             
                  indent = '    ' * level
         
     | 
| 
       15 
     | 
    
         
            -
                  s = "#{indent}#{type ? "(#{id_to_s type})" : ''}#{id_to_s name}"
         
     | 
| 
      
 95 
     | 
    
         
            +
                  s = "#{indent}#{type ? "(#{id_to_s type, m })" : ''}#{id_to_s name, m}"
         
     | 
| 
       16 
96 
     | 
    
         
             
                  unless arguments.empty?
         
     | 
| 
       17 
     | 
    
         
            -
                    s  
     | 
| 
      
 97 
     | 
    
         
            +
                    s << " #{arguments.map(&m).join(' ')}"
         
     | 
| 
       18 
98 
     | 
    
         
             
                  end
         
     | 
| 
       19 
99 
     | 
    
         
             
                  unless properties.empty?
         
     | 
| 
       20 
     | 
    
         
            -
                    s  
     | 
| 
      
 100 
     | 
    
         
            +
                    s << " #{properties.map { |k, v| "#{id_to_s k, m}=#{v.public_send(m)}" }.join(' ')}"
         
     | 
| 
       21 
101 
     | 
    
         
             
                  end
         
     | 
| 
       22 
102 
     | 
    
         
             
                  unless children.empty?
         
     | 
| 
       23 
     | 
    
         
            -
                    s  
     | 
| 
       24 
     | 
    
         
            -
                    s  
     | 
| 
       25 
     | 
    
         
            -
                    s  
     | 
| 
      
 103 
     | 
    
         
            +
                    s << " {\n"
         
     | 
| 
      
 104 
     | 
    
         
            +
                    s << children.map { |c| "#{c.public_send(m, level + 1)}" }.join("\n")
         
     | 
| 
      
 105 
     | 
    
         
            +
                    s << "\n#{indent}}"
         
     | 
| 
       26 
106 
     | 
    
         
             
                  end
         
     | 
| 
       27 
107 
     | 
    
         
             
                  s
         
     | 
| 
       28 
108 
     | 
    
         
             
                end
         
     | 
| 
       29 
109 
     | 
    
         | 
| 
      
 110 
     | 
    
         
            +
                def inspect(level = 0)
         
     | 
| 
      
 111 
     | 
    
         
            +
                  to_s(level, :inspect)
         
     | 
| 
      
 112 
     | 
    
         
            +
                end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
       30 
114 
     | 
    
         
             
                def ==(other)
         
     | 
| 
       31 
115 
     | 
    
         
             
                  return false unless other.is_a?(Node)
         
     | 
| 
       32 
116 
     | 
    
         | 
| 
         @@ -45,18 +129,37 @@ module KDL 
     | 
|
| 
       45 
129 
     | 
    
         | 
| 
       46 
130 
     | 
    
         
             
                    return self.as_type(type) if result.nil?
         
     | 
| 
       47 
131 
     | 
    
         | 
| 
       48 
     | 
    
         
            -
                    unless result.is_a?(::KDL::Node)
         
     | 
| 
       49 
     | 
    
         
            -
                      raise ArgumentError, "expected parser to return an instance of ::KDL::Node, got `#{result.class}'"
         
     | 
| 
      
 132 
     | 
    
         
            +
                    unless result.is_a?(::KDL::Node::Custom)
         
     | 
| 
      
 133 
     | 
    
         
            +
                      raise ArgumentError, "expected parser to return an instance of ::KDL::Node::Custom, got `#{result.class}'"
         
     | 
| 
       50 
134 
     | 
    
         
             
                    end
         
     | 
| 
       51 
135 
     | 
    
         | 
| 
       52 
136 
     | 
    
         
             
                    result
         
     | 
| 
       53 
137 
     | 
    
         
             
                  end
         
     | 
| 
       54 
138 
     | 
    
         
             
                end
         
     | 
| 
       55 
139 
     | 
    
         | 
| 
      
 140 
     | 
    
         
            +
                def version
         
     | 
| 
      
 141 
     | 
    
         
            +
                  2
         
     | 
| 
      
 142 
     | 
    
         
            +
                end
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
                def to_v2
         
     | 
| 
      
 145 
     | 
    
         
            +
                  self
         
     | 
| 
      
 146 
     | 
    
         
            +
                end
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                def to_v1
         
     | 
| 
      
 149 
     | 
    
         
            +
                  ::KDL::V1::Node.new(name,
         
     | 
| 
      
 150 
     | 
    
         
            +
                    arguments: arguments.map(&:to_v1),
         
     | 
| 
      
 151 
     | 
    
         
            +
                    properties: properties.transform_values(&:to_v1),
         
     | 
| 
      
 152 
     | 
    
         
            +
                    children: children.map(&:to_v1),
         
     | 
| 
      
 153 
     | 
    
         
            +
                    type: type
         
     | 
| 
      
 154 
     | 
    
         
            +
                  )
         
     | 
| 
      
 155 
     | 
    
         
            +
                end
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
       56 
157 
     | 
    
         
             
                private
         
     | 
| 
       57 
158 
     | 
    
         | 
| 
       58 
     | 
    
         
            -
                def id_to_s(id)
         
     | 
| 
       59 
     | 
    
         
            -
                   
     | 
| 
      
 159 
     | 
    
         
            +
                def id_to_s(id, m = :to_s)
         
     | 
| 
      
 160 
     | 
    
         
            +
                  return id.public_send(m) unless m == :to_s
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
                  StringDumper.call(id.to_s)
         
     | 
| 
       60 
163 
     | 
    
         
             
                end
         
     | 
| 
       61 
164 
     | 
    
         
             
              end
         
     | 
| 
       62 
165 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module KDL
         
     | 
| 
      
 4 
     | 
    
         
            +
              module ParserCommon
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                private
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                def init(parse_types: true, type_parsers: {}, output_module: ::KDL)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @output_module = output_module
         
     | 
| 
      
 10 
     | 
    
         
            +
                  if parse_types
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @type_parsers = ::KDL::Types::MAPPING.merge(type_parsers)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  else
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @type_parsers = {}
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                def next_token
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @tokenizer.next_token
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                def check_version
         
     | 
| 
      
 22 
     | 
    
         
            +
                  return unless doc_version = @tokenizer.version_directive
         
     | 
| 
      
 23 
     | 
    
         
            +
                  if doc_version != parser_version
         
     | 
| 
      
 24 
     | 
    
         
            +
                    raise VersionMismatchError.new("Version mismatch, document specified v#{doc_version}, but this is a v#{parser_version} parser", doc_version, parser_version)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/kdl/string_dumper.rb
    CHANGED
    
    | 
         @@ -1,45 +1,44 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module KDL
         
     | 
| 
       2 
4 
     | 
    
         
             
              module StringDumper
         
     | 
| 
       3 
     | 
    
         
            -
                 
     | 
| 
       4 
     | 
    
         
            -
                   
     | 
| 
       5 
     | 
    
         
            -
                    %("#{string.each_char.map { |char| escape(char) }.join}")
         
     | 
| 
       6 
     | 
    
         
            -
                  end
         
     | 
| 
      
 5 
     | 
    
         
            +
                def call(string)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  return string if bare_identifier?(string)
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
                   
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
                      ident
         
     | 
| 
       11 
     | 
    
         
            -
                    else
         
     | 
| 
       12 
     | 
    
         
            -
                      call(ident)
         
     | 
| 
       13 
     | 
    
         
            -
                    end
         
     | 
| 
       14 
     | 
    
         
            -
                  end
         
     | 
| 
      
 8 
     | 
    
         
            +
                  %("#{string.each_char.map { |char| escape(char) }.join}")
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
       15 
10 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
      
 11 
     | 
    
         
            +
                private
         
     | 
| 
       17 
12 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                   
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                   
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
                    when '"' then '\"'
         
     | 
| 
       29 
     | 
    
         
            -
                    when "\b" then '\b'
         
     | 
| 
       30 
     | 
    
         
            -
                    when "\f" then '\f'
         
     | 
| 
       31 
     | 
    
         
            -
                    else char
         
     | 
| 
       32 
     | 
    
         
            -
                    end
         
     | 
| 
      
 13 
     | 
    
         
            +
                def escape(char)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  case char
         
     | 
| 
      
 15 
     | 
    
         
            +
                  when "\n" then '\n'
         
     | 
| 
      
 16 
     | 
    
         
            +
                  when "\r" then '\r'
         
     | 
| 
      
 17 
     | 
    
         
            +
                  when "\t" then '\t'
         
     | 
| 
      
 18 
     | 
    
         
            +
                  when '\\' then '\\\\'
         
     | 
| 
      
 19 
     | 
    
         
            +
                  when '"' then '\"'
         
     | 
| 
      
 20 
     | 
    
         
            +
                  when "\b" then '\b'
         
     | 
| 
      
 21 
     | 
    
         
            +
                  when "\f" then '\f'
         
     | 
| 
      
 22 
     | 
    
         
            +
                  else char
         
     | 
| 
       33 
23 
     | 
    
         
             
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
       34 
25 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
                   
     | 
| 
      
 26 
     | 
    
         
            +
                FORBIDDEN =
         
     | 
| 
      
 27 
     | 
    
         
            +
                  Tokenizer::SYMBOLS.keys +
         
     | 
| 
      
 28 
     | 
    
         
            +
                  Tokenizer::WHITESPACE +
         
     | 
| 
      
 29 
     | 
    
         
            +
                  Tokenizer::NEWLINES +
         
     | 
| 
      
 30 
     | 
    
         
            +
                  "()[]/\\\"#".chars +
         
     | 
| 
      
 31 
     | 
    
         
            +
                  ("\x0".."\x20").to_a
         
     | 
| 
       38 
32 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
      
 33 
     | 
    
         
            +
                def bare_identifier?(name)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  case name
         
     | 
| 
      
 35 
     | 
    
         
            +
                  when '', 'true', 'fase', 'null', '#true', '#false', '#null', /\A\.?\d/
         
     | 
| 
      
 36 
     | 
    
         
            +
                    false
         
     | 
| 
      
 37 
     | 
    
         
            +
                  else
         
     | 
| 
      
 38 
     | 
    
         
            +
                    !name.each_char.any? { |c| FORBIDDEN.include?(c) }
         
     | 
| 
       42 
39 
     | 
    
         
             
                  end
         
     | 
| 
       43 
40 
     | 
    
         
             
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                extend self
         
     | 
| 
       44 
43 
     | 
    
         
             
              end
         
     | 
| 
       45 
44 
     | 
    
         
             
            end
         
     |